(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

USING - ключевое слово PL/SQL в версии 9i

Источник: ln

Эта статья посвящена двум особенностям работы 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 "случайно". Вот такие "странные, но интересные" особенности реализации...

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 16.03.2010 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Allround Automation PL/SQL Developer - Annual Service Contract - Unlimited
Oracle Database Standard Edition 2 Processor License
Oracle Database Personal Edition Named User Plus Software Update License & Support
Allround Automation Direct Oracle Access Standard license
Allround Automation PL/SQL Developer - Annual Service Contract - Single user
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
СУБД Oracle "с нуля"
Все о PHP и даже больше
Компьютерная библиотека: книги, статьи, полезные ссылки
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100