powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
44 сообщений из 44, показаны все 2 страниц
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34442364
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
CREATE OR REPLACE PROCEDURE mytest
AS
BEGIN
	FOR rec IN
	(
		SELECT	dummy, COUNT(*)
		FROM	dual
	)
	LOOP
		NULL;
	END LOOP;
END;
Компиляция процедуры происходит нормально. Работать - естественно, не работает:
Message: ORA-00937: not a single-group group function ORA-06512: at "SEB.MYTEST", line 10 ORA-06512: at line 2.
Читаем уважаемого Тома нашего Кайта:
* Статический SQL проверяется в процессе компиляции: Если в коде содержится ошибка, а процедура является действительной и может быть выполнена, то эта ошибка не имеет отношения к SQL.
Вот и думаю: где-то кто-то (т.е. я, конечно) из нас чего-то не понимает.
----------------------------------------------------------------------------------------------------
Является ли запрос
Код: plaintext
1.
SELECT	dummy, COUNT(*)
FROM	dual
верным с точки зрения SQL и PL/SQL ?
----------------------------------------------------------------------------------------------------
а вообще-то, конечно, достаёт в процессе разработки, что компилятор не ругается сразу
----------------------------------------------------------------------------------------------------
BANNER
Oracle9i Enterprise Edition Release 9.2.0.7.0 - Production
PL/SQL Release 9.2.0.7.0 - Production
"CORE 9.2.0.7.0 Production"
TNS for Solaris: Version 9.2.0.7.0 - Production
NLSRTL Version 9.2.0.7.0 - Production
----------------------------------------------------------------------------------------------------
спасибо
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34442402
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С точки зрения синтаксиса здесь все правильно. Ведь может dummy -- это функция, возвращающая константу
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
tst> create function dum return number
   2   as begin return  1 ; end;
   3   /

Function created.

tst> select dum, count(*) from dual;

       DUM   COUNT(*)
---------- ----------
          1            1 

tst> select sysdate, count(*) from dual;

SYSDATE     COUNT(*)
--------- ----------
 06 -APR- 07            1 
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34442451
Iscender
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
SQL> CREATE OR REPLACE PROCEDURE mytest
   2   AS
   3   BEGIN
   4      FOR rec IN
   5      (
   6              SELECT  dummy, COUNT(*)
   7              FROM    dual
   8      )
   9      LOOP
  10              NULL;
  11      END LOOP;
  12   END;
  13   /

Procedure created.

SQL> exec  mytest
BEGIN mytest; END;

*
ERROR at line  1 :
ORA- 00937 : not a single-group group function
ORA- 06512 : at "ISCANDER.MYTEST", line  4 
ORA- 06512 : at line  1 


SQL> CREATE OR REPLACE PROCEDURE mytest
   2   AS
   3   BEGIN
   4      FOR rec IN
   5      (
   6              SELECT  dummy, COUNT(*)
   7              FROM    dual
   8              GROUP BY dummy
   9      )
  10      LOOP
  11              NULL;
  12      END LOOP;
  13   END;
  14   /

Procedure created.

SQL> exec  mytest

PL/SQL procedure successfully completed.
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34442466
_spy_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав ЛюбомудровС точки зрения синтаксиса здесь все правильно. Ведь может dummy -- это функция, возвращающая константу
Хм.. мне казалось, что и разрешение имен происходит на этапе компиляции, а не выполнения.
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34442500
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну, еще примерчик
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
tst> sho user
USER is "U1"
tst> create function dummy return number
   2   as begin return  1 ; end;
   3   /

Function created.

tst> create procedure p1 as
   2   c1 varchar2( 10 ); c2 number;
   3   begin
   4   select dummy, count(*) into c1, c2 from dual;
   5   end;
   6   /

Procedure created.

tst> exec p1;
BEGIN p1; END;

*
ERROR at line  1 :
ORA- 00937 : not a single-group group function
ORA- 06512 : at "U1.P1", line  4 
ORA- 06512 : at line  1 


tst> create table dual as select dummy x from sys.dual;

Table created.

tst> exec p1;

PL/SQL procedure successfully completed.

tst> 
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34442562
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не согласен, Вячеслав, с Вашими примерами.
А Вы-то в них верите? Вячеслав Любомудров
Код: plaintext
1.
tst> create table dual as select dummy x from sys.dual;
После выполнения этой строки процедура p1 пересобирается, а запрос внутри неё с точки зрения Оракла становится совершенно другим.
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34442620
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я к тому, что синтаксис допустимый , а проверять в момент компиляции ХП такие тонкие моменты поле это или функция/константа -- слишком накладно, пожалуй
А вот на этапе parse SQL-машина и выдаст ошибку
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34442634
TiG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxНе согласен, Вячеслав, с Вашими примерами.
А Вы-то в них верите? Вячеслав Любомудров
Код: plaintext
1.
tst> create table dual as select dummy x from sys.dual;
После выполнения этой строки процедура p1 пересобирается, а запрос внутри неё с точки зрения Оракла становится совершенно другим.

Ну тогда вспомним такую фичу как процедуры с правами вызывающего - что реально будет вызываться станет известно только на момент выполнения.
А здесь дело в том, думается, что с точки зрения компилятора COUNT точно такая же функция как и все прочие, не агрегатные. Поэтому синтаксически здесь действительно совершенно корректный код. И ошибка поэтому времени исполнения - происходит только тогда, когда выполняется сама процедура, и sql-машина решает что же ей на самом деле прийдется делать с этим запросом и какие функции вызывать ;-)
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34442701
Jannny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TiGНу тогда вспомним такую фичу как процедуры с правами вызывающего - что реально будет вызываться станет известно только на момент выполнения.Только в данном случае это совсем ни при чем...

TiGА здесь дело в том, думается, что с точки зрения компилятора COUNT точно такая же функция как и все прочие, не агрегатные.А это очень похоже, даже при уточнении через алиас, что dummy - это поле, результат не меняется.

PS: andreymxа вообще-то, конечно, достаёт в процессе разработки, что компилятор не ругается сразуПрисоединюсь, не очень приятно, что проверка пролетит мимо :(
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34442710
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TiGНу тогда вспомним такую фичу как процедуры с правами вызывающего - что реально будет вызываться станет известно только на момент выполнения.
А здесь дело в том, думается, что с точки зрения компилятора COUNT точно такая же функция как и все прочие, не агрегатные. Поэтому синтаксически здесь действительно совершенно корректный код. И ошибка поэтому времени исполнения - происходит только тогда, когда выполняется сама процедура, и sql-машина решает что же ей на самом деле прийдется делать с этим запросом и какие функции вызывать ;-)Да, теперь согласен, всё понял
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34442728
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Jannny TiGНу тогда вспомним такую фичу как процедуры с правами вызывающего - что реально будет вызываться станет известно только на момент выполнения.Только в данном случае это совсем ни при чем...
Именно причем
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34442740
TiG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Jannny[quot TiG]Ну тогда вспомним такую фичу как процедуры с правами вызывающего - что реально будет вызываться станет известно только на момент выполнения.Только в данном случае это совсем ни при чем...
[quot]

Это я не к приведенному выше примеру, а альтернативный пример. И по моему оночень даже в тему ;-))
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34442858
Jannny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав Любомудров Jannny TiGНу тогда вспомним такую фичу как процедуры с правами вызывающего - что реально будет вызываться станет известно только на момент выполнения.Только в данном случае это совсем ни при чем...
Именно причемПочему? Проверка при компиляции с правами создателя по-любому, так что ИМХо речь не о том, что Оракл не занет, что это будет поле или константа. Тем более, что если переписать:
Код: plaintext
SELECT t.dummy, COUNT(*) FROM	dual t
это ничего не изменит.. Или если у создателя, например, dummy - это процедура, а у потенциального исполнителя с правами вызывающего это функция, то компиляться же по-любому не будет. Это я к тому, что не понимаю, как в этом случае это может быть связано.
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34442907
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
tst> sho user
USER is "U1"
tst> create procedure p1 authid current_user as
   2   c1 varchar2( 10 ); c2 number;
   3   begin
   4   select dummy, count(*) into c1, c2 from dual;
   5   end;
   6   /

Procedure created.

tst> grant execute on p1 to u2;

Grant succeeded.

tst> exec p1
BEGIN p1; END;

*
ERROR at line  1 :
ORA- 00937 : not a single-group group function
ORA- 06512 : at "U1.P1", line  4 
ORA- 06512 : at line  1 


tst> connect u2/u2@tst
Connected.
tst> create table dual as select dummy x from sys.dual;

Table created.

tst> create function dummy return number
   2   as begin return  1 ; end;
   3   /

Function created.

tst> exec u1.p1

PL/SQL procedure successfully completed.

tst> 
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34442963
_spy_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИМХО, разговор уходит в другую плоскость. В процедурах с правами выполняющего большая часть проверок происходит во время исполнения, поэтому как раз к ней претензий нет, а вот в процедуре с правами создателя необходимые проверки производится на этапе компиляции, отсюда и возник вопрос, как же так. Так что присоединяюсь к мнению Jannny, что упоминание authid current_user здесь как-то не при чем.
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34443019
Jannny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав Любомудров?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
tst> sho user
USER is "U1"
tst> create procedure p1 authid current_user as
   2   c1 varchar2( 10 ); c2 number;
   3   begin
   4   select dummy, count(*) into c1, c2 from dual;
   5   end;
   6   /
Procedure created.
И что? Если все то же происходит и без authid current_user, то с чего делается вывод, что эти вещи как-то связаны?
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34443020
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я бы вообще перенес эту проверку на этап выполнения
Ведь если значение поля одинаковое -- результат вполне осмысленен и верен
Ведь делается такое для scalar subquery (ORA-01427).

Может у них такое намерение и было :)
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34443043
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поддерживаю автора темы. Меня такое поведение тоже сильно раздражает.
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34443090
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав ЛюбомудровЯ бы вообще перенес эту проверку на этап выполнения. Ведь если значение поля одинаковое -- результат вполне осмысленен и верен
Не согласен. С точки зрения качества программного продукта (надежности, удобства сопровождения итп) крайне нежелательно иметь в коде фрагменты, которые "как правило работают, но могут стрельнуть" (скажем, в Вашем примере поменять return 1 на return dbms_random.value - и что будет?). Поэтому я однозначно предпочитаю подход "ты скажи четко и толком, что тебе надо, а всякую сомнительную неоднозначную фигню я зарублю".
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34443306
TiG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarer Вячеслав ЛюбомудровЯ бы вообще перенес эту проверку на этап выполнения. Ведь если значение поля одинаковое -- результат вполне осмысленен и верен
Не согласен. С точки зрения качества программного продукта (надежности, удобства сопровождения итп) крайне нежелательно иметь в коде фрагменты, которые "как правило работают, но могут стрельнуть" (скажем, в Вашем примере поменять return 1 на return dbms_random.value - и что будет?). Поэтому я однозначно предпочитаю подход "ты скажи четко и толком, что тебе надо, а всякую сомнительную неоднозначную фигню я зарублю".

Ну эта проблема вряд ли имеет отношение к качеству продукта, все таки если она есть - выстрелит при первом же тестовом запуске.
А вообще и сам периодически сталкиваюсь. Пишешь код с нуля - запросы отдельно проверяешь, дописывешь готовый - изменяешь прямо в коде, как итог иногда попадаюсь. Абыдно, да
Тем более что на этапе компиляции вся необходимая информация есть и отличить агрегатную функцию от обычной не составляет труда. Права вызывающего конечно отдельный случай, но и там тем не менее проверки доступности и т.п. объектов, используемых в коде, проводятся на этапе компиляции. И это правильно - чем раньше трабл найдем, тем быстрее исправим ;-)
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34443414
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Быть может, по обыкновению скажу несусветную глупость, но мне представляется, что при компиляции PL/SQL кода парсинга SQL-запросов не происходит. Поэтому проверки проверками, а данная ошибка - runtime.
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34443754
bl_beard
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymousБыть может, по обыкновению скажу несусветную глупость, но мне представляется, что при компиляции PL/SQL кода парсинга SQL-запросов не происходит. Поэтому проверки проверками, а данная ошибка - runtime.

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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
SQL> edit
Wrote file afiedt.buf

   1   CREATE OR REPLACE procedure test_pr is
   2   begin
   3       select count("bla-bla") from dual;
   4 * end;
SQL> /

Warning: Procedure created with compilation errors.

SQL> show errors;
Errors for PROCEDURE TEST_PR:

LINE/COL ERROR
-------- -----------------------------------------------------------------
 3 / 5       PL/SQL: SQL Statement ignored
 3 / 18      PL/SQL: ORA- 00904 : "bla-bla": invalid identifier
SQL>

как несложно понять из этого примера парсинг запроса таки произошел и
откровенную лажу, типа доступа к полям, которых
действительно нет в таблице оно все таки выщемило.

пс "оно" - это Оракл. :)
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34443962
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bl_beard
Код: plaintext
1.
2.
3.
4.
-------- -----------------------------------------------------------------
 3 / 5       PL/SQL: SQL Statement ignored
 3 / 18      PL/SQL: ORA- 00904 : "bla-bla": invalid identifier
SQL>

как несложно понять из этого примера парсинг запроса таки произошел и
откровенную лажу, типа доступа к полям, которых
действительно нет в таблице оно все таки выщемило.
Так где парсинг-то?
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34444001
Andrew Max
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
При выполнении DDL оператора (CREATE OR REPLACE) парсинг, безусловно, происходит.
Но следующий пример показывает, что даже парсинг анонимного блока не вызывает ошибок, в то время как парсинг отдельного SQL-запроса приводит к ORA-00937:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
SQL> declare
   2     c number;
   3   begin
   4     c := dbms_sql.open_cursor;
   5     dbms_sql.parse
   6       (c,
   7       'BEGIN
  8      FOR REC IN
  9      (
 10        SELECT A."DUMMY", COUNT(*) FROM SYS.DUAL A
 11      )
 12      LOOP
 13        NULL;
 14      END LOOP;
 15      END;',
  16       dbms_sql.native);
  17     dbms_sql.close_cursor(c);
  18   exception
  19     when others then
  20       if dbms_sql.is_open(c) then
  21         dbms_sql.close_cursor(c);
  22       end if;
  23       raise;
  24   end;
  25   /

Процедура PL/SQL успешно завершена.

SQL> declare
   2     c number;
   3   begin
   4     c := dbms_sql.open_cursor;
   5     dbms_sql.parse
   6       (c,
   7       'SELECT A."DUMMY", COUNT(*) FROM SYS.DUAL A',
   8       dbms_sql.native);
   9     dbms_sql.close_cursor(c);
  10   exception
  11     when others then
  12       if dbms_sql.is_open(c) then
  13         dbms_sql.close_cursor(c);
  14       end if;
  15       raise;
  16   end;
  17   /
declare
*
ошибка в строке  1 :
ORA- 00937 : групповая функция не является одногруппной
ORA- 06512 : на  line  15 


SQL>
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34444066
Фотография Timm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Andrew MaxПри выполнении DDL оператора (CREATE OR REPLACE) парсинг, безусловно, происходит.
Но следующий пример показывает, что даже парсинг анонимного блока не вызывает ошибок, в то время как парсинг отдельного SQL-запроса приводит к ORA-00937:
...
Не понимаю, в чем может быть разница при парсинге анонимного/хранимого PL-блоков? Для чего этот пример? :)
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34444078
Jannny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Timm Andrew MaxПри выполнении DDL оператора (CREATE OR REPLACE) парсинг, безусловно, происходит.
Но следующий пример показывает, что даже парсинг анонимного блока не вызывает ошибок, в то время как парсинг отдельного SQL-запроса приводит к ORA-00937:
...
Не понимаю, в чем может быть разница при парсинге анонимного/хранимого PL-блоков? Для чего этот пример? :)Потому что в приведенном примере продемонстрирован явный парсинг
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34444127
Andrew Max
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Timm Andrew MaxПри выполнении DDL оператора (CREATE OR REPLACE) парсинг, безусловно, происходит.
Но следующий пример показывает, что даже парсинг анонимного блока не вызывает ошибок, в то время как парсинг отдельного SQL-запроса приводит к ORA-00937:
...
Для чего этот пример? :)
Ммм... пока думал, как ответить - за меня ответила Jannny. Спасибо.
Пример - ни для чего иного, кроме как в качестве ответа на мнение, высказанное здесь:

andrey_anonymous... мне представляется, что при компиляции PL/SQL кода парсинга SQL-запросов не происходит.
Пример с DBMS_SQL просто показал, что парсинг происходит-таки. Еще его, разумеется, можно увидеть "явно", через V$MYSTAT:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
SQL> select n.name, s.value
   2     from v$statname n,
   3          v$mystat s
   4    where n.name like 'parse count%'
   5      and n.statistic# = s.statistic#;

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
parse count (total)                                                      130 
parse count (hard)                                                        21 
parse count (failures)                                                     4 

SQL> /

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
parse count (total)                                                      132 
parse count (hard)                                                        21 
parse count (failures)                                                     4 

SQL> CREATE OR REPLACE PROCEDURE mytest AS
   2   BEGIN
   3      FOR rec IN (SELECT dummy, COUNT(*) FROM dual)
   4     LOOP
   5       NULL;
   6     END LOOP;
   7   END;
   8   /

Процедура создана.

SQL> select n.name, s.value
   2     from v$statname n,
   3          v$mystat s
   4    where n.name like 'parse count%'
   5      and n.statistic# = s.statistic#;

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
parse count (total)                                                      190 
parse count (hard)                                                        22 
parse count (failures)                                                     4 

Но ошибки данный парсинг по каким-то причинам не вызывает. По поводу природы этих причин у меня пока гипотез нет.
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34444137
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TimmНе понимаю, в чем может быть разница при парсинге анонимного/хранимого PL-блоков? Для чего этот пример? :)Для того, чтобы показать, что парсер чисто-SQL-я и парсер SQL-я-внутри-PL/SQL-я - это всё ещё разные движки.
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34444194
Фотография Timm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ага, понятно, спасибо.
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34444241
Andrew Max
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав Любомудров Jannny TiGНу тогда вспомним такую фичу как процедуры с правами вызывающего - что реально будет вызываться станет известно только на момент выполнения.Только в данном случае это совсем ни при чем...
Именно причем
Увы, ни функции, ни AUTHID здесь ни при чем.
В следующем примере уж точно нет ничего, что можно было бы посчитать функцией либо списать на механизм AUTHID:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
SQL> CREATE OR REPLACE PROCEDURE mytest AS
   2   BEGIN
   3      FOR rec IN (SELECT * FROM SYS.DUAL D GROUP BY NULL)
   4     LOOP
   5       NULL;
   6     END LOOP;
   7   END;
   8   /

Процедура создана.

SQL> exec mytest
BEGIN mytest; END;

*
ошибка в строке  1 :
ORA- 00979 : выражение не является выражением GROUP BY
ORA- 06512 : на  "MAX.MYTEST", line  3 
ORA- 06512 : на  line  1 

Мое ИМХО: причина - в "недоделанности" парсера.
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34444276
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Andrew MaxУвы, ни функции, ни AUTHID здесь ни при чем.
В следующем примере уж точно нет ничего, что можно было бы посчитать функцией либо списать на механизм AUTHID:
Код: plaintext
 FOR rec IN (SELECT * FROM SYS.DUAL D GROUP BY NULL)
Уважаю!
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34444327
Andrew Max
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymx Andrew MaxУвы, ни функции, ни AUTHID здесь ни при чем.
В следующем примере уж точно нет ничего, что можно было бы посчитать функцией либо списать на механизм AUTHID:
Код: plaintext
 FOR rec IN (SELECT * FROM SYS.DUAL D GROUP BY NULL)
Уважаю!
Хм. Польщен. Засмущался.
Спасибо, тезка.

ЗЫ: Алиас "D" можно из примера выбросить, он, разумеется, ни на что не влияет.
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34444594
Фотография orawish
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Andrew Max..
Мое ИМХО: причина - в "недоделанности" парсера.
+1
А банальная причина может быть в лени разбираться не есть ли это нечто
синтаксически корректное, например, при наличии окна:
Код: plaintext
select dummy,count(*) over() from dual
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34444899
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Andrew MaxПри выполнении DDL оператора (CREATE OR REPLACE) парсинг, безусловно, происходит.
Тезка, парсинг ЧЕГО?
А происходит парсинг DDL-предложения "create or replace..."
При этом никакого парсинга проблемного sql-предложения "select from..." НЕ ПРОИСХОДИТ, в чем можно элементарно убедиться по трассе 10046.
Все, что делается - проверка синтаксиса, семантика же предожения select на этом этапе не проверяется.
Ладно молодые и горячие, но Вы-то... Иеххх, куда катится мир :)
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34444937
Владимир Бегун
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymx...

#2765516

P.S.: В мире много сказок, в мире много сказок, грустных и смешных... ;)
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34444943
Andrew Max
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous...
Процитирую один важный момент еще раз:
andrey_anonymous... мне представляется, что при компиляции PL/SQL кода парсинга SQL-запросов не происходит.
Да, признаю, я несколько поспешил с критикой, упустив из виду то, что акцент был сделан на словах "SQL-запросов".

Мой пример с DBMS_SQL, демонстрирует тот факт, что даже парсинг анонимного PL/SQL-блока, содержащего некорректный статический SQL, выполняется успешно (и это, действительно, может стать источником малоприятных сюрпризов).

andrey_anonymousПри этом никакого парсинга проблемного sql-предложения "select from..." НЕ ПРОИСХОДИТ, в чем можно элементарно убедиться по трассе 10046.
Вот здесь, на мой взгляд, нужно определиться с терминами.

Разумеется, в трассе 10046 в нашем случае не будет упоминаний об отдельных запросах в нашем PL/SQL-блоке, который подвергается парсингу. Конечно, не увидим мы никаких следов и в V$SQL, V$SQL_PLAN. Все это вполне логично и понятно: никаких SQL-курсоров на данном этапе мы не открываем и никаких планов выполнения не строим.

Но можем ли мы на основании этих факторов судить о том, что "никакого парсинга проблемного sql-предложения не происходит"?

Полагаю, что все-таки не можем.
Да, вышеперечисленные факторы дают нам основания полагать, что в нашей ситуации запросы не парсятся SQL-машиной. Но они, разумеется, обрабатываются PL/SQL-парсером, который, в силу особенностей своей реализации, иногда вот так вот чудит.

Разумеется, мы должны помнить о том, что парсинг - это не только построение планов. Строго говоря, планами вообще занимается не парсер, а query optimizer. А парсинг - это прежде всего синтаксическая и семантическая проверки , без которых статический SQL в PL/SQL - просто немыслим.

andrey_anonymousВсе, что делается - проверка синтаксиса, семантика же предложения select на этом этапе не проверяется.
Здесь категорически не согласен. Проверка семантики обязана выполняться ( и выполняется ).

К примеру, следующий запрос корректен синтаксически, но неверен семантически:

Код: plaintext
SELECT BLABLABLA FROM SYS.DUAL;

Семантические проверки - это проверки того, что указанные в запросе объекты существуют и пользователь имеет все необходимые привилегии. Столбец "BLABLABLA" отсутствует в таблице SYS.DUAL, поэтому семантическая проверка окончится неуспешно, хотя с синтаксической точки зрения звпрос корректен.

Разумеется, PL/SQL такой семантически некорректный запрос не пропустит:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
SQL> CREATE OR REPLACE PROCEDURE TESTA IS
   2   BEGIN
   3     FOR REC IN
   4       (SELECT BLABLABLA FROM SYS.DUAL)
   5     LOOP
   6       NULL;
   7     END LOOP;
   8   END;
   9   /

Warning: Procedure created with compilation errors.

SQL> show errors
Errors for PROCEDURE TESTA:

LINE/COL ERROR
-------- ----------------------------------------------------
 4 / 5       PL/SQL: SQL Statement ignored
 4 / 12      PL/SQL: ORA- 00904 : "BLABLABLA": invalid identifier
SQL>

А вот такой звпрос будет некорректным даже синтаксически:

Код: plaintext
SELECT * SYS.DUAL; 

Например, вот здесь , в начале статьи все это обстоятельно описывается.

Так что - нет, пока что Вы не убедили меня в том, что при парсинге PL/SQL-блоков "никакого парсинга проблемных sql-предложений" не происходит. Происходит . Просто выполняется он, по-видимому, PL/SQL-парсером, что иногда приводит к таким вот казусам.

andrey_anonymousЛадно молодые и горячие, но Вы-то...
Я заинтригован.
Вы разве обладаете информацией относительно моего возраста?
:)
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34445072
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Andrew MaxНо можем ли мы на основании этих факторов судить о том, что "никакого парсинга проблемного sql-предложения не происходит"?
Пришла моя очередь уточнить что конкретно я имел ввиду :)
А имел я ввиду тот факт, что в обсуждаемом случае парсинг не производится SQL-машиной, потому и ссылался на 10046.

Да, безусловно, парсинг - составная часть процесса компиляции PL/SQL кода. Но парсер PL/SQL машины - это совсем другой парсер, он разбирает PL/SQL.
Да, семантическая проверка - часть парсинга. Но семантика PL/SQL и семантика SQL - все-таки заметно отличаются. PL/SQL - императивен, SQL - декларативный язык. Поэтому парсер PL/SQL, несмотря на ряд выполняемых проверок, не может заменить собой парсер SQL.
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34445084
Рико
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andrey_anonymous
Да, безусловно, парсинг - составная часть процесса компиляции PL/SQL кода. Но парсер PL/SQL машины - это совсем другой парсер, он разбирает PL/SQL.
Да, семантическая проверка - часть парсинга. Но семантика PL/SQL и семантика SQL - все-таки заметно отличаются. PL/SQL - императивен, SQL - декларативный язык. Поэтому парсер PL/SQL, несмотря на ряд выполняемых проверок, не может заменить собой парсер SQL.
Отработка dbms_output в процедуре перед вызовом ошибки говорит, видимо, в пользу этих слов...
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34445114
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
РикоОтработка dbms_output в процедуре перед вызовом ошибки говорит, видимо, в пользу этих слов...
Не поясните свою мысль?
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34446200
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С этим оператором что-то вообще не все понятно
Например, он не попадает в трассу -- ни разбор, ни ошибка. Возможно, надо выполнять трассировку с другим уровнем, но все равно это как-то аномально.
Еще мне интересно, почему в трассе нет ошибок выполнения?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
tst> alter session set sql_trace=true;

Session altered.

tst> select Dummy, count(*) from dual;
select Dummy, count(*) from dual
       *
ERROR at line  1 :
ORA- 00937 : not a single-group group function


tst> select dm from dual;
select dm from dual
       *
ERROR at line  1 :
ORA- 00904 : "DM": invalid identifier


tst> select * from dual where dummy=
   2   (select  1  from dual union all select  2  from dual);
select * from dual where dummy=
                         *
ERROR at line  1 :
ORA- 01722 : invalid number


tst> select * from dual where dummy=
   2   (select '1' from dual union all select '2' from dual);
(select '1' from dual union all select '2' from dual)
 *
ERROR at line  2 :
ORA- 01427 : single-row subquery returns more than one row


tst> alter session set sql_trace=false;

Session altered.

tst> connect u1/u1@tst
Connected.
tst> 
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
*** 2007-04-09 10:52:08.169
*** SESSION ID:(10.5864) 2007-04-09 10:52:08.169
APPNAME mod='SQL*Plus' mh=3669949024 act='' ah=4029777240
=====================
PARSING IN CURSOR #1 len=32 dep=0 uid=24 oct=42 lid=24 tim=2863421259068 hv=3943786303 ad='2f09e5dc'
alter session set sql_trace=true
END OF STMT
EXEC #1:c=0,e=266,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=2863421258761
*** 2007-04-09 10:52:20.374
=====================
PARSING IN CURSOR #2 len=198 dep=1 uid=0 oct=3 lid=0 tim=2863433178620 hv=2703824309 ad='2ff65780'
select obj#,type#,ctime,mtime,stime,status,dataobj#,flags,oid$, spare1, spare2 from obj$ where owner#=:1 and name=:2 and namespace=:3 and remoteowner is null and linkname is null and subname is null
END OF STMT
PARSE #2:c=0,e=159,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=2863433178603
EXEC #2:c=0,e=185,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=2863433179400
FETCH #2:c=0,e=114,p=0,cr=2,cu=0,mis=0,r=0,dep=1,og=4,tim=2863433179606
=====================
PARSING IN CURSOR #2 len=198 dep=1 uid=0 oct=3 lid=0 tim=2863440951894 hv=2703824309 ad='2ff65780'
select obj#,type#,ctime,mtime,stime,status,dataobj#,flags,oid$, spare1, spare2 from obj$ where owner#=:1 and name=:2 and namespace=:3 and remoteowner is null and linkname is null and subname is null
END OF STMT
PARSE #2:c=0,e=149,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=2863440951877
EXEC #2:c=0,e=136,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=2863440952544
FETCH #2:c=0,e=65,p=0,cr=2,cu=0,mis=0,r=0,dep=1,og=4,tim=2863440952782
EXEC #2:c=0,e=82,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=2863440953282
FETCH #2:c=0,e=43,p=0,cr=2,cu=0,mis=0,r=0,dep=1,og=4,tim=2863440953409
=====================
PARSE ERROR #1:len=20 dep=0 uid=24 oct=3 lid=24 tim=2863440953580 err=904
select dm from dual
*** 2007-04-09 10:52:57.646
=====================
PARSING IN CURSOR #1 len=81 dep=0 uid=24 oct=3 lid=24 tim=2863469576374 hv=1927069963 ad='2f084794'
select * from dual where dummy=
(select 1 from dual union all select 2 from dual)
END OF STMT
PARSE #1:c=0,e=2222,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=4,tim=2863469576353
EXEC #1:c=0,e=108,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=2863469576843
FETCH #1:c=0,e=160,p=0,cr=3,cu=0,mis=0,r=0,dep=0,og=4,tim=2863469577141
STAT #1 id=1 cnt=0 pid=0 pos=1 obj=0 op='FILTER  '
=====================
PARSING IN CURSOR #2 len=116 dep=1 uid=0 oct=3 lid=0 tim=2863489522417 hv=431456802 ad='2ff628a8'
select o.owner#,o.name,o.namespace,o.remoteowner,o.linkname,o.subname,o.dataobj#,o.flags from obj$ o where o.obj#=:1
END OF STMT
PARSE #2:c=10000,e=1714,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=0,tim=2863489522404
EXEC #2:c=0,e=888,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=2863489523795
FETCH #2:c=0,e=81,p=0,cr=3,cu=0,mis=0,r=1,dep=1,og=4,tim=2863489523978
STAT #1 id=2 cnt=1 pid=1 pos=1 obj=222 op='TABLE ACCESS FULL DUAL '
STAT #1 id=3 cnt=0 pid=1 pos=2 obj=0 op='UNION-ALL  '
STAT #1 id=4 cnt=0 pid=3 pos=1 obj=222 op='TABLE ACCESS FULL DUAL '
STAT #1 id=5 cnt=0 pid=3 pos=2 obj=222 op='TABLE ACCESS FULL DUAL '
=====================
PARSING IN CURSOR #1 len=85 dep=0 uid=24 oct=3 lid=24 tim=2863489526270 hv=2466126633 ad='2f06c730'
select * from dual where dummy=
(select '1' from dual union all select '2' from dual)
END OF STMT
PARSE #1:c=0,e=1612,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=4,tim=2863489526258
EXEC #1:c=0,e=94,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=2863489526583
FETCH #1:c=0,e=237,p=0,cr=9,cu=0,mis=0,r=0,dep=0,og=4,tim=2863489526987
STAT #1 id=1 cnt=0 pid=0 pos=1 obj=0 op='FILTER  '
STAT #1 id=2 cnt=1 pid=1 pos=1 obj=222 op='TABLE ACCESS FULL DUAL '
STAT #1 id=3 cnt=2 pid=1 pos=2 obj=0 op='UNION-ALL  '
STAT #1 id=4 cnt=1 pid=3 pos=1 obj=222 op='TABLE ACCESS FULL DUAL '
STAT #1 id=5 cnt=1 pid=3 pos=2 obj=222 op='TABLE ACCESS FULL DUAL '
=====================
PARSING IN CURSOR #1 len=33 dep=0 uid=24 oct=42 lid=24 tim=2863499414887 hv=4238949625 ad='2f748900'
alter session set sql_trace=false
END OF STMT
PARSE #1:c=0,e=180,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=2863499414875
EXEC #1:c=0,e=140,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=2863499415195
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34446383
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владимир Бегун#2765516
Код: plaintext
1.
2.
3.
4.
5.
6.
Bug No.		2765516 
Filed		23-JAN-2003
Updated		23-JAN-2003 
Product		PL/SQL
Product Version	9.0.1.4.0
...
Fixed in Product Version	No Data

За 4 года некому было пофиксить
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34446403
Владимир Бегун
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxЗа 4 года некому было пофиксить:-) Приоритет низкий, есть workaround...
...
Рейтинг: 0 / 0
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #34446420
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxЗа 4 года некому было пофикситьЭто древняя "фича" :)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
SQL*Plus: Release 3.3.4.0.0 - Production on Mon Apr 09 08:42:36 2007

Copyright (c) Oracle Corporation 1979,  1996 .  All rights reserved.


Connected to:
Oracle7 Server Release  7.3 .4.0.0 - Production
With the distributed, replication and parallel query options
PL/SQL Release 2.3.4.0.0 - Production

Monday    09.04.2007 08:42.  User - "SYSTEM".  Database - "ELIC".

System@Elic>; CREATE OR REPLACE PROCEDURE mytest AS
System@Elic>; BEGIN
System@Elic>;    FOR rec IN (SELECT * FROM SYS.DUAL D GROUP BY NULL)
System@Elic>;   LOOP
System@Elic>;     NULL;
System@Elic>;   END LOOP;
System@Elic>; END;
System@Elic>; /

Procedure created.

System@Elic>;
System@Elic>; exec mytest
begin mytest; end;

*
ERROR at line 1:
ORA-00979: not a GROUP BY expression
ORA-06512: at "SYSTEM.MYTEST", line 5
ORA-06512: at line 1
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
    #39446855
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
...
Рейтинг: 0 / 0
44 сообщений из 44, показаны все 2 страниц
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Кривой вопрос в пятницу: PL-SQL, групповые функции, статический SQL, Том Кайт
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]