الارتباك حول استخدام الأنواع بدلاً من GTTs في Oracle
سؤال
أحاول تحويل الاستعلامات كما يلي إلى الأنواع حتى لا أضطر إلى استخدام 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: الكثير من القيم
أنا في حيرة من أمري حقًا ومعلقة مع هذا :(
المحلول
لقد حددت نوعًا مع 6 السمات وتحاول إنشاء مثيل لها 7 القيم. جرب هذا بدلاً من ذلك:
select lname_row(/*'',*/
'',
'',
'',
'',
'',
sysdate) bulk collect
into tab_a_recs
from table_1;
تعديليبدو أن هناك أيضًا ارتباكًا يتعلق بالأنواع. في Oracle ، يمكنك تحديد الأنواع في SQL أو في PL/SQL. أنواع SQL هي AccessiBles إلى SQL (!) في حين توفر تلك PL/SQL بعض الميزات الإضافية ولكنها غير مرئية لـ SQL Pure (يمكن أيضًا الوصول إلى أنواع SQL).
ومع ذلك ، من المربك وغير الحكيم أن أنواع الأنواع هي نفسها في SQL و PL/SQL (أنت تصادف إلى التظليل مسائل). لقد حددت lname_exact
اكتب مرتين (مع بيان إنشاءك وفي كتلة إعلانك). بما أنك تقوم بتثبيت أ lname_exact
في عبارة SQL ، النوع الذي تم اختياره في هذه الحالة هو نوع SQL (مع 6 سمات فقط).
يجب عليك إما إزالة إعلان lname_exact
على SP أو إعادة تسميته.
نصائح أخرى
بالإضافة إلى إجابة Vincent الممتازة: لا تحتاج إلى إنشاء LNAME_ROW بشكل صريح في استعلام SQL الخاص بك. ستقوم Bulk Collection بتطابق الأعمدة المحددة تلقائيًا مع حقول الهدف إلى الهدف. بناءً على ما أظهرته حتى الآن ، لا تحتاج إلى إنشاء أنواع على مستوى المخطط ، فأنت بحاجة فقط إلى تعريفها في كتلة 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