путаница в использовании типов вместо gtts в Oracle - PullRequest
0 голосов
/ 14 июня 2010

Я пытаюсь преобразовать запросы, подобные приведенным ниже, в типы, чтобы мне не пришлось использовать GTT:

insert into my_gtt_table_1
(house, lname, fname, MI, fullname, dob)
(select house, lname, fname, MI, fullname, dob 
 from (select 'REG' house, mbr_last_name lname, mbr_first_name fname, mbr_mi MI, 
       mbr_first_name || mbr_mi || mbr_last_name fullname, mbr_dob dob from 
       table_1 a, table_b
       where a.head = b.head and mbr_number = '01' and mbr_last_name = v_last_name) c

выше - это всего лишь пример, но сложные запросы больше этого.
выше находится внутри хранимой процедуры.Так что, чтобы избежать gtt (my_gtt_table_1).Я сделал следующее:

create or replace type lname_row as object
    (
     house varchar2(30)
     lname varchar2(30),
     fname varchar2(30),
     MI char(1),
     fullname VARCHAR2(63),
     dob DATE
     )

create or replace type lname_exact as table of lname_row 

Теперь в SP:

type lname_exact is table of <what_table_should_i_put_here>%rowtype;
tab_a_recs lname_exact;

В приведенном выше примере я не уверен, в какую таблицу поместить в качестве запроса вложенные подзапросы.

запрос в SP: (я пытаюсь сделать это для примера, чтобы увидеть, работает ли он)

        select lname_row('',
                                '',
                                '',
                                '',
                                '',
                                '',
                                sysdate) bulk collect
          into tab_a_recs
        from table_1;

Я получаю сообщения об ошибках типа: ORA-00913: слишком много значений

Iя действительно смущен и застрял с этим: (

Ответы [ 2 ]

2 голосов
/ 14 июня 2010

Вы определили тип с атрибутами 6 , и вы пытаетесь создать его экземпляр со значениями 7 . Попробуйте вместо этого:

    select lname_row(/*'',*/
                     '',
                     '',
                     '',
                     '',
                     '',
                     sysdate) bulk collect
      into tab_a_recs
    from table_1;

Редактировать Там также, кажется, путаница в отношении типов. В Oracle вы можете определять типы в SQL или в PL / SQL. Типы SQL доступны для SQL (!), В то время как PL / SQL предлагают некоторые дополнительные функции, но невидимы для чистого SQL (PL / SQL также может обращаться к типам SQL).

Тем не менее, путать и неразумно называть типы одинаково как в SQL, так и в PL / SQL (вы сталкиваетесь с проблемами shadowing ). Вы определили тип lname_exact два раза (с вашим CREATE STATEMENT и в вашем блоке DECLARE). Поскольку вы создаете экземпляр lname_exact в операторе SQL, тип, выбранный в этом случае, является типом SQL (только с 6 атрибутами).

Вы должны либо удалить объявление lname_exact на SP, либо переименовать его.

0 голосов
/ 14 июня 2010

В дополнение к отличному ответу Винсента: вам не нужно явно создавать lname_row в вашем SQL-запросе. BULK COLLECT автоматически сопоставит выбранные столбцы с полями цели INTO. Итак, основываясь на том, что вы уже показали, вам не нужно СОЗДАТЬ типы на уровне схемы, вам просто нужно определить их в своем блоке PL / SQL.

Вот простой пример, который работает:

SQL> l
  1  declare
  2    type my_row is record (x number, y date);
  3    type my_tab is table of my_row;
  4    a_table  my_tab;
  5  begin
  6  select 1,sysdate
  7      bulk collect into a_table
  8      from dual;
  9  dbms_output.put_line(a_table(1).y);
 10* end;
SQL> /
14-JUN-10
...