USING – ключове слово PL / SQL у версії 9i, Інші СУБД, Бази даних, статті

Ця стаття присвячена двом особливостям роботи PL / SQL-машини, яка у версіях 9.x об’єднана з SQL-машиною. Цікаві особливості, які можуть спливти при перенесенні програмного забезпечення на нову версію сервера Oracle… За мотивами відповіді Тома Кайта на питання, задані 15 червня 2003.

USING – ключове слово PL / SQL!


Том,


Я хотів би задати два питання, які мене сильно збивають з пантелику.
Перше питання: Один з розробників написав наступний код в Oracle 8.1.7.3:

create table auxtab as select from dual;
create or replace procedure p_insert_auxtab as
begin
insert into auxtab using (select * from dual);
commit;
end;
/
Procedure created.
SQL> show errors
No errors.

При спробі виконання тих же дій у версії 9.2.0.3.0 отримуємо повідомлення про помилку:

create table auxtab as select from dual;
create or replace procedure p_insert_auxtab as
begin
insert into auxtab using (select * from dual);
commit;
end;
/
Warning: Procedure created with compilation errors.
SQL> show errors
Errors for PROCEDURE P_INSERT_AUXTAB:
LINE/COL ERROR
——– —————————————————-
3/1 PL/SQL: SQL Statement ignored
3/31 PL/SQL: ORA-00926: missing VALUES keyword

Але якщо зробити так:

SQL> create or replace procedure p_insert_auxtab as
2 begin
3 insert into auxtab using select * from dual;
4 commit;
5* end;
SQL> /
Procedure created.
SQL> show errors
No errors.

Я ніколи не думав, що слово “using“Може використовуватися так. Я використовував слово using в операторах типу execute immediate або при відкритті курсору. Моє питання: чи правильно використовувати слово using в операторі “insert into…“Чому розробник зміг скомпілювати і виконати процедуру у версії 8i з дужками, а у версії 9i це вже не пройшло?


Друге питання: Один з розробників зробив наступну у версії 8.1.7.3

SQL> create table test2
2 (colnum number)
3 ;
Table created.
SQL> create or replace procedure p_test2 as
2 x number:=0;
3 begin
4 select colnum into x from test2 where colnum mod 4 =0;
5 dbms_output.put_line(to_char(x));
6* end;
SQL> /
Procedure created.
SQL> show error
No errors.

У версії 9i я отримую:

SQL> create table test2
2 (colnum number)
3 ;
Table created.
SQL> create or replace procedure p_test2 as
2 x number:=0;
3 begin
4 select colnum into x from test2 where colnum mod 4 =0;
5 dbms_output.put_line(to_char(x));
6* end;
7 /
Warning: Procedure created with compilation errors.
SQL> show errors
Errors for PROCEDURE P_TEST2:
LINE/COL ERROR
——– —————————————————————–
4/1 PL/SQL: SQL Statement ignored
4/59 PL/SQL: ORA-00920: invalid relational operator

Чому версія 8i дозволяла використовувати функцію mod як оператор? Чи не повинна билап видаватися помилка і у версії 8i? Я переглянув документацію Oracle і не знайшов жодного прикладу, де mod використовується як оператор. Чи можна використовувати mod як оператор? Чому процедура перестала успішно компілюватися у версії 9i?


Відповідь Тома Кайта


Перше питання:

insert into T
(select * from dual);

Такий оператор вас не дивує, перавда? Так що:

insert into T T1
(select * from dual);

теж не здивує. А далі:

insert into T “using”
(select * from dual);

Адже аналогічна конструкція, як і:

insert into T using
(select * from dual);

USING – Всього лише “корреляционное ім’я”, псевдонім таблиці T, А не ключове слово. Але у версії 9i з’явилося ключове слово USING в мові PL / SQL, що ускладнило ситуацію:

ops$tkyte@ORA920> create table t as select * from dual where 1=0;
Table created.
ops$tkyte@ORA920> begin
2 insert into t using (select * from dual);
3 end;
4 /
end;
*
ERROR at line 3:
ORA-06550: line 2, column 16:
PL/SQL: ORA-00926: missing VALUES keyword
ORA-06550: line 2, column 2:
PL/SQL: SQL Statement ignored
ops$tkyte@ORA920> begin
2 insert into t using select * from dual;
3 end;
4 /
PL/SQL procedure successfully completed.
ops$tkyte@ORA920> begin
2 insert into t “using” (select * from dual);
3 end;
4 /
PL/SQL procedure successfully completed.
ops$tkyte@ORA920> begin
2 insert into t “using” select * from dual;
3 end;
4 /
PL/SQL procedure successfully completed.

Але якщо короткий – USING інтерпретувалося як псевдонім, а не як ключове слово. Його просто не потрібно вказувати.


Друге питання:


Унікальна ситуація – я з такою не стикався. Проблема пов’язана з тим, що у версіях до 8i включно PL / SQL-машина використала окремий аналізатор SQL. В PL / SQL всі оператори типу =, < і т.п. визначалися як “функції”, вони листувалися. Якщо включити sql_trace і подивитися на SQL, згенерований з PL / SQL, можна побачити наступне:

SELECT COLNUM
FROM
T WHERE MOD (COLNUM,4) = 0

Хоча у вихідному коді і було написано:

ops$tkyte@ORA817DEV> create table t ( colnum number );
Table created.
ops$tkyte@ORA817DEV> insert into t select rownum-1 from all_users where rownum <=4;
4 rows created.
ops$tkyte@ORA817DEV> create or replace procedure p_test2 as
2 x number:=0;
3 begin
4 select colnum into x from t where colnum mod 4 =0;
5 dbms_output.put_line(to_char(x));
6 end;
7 /
Procedure created.
ops$tkyte@ORA817DEV> exec p_test2;
0
PL/SQL procedure successfully completed.
ops$tkyte@ORA817DEV> select colnum from t where colnum mod 4 = 0;
select colnum from t where colnum mod 4 = 0
*
ERROR at line 1:
ORA-00920: invalid relational operator

Це ніде не описано в документації. Працювало в 8i “випадково”. Ось такі “дивні, але цікаві” особливості реалізації …

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*