(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 "случайно". Вот такие "странные, но интересные" особенности реализации...

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


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

Магазин программного обеспечения   WWW.ITSHOP.RU
Allround Automation PL/SQL Developer - Annual Service Contract - 5 users
Allround Automation PL/SQL Developer Single user license
Allround Automation PL/SQL Developer - Annual Service Contract - Unlimited
Allround Automation PL/SQL Developer - Annual Service Contract - Single user
Oracle Database Standard Edition 2 Processor License
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
Программирование в AutoCAD
СУБД Oracle "с нуля"
Компьютерные книги. Рецензии и отзывы
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
Обсуждения в форумах
Отличается ли ДрифтКазино от беттинга? (1)
Друзья, давно заметил, что на Дрифте уже несколько месяцев во всю рекламируется и предлагается...
 
Введение в WML (3)
если все странички пишутся на wml, почему опубликованы они с расширением php?
 
Доступ к почте из разных постовых служб (2)
На компьютере одновременно функционируют почтовая служба Outlook Express (в составе пакета MS...
 
Помощь по MS Access (328)
Доброе время суток. Случайно оказался на этом сайте, искал статьи по OLAP. Вижу, что...
 
Модульный метод создания сайтов (5)
Модульный метод создания (компоновки) сайтов на основе наборов типовых отлаженных функциональных...
 
 
 



    
rambler's top100 Rambler's Top100