powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Informix [игнор отключен] [закрыт для гостей] / Dynamic SQL, проблема с курсором
24 сообщений из 24, страница 1 из 1
Dynamic SQL, проблема с курсором
    #36577884
Fet Frumos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нужно выбрать данные из нескольких баз. Решил использовать Dynamic SQL в хранимой процедуре. D Столкнулся с следующей проблемой, часть кода ХП
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
foreach
  select id_val  into i_val
  from  mytable 
    let  i1, i2, i3 =  0 , 0 , 0 ;
    let sql ="execute procedure  "||  alias||"myspl("||i_val||"); ";
    PREPARE tmp  FROM sql;
    DECLARE cur cursor FOR tmp;
    OPEN cur;
    FETCH  cur INTO i_i1, i_i2, i_i3;
    CLOSE cur;
    FREE tmp;
    FREE cur;
    trace 'end value='||i_i1||'  '||i_i2||'  '||i_i3; 
    --дальше использую значения  i_i1, i_i2, i_i3
end foreach	
Проблем в том что значения i_i1, i_i2, i_i3(те что вижу в trace) одинаковы на протяжении всего цикла. Т.е. первое значение i_val подставляю в myspl она возвращает значения, в следующем шаге новое значение i_val а на выходе те же значения. Очень похоже что я неправильно использую курсор. Подскажите в чем может быть ошибка? (alias - алиас BDE)
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36578016
Ikir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fet Frumos,

Во-первых, поставить в трейс i_val, чтоб убедиться , что оно разное.
Во-вторых, не видно, где вы в цикле меняете alias, то есть вызываете одну и ту же процедуру.
В-третьих, поставить в трейс alias, и показать процедуру myspl для каждого alias.
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36578083
Fet Frumos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
автор
Во-первых, поставить в трейс i_val, чтоб убедиться , что оно разное.
Во-вторых, не видно, где вы в цикле меняете alias, то есть вызываете одну и ту же процедуру.
В-третьих, поставить в трейс alias, и показать процедуру myspl для каждого alias.

1. i_val трейсил оно разное
ставил TRACE после
Код: plaintext
let sql ="execute procedure  "||  alias||"myspl("||i_val||"); ";
входные значения меняются
2,3 alias передаю как входной параметр в процедуру, на время отладки использую один алиас прописанный в переменной.
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36578861
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fet Frumos, лучше бы полный "работоспособный" текст для теста привёл....

Штатный dynamic sql в informix ещё новый - вряд ли кто-то активно польз[уется/овался].

"Всё приходится делать самому..." :)
Привожу пример для остальных, на котором ощутимо видна проблема.
По крайне мере у меня на 11.50FC6TL.

Код: 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.
create temp table tmp_table1(id_val INT) lock mode row;
insert into tmp_table1 values( 1 );                        
insert into tmp_table1 values( 2 );
insert into tmp_table1 values( 3 );

create procedure tmp_pair(
  i int
) returning
   int
 , int
 ;

  return i, i;
 
end procedure; 

execute procedure tmp_pair( 2 );
execute procedure tmp_pair( 3 );
 
create procedure tmp_test_dsql(
) returning
    int
  , int
  ;

  define i_val int;
  define i_i1, i_i2 int;
  define s_sql varchar( 120 );
  foreach
    select id_val into i_val
      from tmp_table1 
         order by  1  desc

    let  i_i1, i_i2 =  0 , 0 ;
    let s_sql ="execute procedure tmp_pair("||i_val||"); ";
    PREPARE tmp FROM s_sql;
    DECLARE cur cursor FOR tmp;
    OPEN cur;
    FETCH  cur INTO i_i1, i_i2;
    CLOSE cur;
    FREE tmp;
    FREE cur;
    return i_i1, i_i2 
      with resume; 
  end foreach	
end procedure;

-- вот здесь видна проблема
execute procedure tmp_test_dsql();
-- возвращается 3 записи и все с одинаковыми полями = 3...

-- чистим за собой
drop procedure tmp_test_dsql();
drop procedure tmp_pair(int);
drop table tmp_table1;
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36578873
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На нижеприведённом варианте ХП для того же теста видно что собака где-то с переподготовкой cur2.
Вполне может быть багом - или вскоре оказаться "недооформленной фичей" :)

Код: 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.
create procedure tmp_test_dsql(
) returning
    int
  , int
  ;

  define i_val int;
  define i_i1, i_i2 int;
  define s_sql varchar( 120 );
  foreach
    select id_val into i_val
      from tmp_table1
        order by  1  desc 
 
    let  i_i1, i_i2 =  0 , 0 ;
    let s_sql ="execute procedure tmp_pair("||i_val||"); ";
    if i_val =  3  then
      PREPARE tmp FROM s_sql;
      DECLARE cur cursor FOR tmp;
      OPEN cur;
      FETCH cur INTO i_i1, i_i2;
      CLOSE cur;
      FREE tmp;
      FREE cur;
    else
      PREPARE tmp2 FROM s_sql;
      DECLARE cur2 cursor FOR tmp2;
      OPEN cur2;
      FETCH  cur2 INTO i_i1, i_i2;
      CLOSE cur2;
      FREE tmp2;
      FREE cur2;
    end if
    return i_i1, i_i2 
      with resume; 
  end foreach	
end procedure;
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36578892
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С одной стороны:
RTFM Resources allocated to the prepared statement can be released later using the FREE statement.
С другой:
RTFMA statement identifier can represent only one SQL statement or (in ESQL/C) one semicolon-separated list of SQL statements at a time .

A new PREPARE statement can specify an existing statement identifier if you want to bind the identifier to a different SQL statement text.

Т.е. исходя из доки тестовый пример выглядит корректным.
Похоже на баг.
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36578895
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ОФФ: 1313 сообщений. Жду бана :)
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36578914
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
АнатоЛойОФФ: 1313 сообщений. Жду бана :)
И подсказывают, что в ветке Informix с утра было 666 сообщений :)
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36578929
vasilis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
АнатоЛойОФФ: 1313 сообщений. Жду бана :)
Ну, этим сообщением ты всю магию цифр и сломал (уже стало 1314).
Но если есть большое желание могу профилактический бан выдать на денек - просто никого раньше не банил, аж руки чешутся :))
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36579031
Ikir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fet FrumosНужно выбрать данные из нескольких баз. Решил использовать Dynamic SQL в хранимой процедуре. D Столкнулся с следующей проблемой, часть кода ХП
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
foreach
  select id_val  into i_val
  from  mytable 
    let  i1, i2, i3 =  0 , 0 , 0 ;
    let sql ="execute procedure  "||  alias||"myspl("||i_val||"); ";
    PREPARE tmp  FROM sql;
    DECLARE cur cursor FOR tmp;
    OPEN cur;
    FETCH  cur INTO i_i1, i_i2, i_i3;
    CLOSE cur;
    FREE tmp;
    FREE cur;
    trace 'end value='||i_i1||'  '||i_i2||'  '||i_i3; 
    --дальше использую значения  i_i1, i_i2, i_i3
end foreach	
Проблем в том что значения i_i1, i_i2, i_i3(те что вижу в trace) одинаковы на протяжении всего цикла. Т.е. первое значение i_val подставляю в myspl она возвращает значения, в следующем шаге новое значение i_val а на выходе те же значения. Очень похоже что я неправильно использую курсор. Подскажите в чем может быть ошибка? (alias - алиас BDE)

Надо модифицировать процедуру:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
    let sql ="execute procedure  "||  alias||"myspl( ? ); ";
    PREPARE tmp  FROM sql;
foreach
  select id_val  into i_val
  from  mytable 
    let  i1, i2, i3 =  0 , 0 , 0 ;
    DECLARE cur cursor FOR tmp;
    OPEN cur using i_val;
    FETCH  cur INTO i_i1, i_i2, i_i3;
    CLOSE cur;
    FREE cur;
    trace 'end value='||i_i1||'  '||i_i2||'  '||i_i3; 
    --дальше использую значения  i_i1, i_i2, i_i3
end foreach	
    FREE tmp;

...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36579143
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ikir
Надо модифицировать процедуру:
...
Код: plaintext
1.
2.
3.
...
    let sql ="execute procedure  "||  alias||"myspl( ? ); ";
...

Если бы не переменная "alias||", присутствующая перед именем ХП, было бы совсем хорошо...
Но есть подозрение, что alias либо префикс, изменяющий собственно имя ХП, которую вызываем, либо ещё веселее - имя другой БД [а то и сервера]. А по тесту видно, что смена строки с выражением не приводит к "перекомпиляции" запроса. Итого: если alias - это параметр тестируемой ХП, то должно заработать, а если alias меняется внутри ХП (есть внешний цикл - скорее всего не заработает)...
ТС, ау?! :)
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36579214
Fet Frumos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Большое спасибо, вариант предложенный Ikir работает . Алиас - имя другой базы, пока что на одном сервере(на время тестов), а так планирую на разных. Алиас передается в ХП входным параметром. О результате экспериментов напишу :)
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36585176
может быть, поможет. :-)

... statement text that [SQL statement for Dynamic Cursor in an SPL Routine] specifies can include question mark (? ) symbols as placeholders for values that the user supplies at runtime, but these placeholders in the PREPARE statement can represent only data values, not SQL
identifiers.

(c) http://publibfp.dhe.ibm.com/epubs/pdf/c2377515.pdf

Насколько я понимаю, эта проблема была с данными,
название сервера или имя хранимки ("alias") - это идентификтор.
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36586502
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Лена Владыкина, не совсем так. К "знаку вопроса" пришли позже: как к обходному решению выявленной проблемы. А выявленная проблема звучит так: "Несмотря на возможность (декларированную в документации) повторно использовать одну и ту же переменную внутри ХП для выполнения разных SQL-утверждений, в действительности смена в цикле SQL утверждения не приводит к реальному выполнению разных SQL-утверждений, а выполняется всё время то, которое было подготовлено первым. К счастью, механизм параметров оказался работающим - что и устроило топик-стартера".
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36588589
АнатоЛой, я понимаю, что ты имеешь ввиду... Но вопрос, мне кажется, в другом.. Дело в том, что в документации написано только то, что переменная для SQL выражения должна быть типа character. А можно ли ее формировать приведением типов или нет, видимо, решается самостоятельно, исходя из богатого опыта формирования значений таких переменных. И это, по-моему, вполне нормально. На самом же деле, немного ниже того места, что ты цитировал из документации, есть целый список условий по формированию текста SQL выражения, включая это:

In some statements, parameters are unknown when the statement is prepared
because a different value can be inserted each time the statement is executed. In
these statements, you can use a question-mark ( ? ) placeholder where a parameter
must be supplied when the statement is executed.


Собственно, вопрос тогда вот в чем.. Насколько это этично, давать программистам возможность пользоваться динамическим SQL, но при этом предполагать возможность, что они будут спотыкаться?
Как по мне, ну и ничего особо страшного в этом нет:-)

p.s. Толик, уточняю на всякий случай, что я остаюсь преданной поклоннице всех твоих талантов, с которыми знакома:-)))
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36589331
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Лена ВладыкинаА можно ли ее формировать приведением типов или нет, видимо, решается самостоятельно, исходя из богатого опыта формирования значений таких переменных.
...

Именно с формированием строки никаких проблем и не возникало...
Ещё раз обращаю внимание на упомянутую цитату:

RTFMA new PREPARE statement can specify an existing statement identifier if you want to bind the identifier to a different SQL statement text.

Теперь я выделил только одно слово, хотя важным является всё предложение.
Fet Frumos (не перевелись богатыри в земле русской, пусть даже и болгарские! :) ),
как раз и попробовал на разных итерациях цикла с помощью повторного PREPARE связывать (bind) один и тот же идентификатор (identifier: "tmp") с разными SQL утверждениями в строке "sql" (different SQL statement text).
Тяжело предположить, что "new" из документации предполагает только несколько утверждений PREPARE, и не предполагает использование одного и того же утверждения с PREPARE на разных итерациях цикла .

Лена Владыкина
...you can use a question-mark ( ? ) placeholder where a parameter
must be supplied when the statement is executed.


"can use" - не "must use"...

Лена Владыкина
Насколько это этично, давать программистам возможность пользоваться динамическим SQL, но при этом предполагать возможность, что они будут спотыкаться?
Как по мне, ну и ничего особо страшного в этом нет:-)


Никто и не спорит, фича новая, разработчик же должен был споткнуться :) Чуть-чуть обидно, что это оказался не разработчик из IBM :).

Лена Владыкина
p.s. Толик, .... я остаюсь ... поклонницей ... :-)))
Блин, где здесь кнопка с красными щёчками?!
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36590396
Фотография Daugava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще-то, персонажа румынских народных сказок Фет Фрумоса можно назвать молдаванином. С натяжкой даже украинцем (есть на Буковине и украинские сказки о нем). Ну никак не болгарин :).
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36590779
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Daugava и Fet Frumos, я каюсь за столь раннее обретение склероза .
Я, правда, в районе обеда даже вспомнил про эту разницу - но мини-командировка по Киеву не дала мне вовремя извиниться.

В общем, оговорка получилась прям по фильму:

к/ф Брат- Киркоров мне не нравится - весь слащавый, напудренный как баба, одним словом - румын.
- Так ведь он же болгарин!
- Да?! А какая разница? ..


П.С.:
Съездить на майские праздники в Европу и посмотреть в чём разнмица, что-ли?! :)
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36617558
Fet Frumos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Был в отпуске. Дальнейший результат экспериментов неутешителен, на одном сервере ХП работает, а если ХП запускаю на одном сервере, а обращаюсь к базе расположенной на другом то процедура вываливается с ошибкой "-9791 SQL error: User Defined Routine (importdb_t2) execution failed." :(. Видимо придется отказаться от использования в моей задаче Dynamic SQL .
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36617595
Fet Frumos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кстати, Fet Frumos - древнеукраиский богатырь (согласно исследований украинских историков) .
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36617674
Fet Frumos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Дополнение: ошибка появляется как раза при выполнении "проблемного участка"
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
 let sql ="execute procedure  "||  alias||"myspl( ? ); ";
    PREPARE tmp  FROM sql;
foreach
  select id_val  into i_val
  from  mytable 
    let  i1, i2, i3 =  0 , 0 , 0 ;
    DECLARE cur cursor FOR tmp;
    OPEN cur using i_val;
    FETCH  cur INTO i_i1, i_i2, i_i3;
    CLOSE cur;
    FREE cur;

если его закоментить то работает ок
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36617895
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fet FrumosДополнение: ошибка появляется как раза при выполнении "проблемного участка"
...
если его закоментить то работает ок

весь отображённый участок - проблемный?
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36617912
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ОФ:
Fet FrumosКстати, Fet Frumos - древнеукраиский богатырь (согласно исследований украинских историков) .

Он же - молдавский :). Старые добрые сказки...

Шварц - богатырь предыдущего поколения, и Фредди - его ужас :) (хотя похоже, и нынешнему достанется :)
...
Рейтинг: 0 / 0
Dynamic SQL, проблема с курсором
    #36622584
Fet Frumos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ошибка вываливается при вызове ХП с параметром. Получаю ошибки
Код: plaintext
1.
2.
3.
4.
5.
6.
 05 / 07 / 10   11 : 58 : 59   Assert Failed: Exception Caught. Type: MT_EX_OS, Context: mem
 05 / 07 / 10   11 : 58 : 59   IBM Informix Dynamic Server Version  11 . 50 .FC6TL
 05 / 07 / 10   11 : 58 : 59    Who: Session( 9356 , my@my,  4040 , 0x98f87b60)
                Thread( 60191 , sqlexec, 98f49918,  1 )
                File: mtex.c Line:  417 
 05 / 07 / 10   11 : 58 : 59    Action: Please notify IBM Informix Technical Support.
Код: plaintext
1.
2.
 05 / 07 / 10   12 : 05 : 12   (- 9791 ): ERROR: Routine execution trap -- procname=<myspl> procid=1123
    reason: mem
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / Informix [игнор отключен] [закрыт для гостей] / Dynamic SQL, проблема с курсором
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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