Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / SQL20267N в функции и далее / 25 сообщений из 30, страница 1 из 2
01.06.2006, 13:33
    #33765884
ValPot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
Конвертируя предложения используемые в функциях и процедурах типа

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
 SET (p1,p2,p3) =

 ( select max(p1),max(p2),max(p3) 
    from t1
       left join TABLE(func1(t1.pt1)) AS t2
       left join t3 on t3.val=t2.val
 )

или даже

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
 SET (p1,p2,p3) =

 ( select max(p1),max(p2),max(p3) 
    from TABLE(func1('constanta')) AS t2
       left join t1 on t1.val=t2.val
       left join t3 on t3.val=t1.val
 )

которые понимаются IB,ORACLE, MSSQL

получаю SQL20267N с кодом (1) с советом использовать SELECT statment, для размещения вызова функции последней в FROM предложении. Но WITH ( т.е SELECT statment ) синтаксически в SET не проходит.

Нет ли решения более элегантного чем создание промежуточной таблицы для эмуляции результата вызова во 2 случае.

Как выкручиваться в первом случае, вообще непонятно.
...
Рейтинг: 0 / 0
01.06.2006, 15:00
    #33766209
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
Код: plaintext
1.
2.
3.
select max(p1),max(p2),max(p3) into p1, p2, p3
    from t1
       left join TABLE(func1(t1.pt1)) AS t2
       left join t3 on t3.val=t2.val;
Это для статического sql.
...
Рейтинг: 0 / 0
01.06.2006, 15:00
    #33766210
Victor Metelitsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
Если
Код: plaintext
1.
2.
3.
4.
5.
6.
SET (p1,p2,p3) =
   (select max(t1.p1),max(t2.p2),max(t3.p3) 
    from t1
       left join TABLE(func1(t1.pt1)) AS t2
       left join t3 on t3.val=t2.val
   )


Может, так сойдёт?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
SET (p1,p2,p3) =
   (select max(z.p1),max(z.p2),max(t3.p3) 
    from (
          select t1.p1, t2.p2, t2.val
            from t1 left join TABLE(func1(t1.pt1)) AS t2
       ) z
       left join t3 on t3.val=z.val
   )

Кстати, ведь SQL20267N - это The function function-name (specific specific-name) modifies SQL data and is invoked in an illegal context. Крутые же вы штуки выделываете...
...
Рейтинг: 0 / 0
01.06.2006, 15:07
    #33766246
Victor Metelitsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
Mark Barinstein
Код: plaintext
1.
select max(p1),max(p2),max(p3) into p1, p2, p3
   ...
Это для статического sql.
Там ведь загвоздка в функции, которая, мало того, что возвращает набор строк, ещё и модифицирует данные. Мне кажется, что предложенное в help'е переписывание с WITH и мой вариант эквивалентны.
...
Рейтинг: 0 / 0
01.06.2006, 17:00
    #33766722
ValPot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
VM

Может, так сойдёт?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
SET (p1,p2,p3) =
   (select max(z.p1),max(z.p2),max(t3.p3) 
    from (
          select t1.p1, t2.p2, t2.val
            from t1 left join TABLE(func1(t1.pt1)) AS t2
       ) z
       left join t3 on t3.val=z.val
   )



На данный ход я получил SQL20267N причина 2. Как можно это перенести во внешнюю выборку ( т.е. для функции в RETURN, как я понимаю ) если по функции таких кусков несколько мне непонятно, т.е. наверно невозможно.

MB
Код: plaintext
1.
2.
3.
4.
select max(p1),max(p2),max(p3) into p1, p2, p3
    from t1
       left join TABLE(func1(t1.pt1)) AS t2
       left join t3 on t3.val=t2.val;
Это для статического sql.


Буду думать как мне эту непонятную статичность обеспечить. Привык, что трансляторы сами обычно решают подобные вопросы. Но с учетом позднего замечания VM путь м.б. тупиковый.
...
Рейтинг: 0 / 0
01.06.2006, 17:15
    #33766796
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
ValPot
Буду думать как мне эту непонятную статичность обеспечить. Привык, что трансляторы сами обычно решают подобные вопросы. Но с учетом позднего замечания VM путь м.б. тупиковый.
Да вы не пугайтесь, просто напишите в своей процедуре так примерно, как в этом работающем примере:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
create function t(v varchar( 10 ))
modifies sql data
returns table
(
c varchar( 10 )
)
begin atomic
declare c varchar( 10 );
set c=t.v;
return select c from sysibm.sysdummy1;
end@

create procedure test_into()
begin
 declare i char( 1 );
 declare c varchar( 10 );
 select max(d.ibmreqd), min(t.c) into i, c 
 from sysibm.sysdummy1 d
 left join table(t(d.ibmreqd)) t on  1 = 1 ;
end@
Пример тупой, в смысл его не вникайте, т.к. его там нет.
Это просто демонстрация этого статического sql.
В вашем примере похожий подход прокатит?
...
Рейтинг: 0 / 0
01.06.2006, 17:44
    #33766901
ValPot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
Так я так и пишу

Код: 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.
create function PR_B_PORT_RATE (  
    ...
    PORT VARCHAR( 255 ))
returns table 
(
    OFICDATE timestamp,
    ...
    IS_MARKET_RATE integer)
LANGUAGE SQL
MODIFIES SQL DATA
BEGIN ATOMIC 
    DECLARE A_MODE$ VARCHAR( 255 );
    DECLARE MODE$ VARCHAR( 255 );
    DECLARE O_MODE$ VARCHAR( 255 );
    DECLARE A_RATER$  integer;
    DECLARE RATER$  integer;
    DECLARE O_RATER$  integer;
    DECLARE I_TYPE$  integer;
    DECLARE STAVKA$  numeric(  22 ,  7 );
 
    ....
 
      select  max(AM.DOP), max(OM.DOP), max(C.A_RATER), max(C.O_RATER), max(C.I_TYPE), max(C.STAVKA) 
             into A_MODE$,O_MODE$,A_RATER$,O_RATER$,I_TYPE$,STAVKA$
      from table(PR_STR_TO_LIST(pr_b_port_rate.PORT)) as L
      left join D_B_CONTRACTS C on C.DOC=L.VAL
      left join OD_SYS_TABS AM on AM.NUM=C.A_MODE and AM.CODE='RATE_MODE'
      left join OD_SYS_TABS OM on OM.NUM=C.O_MODE and OM.CODE='RATE_MODE';

    .... 
    далее еще метр текста


а она мне в ответ


Код: plaintext
1.
2.
3.
4.
SQL0104N  Обнаружен неправильный элемент "A_MODE$" после текста ")             
into".  Список правильных элементов: "<space>".  LINE NUMBER= 66 .  
SQLSTATE= 42601 


в чем моя нестатичность ?
...
Рейтинг: 0 / 0
01.06.2006, 18:32
    #33767111
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
ValPot
в чем моя нестатичность ?
В функциях вы не можете использовать
Код: plaintext
select into
Мой вам глобальный совет:
В db2 sql функции слабо приспособлены для выполнения в них сложной логики.
Они должны выполняться быстро и просто, чтобы sql команды, в которых они используются, могли хорошо оптимизироваться.
Для сложной логики есть sql и external (если совсем тяжело) процедуры.
Я понимаю, что вы портируете что-то с других систем и у вас есть уже устоявшийся стиль программирования и много написанного кода.
Но, все таки хорошо подумайте над тем, чтобы использовать процедуры вместо функций.
Мое ИМХО: не прислушавшись, вы, может быть, и получите в конце концов рабочую систему, но только для того, чтобы потом сказать: db2 - это большое Г@$%о, которое предназначено только для настольных приложений.
...
Рейтинг: 0 / 0
01.06.2006, 18:40
    #33767139
Astron
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
Хм, не скажете версию DB2 на которую вы это переводите? Не то чтобы я ответ знал, просто интересно.
Про 2-й вариант - просто версия, если функцию определить как DETERMINISTIC - может это поможет?
Про первый вариант - опять же чистая теория, и вдобавок DB2 LUW 8.1.4 и выше надо - нельзя ли переделать логику под использование конструкции
SELECT.. FROM {NEW|OLD|FINAL} TABLE (insert|update)
(это если функция простая-ее получится запихать в апдейт или инсерт)
Прошу прощения что не проверял свои предложения - и некогда и версию сервера вашего не знаю...
...
Рейтинг: 0 / 0
01.06.2006, 18:53
    #33767169
Astron
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
ValPotТак я так и пишу

Код: plaintext
1.
2.
3.
4.
5.
6.
      select  max(AM.DOP), max(OM.DOP), max(C.A_RATER), max(C.O_RATER), max(C.I_TYPE), max(C.STAVKA) 
             into A_MODE$,O_MODE$,A_RATER$,O_RATER$,I_TYPE$,STAVKA$
      from table(PR_STR_TO_LIST(pr_b_port_rate.PORT)) as L
      left join D_B_CONTRACTS C on C.DOC=L.VAL
      left join OD_SYS_TABS AM on AM.NUM=C.A_MODE and AM.CODE='RATE_MODE'
      left join OD_SYS_TABS OM on OM.NUM=C.O_MODE and OM.CODE='RATE_MODE';
а она мне в ответ

Код: plaintext
1.
2.
3.
4.
SQL0104N  Обнаружен неправильный элемент "A_MODE$" после текста ")             
into".  Список правильных элементов: "<space>".  LINE NUMBER= 66 .  
SQLSTATE= 42601 


в чем моя нестатичность ?

А тут обычная синтаксическая ошибка, SELECT INTO действительно нельзя, зато тут можно написать FOR и получить примерно то же самое.
...
Рейтинг: 0 / 0
01.06.2006, 19:19
    #33767228
ValPot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
Версия свежая 9 for Win.

MB. Проблемы .
1. Чтобы принимать сложное решение нужно хорошо чувствовать язык. А этого нет.
2. Обеспечивать портабельность очень сложного и активно развиваемого приложения невозможно в разных стилях.


Пока понятно, что на каждый такой Select первого типа можно автогенерить уникальную функцию или процедуру.

Со вторым типом хуже, когда у вас сотни живых запросов использующий данную, достаточно естественную и не запрещаемую стандартом SQL-92 , логику. Одна надежда что прием VM сработает в скрипте.
...
Рейтинг: 0 / 0
01.06.2006, 21:10
    #33767368
Victor Metelitsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
На всякий случай:

в UDF присваивание надо писать так:
SET (p1, p2, p3) = (select max(p1),max(p2),max(p3) ...)

а в SP надо писать так:
select max(p1),max(p2),max(p3) into p1, p2, p3 ...

странно, но...
...
Рейтинг: 0 / 0
01.06.2006, 22:54
    #33767442
Victor Metelitsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
Дела обстоят хуже, чем я думал.
Код: 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.
BEGIN ATOMIC
  DECLARE p1 VARCHAR( 10 );
  DECLARE p2 VARCHAR( 10 );
  SET (p1,p2) =   
       (
          select max(t1.p1), max(t2.p2)
            from T1 ,
              TABLE(func1(t1.pt1)) AS t2
            
       );
END
DB20000I  The SQL command completed successfully.

BEGIN ATOMIC
  DECLARE p1 VARCHAR( 10 );
  DECLARE p2 VARCHAR( 10 );
  SET (p1,p2) =
   (select max(z.p1),max(z.p2)
    from 
       (
          select t1.p1, t2.p2, t2.val
            from T1,
              TABLE(func1(t1.pt1)) AS t2
       ) z
   );
END
DB21034E  The command was processed as an SQL statement because it was not a 
valid Command Line Processor command.  During SQL processing it returned:
SQL20267N  The function "VVM.FUNC1" (specific "SQL060602005021800") modifies 
SQL data and is invoked in an illegal context. Reason code =  "2".  LINE 
NUMBER= 4 .  SQLSTATE=429BL

BEGIN ATOMIC
  DECLARE p1 VARCHAR( 10 );
  DECLARE p2 VARCHAR( 10 );
  SET (p1,p2) =   
       (
          select max(t1.p1), max(t2.p2)
            from T1 left join
              TABLE(func1(t1.pt1)) AS t2
            on  1 = 1 
       );
END
DB21034E  The command was processed as an SQL statement because it was not a 
valid Command Line Processor command.  During SQL processing it returned:
SQL20267N  The function "VVM.FUNC1" (specific "SQL060602005021800") modifies 
SQL data and is invoked in an illegal context. Reason code =  "5".  LINE 
NUMBER= 4 .  SQLSTATE=429BL
...
Рейтинг: 0 / 0
01.06.2006, 23:03
    #33767455
Victor Metelitsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
Интересно было бы узнать, что модифицирует пресловутая func1.
...
Рейтинг: 0 / 0
02.06.2006, 10:17
    #33767871
ValPot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
Что это за код причины 5. В моих доках такого нет.

Интересно когда их несколько, а когда сотни ..

Вот пример безобидного размера, но показывающий, как я вынужден бороться с отсутствием у DB2 возможности вызова Suspend где ни попадя.





Код: 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.
-- Создание служебной таблицы для эмуляция SUSPEND
create table TF_PR_STR_TO_LIST ( id_session varchar( 255 ), VAL integer ) ^ 
-- выделение из строки термов, разделенных запятой
create function PR_STR_TO_LIST ( STR VARCHAR( 255 )) 
returns table ( VAL integer)
LANGUAGE SQL
MODIFIES SQL DATA
BEGIN ATOMIC 
    DECLARE P$  integer;
    DECLARE L$  integer;
    DECLARE STR# VARCHAR( 255 );

    DECLARE w_VAL integer;
    
    -- приложение однопоточное поэтому ключ application_id() достаточен 
    delete from TF_PR_STR_TO_LIST  where id_session=application_id(); 
    
        set STR# =STR;
        SET P$ = f_substr( ',', STR# );
        SET L$ = f_strlen( STR# );
        while (P$>= 0 ) DO 
            SET w_VAL = int(f_left( STR#, P$ ));
            SET L$ = L$-P$- 1 ;
            SET STR# = f_right( STR#, L$ );
            insert into TF_PR_STR_TO_LIST values ( application_id(), w_VAL );
            SET P$ = f_substr( ',', STR# );
        end while;
        if (L$> 0 ) then
            SET w_VAL = int(STR#);
            insert into TF_PR_STR_TO_LIST values ( application_id(), w_VAL );
        end if;
        return  select  VAL  from TF_PR_STR_TO_LIST where id_session=application_id();
 END ^ 
...
Рейтинг: 0 / 0
02.06.2006, 10:54
    #33768008
Victor Metelitsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
Не...., ну, на DB2 так не программируют. Почитайте лучше "кулинарную книжку", посмотрите примеры рекурсивных запросов. Да даже табличный UDF на Java будет лучше.
...
Рейтинг: 0 / 0
02.06.2006, 10:59
    #33768018
Victor Metelitsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
А ещё лучше здесь UDF на C. Естественно, без всяких там временных таблиц.
...
Рейтинг: 0 / 0
02.06.2006, 11:37
    #33768134
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
create function tokenizer(c varchar( 255 ))
returns table (i int)
begin atomic
 return
 with t (c, i) as 
 (
   values 
   (
   substr(c, nullif(posstr(c, ','),  0 )+ 1 ),
   int(substr(c,  1 , coalesce(nullif(posstr(c, ','),  0 ), length(c)+ 1 )- 1 ))
   )
     union all
   select 
   substr(c, nullif(posstr(c, ','),  0 )+ 1 ),
   int(substr(c,  1 , coalesce(nullif(posstr(c, ','),  0 ), length(c)+ 1 )- 1 ))
   from t
   where t.c is not null
 )
 select t.i from t;
end@
...
Рейтинг: 0 / 0
02.06.2006, 11:54
    #33768214
Victor Metelitsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
О!

Про
Код: plaintext
1.
create function tokenizer(c varchar( 255 ))
...
мелкая оптимизация: насколько я помню по письмам от ibm-еров в db2-шной ньюсгруппе, если в функции можно обойтись одним return, не заключая в скобки begin atomic...end, оптимизатору это больше понравится.
...
Рейтинг: 0 / 0
02.06.2006, 11:57
    #33768233
ValPot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
Так как я решаю адачу полуавтоматической конвертации и последующей потдержки аутентичности вагона текстов написанных и перерабатываемых на SQL-92, а не потдержки культуры речи на диалекте DB2, то предложение изучить основы С, смотрится более адекватно.
...
Рейтинг: 0 / 0
02.06.2006, 12:28
    #33768378
Victor Metelitsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
Ничего не понял. В том числе про SQL-92.
...
Рейтинг: 0 / 0
02.06.2006, 12:35
    #33768402
Victor Metelitsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
Пресловутый SUSPEND - он ведь не из SQL-92?
...
Рейтинг: 0 / 0
02.06.2006, 12:35
    #33768403
ппм
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
да что там не понять - воплощение и поддержка независимого от конкретной базы приложения делает его одинаково плохо работающим на всех базах...
то есть - миграция == полная задница, если только речь не идет о полной переделки....
IMHO
...
Рейтинг: 0 / 0
21.06.2006, 19:07
    #33806818
ValPot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
Насчет SQL-92 в процедурах и функциях действительно ляпнул не подумав.

Начал пробовать проблему во "внешних" запросах.

Беру запрос -
Код: plaintext
1.
2.
insert into t2 ( p1 ) 
   select p1 from  table( func(param) ) as T

- получаю - 20267N причина 2

Переписываю -

Код: plaintext
1.
2.
     with WT as (select p1 from  table( func(param) ) as T )   
        select p1 from WT

- проходит, а нужный мне INSERT

Код: plaintext
1.
2.
3.
4.
     with WT as (select p1 from  table( func(param) ) as T )   
       insert into t2 ( p1 )  
        select p1 from WT



- не проходит по синтаксису. Значит ли это, что WITH работает только с последующим SELECT, а я снова попал на невозможность конвертации одного исходного запроса в один целевой?
...
Рейтинг: 0 / 0
21.06.2006, 21:09
    #33807045
Victor Metelitsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL20267N в функции и далее
Тогда уж
Код: plaintext
1.
2.
insert into t2 ( p1 )
  with WT as (select p1 from  table( func(param) ) as T )           
  select p1 from WT
...
Рейтинг: 0 / 0
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / SQL20267N в функции и далее / 25 сообщений из 30, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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