Подскажите пожалуйста, что это за ошибка: message length error (encountered 0, expected 32)
возникает при вызове программно хранимой процедуры: execute procedure name(param);
при вызове хранимой процедуры в ручную, через isql все работает.
Код БД и хранимой процедуры:
CREATE DATABASE "test.gdb" user 'SYSDBA' password 'masterkey';
CREATE TABLE title
(
id INTEGER NOT NULL,
name VARCHAR(20) NOT NULL,
PRIMARY KEY (id)
);
INSERT INTO title VALUES ( 1, 'qqqqq');
INSERT INTO title VALUES ( 2, 'wwwww');
INSERT INTO title VALUES ( 3, 'eeeee');
INSERT INTO title VALUES ( 4, 'rrrrr');
INSERT INTO title VALUES ( 5, 'ttttt');
SET TERM !! ;
CREATE PROCEDURE sp (param INTEGER)
RETURNS (param2 INTEGER, param3 VARCHAR(20))
AS
DECLARE VARIABLE n INTEGER;
DECLARE VARIABLE ret INTEGER;
BEGIN
ret = 5;
FOR SELECT id,name FROM title WHERE id =: param INTO :n,:param3
DO
ret = ret + n;
param2 = ret;
END !!
exit !!
SET TERM ; !!
Здравствуйте, Hiden, Вы писали:
H>Здравствуйте, vvu, Вы писали:
vvu>>Здравствуйте, Hiden, Вы писали:
H>>>Здравствуйте, Tonal-, Вы писали:
vvu>>А где в ХП SUSPEND
H>так если я вызываю хранимую процедуру вручную, при помощи isql то она выполняется H>там точно обязательно писать SUSPEND?
а иначе она ничего не вернет . suspend не нужен только, если у тебя будет процедура действия (нет RETURNS). А у тебя процедура выбора.
Здравствуйте, vvu, Вы писали:
vvu>Здравствуйте, Hiden, Вы писали:
H>>Здравствуйте, vvu, Вы писали:
vvu>>>Здравствуйте, Hiden, Вы писали:
H>>>>Здравствуйте, Tonal-, Вы писали:
vvu>>>А где в ХП SUSPEND
H>>так если я вызываю хранимую процедуру вручную, при помощи isql то она выполняется H>>там точно обязательно писать SUSPEND?
vvu>а иначе она ничего не вернет . suspend не нужен только, если у тебя будет процедура действия (нет RETURNS). А у тебя процедура выбора.
Написал вот так, но ничего не изменилось
SET TERM !! ;
CREATE PROCEDURE sp (param INTEGER)
RETURNS (param2 INTEGER, param3 VARCHAR(20))
AS
DECLARE VARIABLE n INTEGER;
DECLARE VARIABLE ret INTEGER;
BEGIN
ret = 5;
FOR SELECT id,name FROM title WHERE id =: param INTO :n,:param3
DO
ret = ret + n;
param2 = ret;
SUSPEND;
END !!
exit !!
SET TERM ; !!
Здравствуйте, Hiden, Вы писали:
H>Написал вот так, но ничего не изменилось
Используй, во-первых, тэги форматирования. Так будет проще понять, чего ты хочешь. А во-вторых, вот так работает. Имена таблиц, переменных подствь свои.
create procedure f_cross_bank_s
returns (
id integer,
id_firm integer,
id_bank integer)
as
begin
for select id,
id_firm,
id_bank
from f_cross_bank
into :id,
:id_firm,
:id_bank
do
begin
suspend;
end
end
Здравствуйте, Hiden, Вы писали:
H>Здравствуйте, vvu, Вы писали:
vvu>>Здравствуйте, Hiden, Вы писали:
H>>>Здравствуйте, vvu, Вы писали:
vvu>>>>Здравствуйте, Hiden, Вы писали:
H>>>>>Здравствуйте, Tonal-, Вы писали:
vvu>>>>А где в ХП SUSPEND
H>>>так если я вызываю хранимую процедуру вручную, при помощи isql то она выполняется H>>>там точно обязательно писать SUSPEND?
vvu>>а иначе она ничего не вернет . suspend не нужен только, если у тебя будет процедура действия (нет RETURNS). А у тебя процедура выбора.
а ты бегин энд не пропустил. Должны быть вот тут:
H>Написал вот так, но ничего не изменилось H>SET TERM !! ; H>CREATE PROCEDURE sp (param INTEGER) H>RETURNS (param2 INTEGER, param3 VARCHAR(20)) H>AS H>DECLARE VARIABLE n INTEGER; H>DECLARE VARIABLE ret INTEGER; H>BEGIN H>ret = 5; H>FOR SELECT id,name FROM title WHERE id =: param INTO :n,:param3 H>DO
BEGIN H>ret = ret + n; H>param2 = ret; H>SUSPEND;
END; H>END !! H>exit !! H>SET TERM ; !!
[Sorry, skipped] H> Написал вот так, но ничего не изменилось H> SET TERM !! ; H> CREATE PROCEDURE sp (param INTEGER) H> RETURNS (param2 INTEGER, param3 VARCHAR(20)) H> AS H> DECLARE VARIABLE n INTEGER; H> DECLARE VARIABLE ret INTEGER; H> BEGIN H> ret = 5; H> FOR SELECT id,name FROM title WHERE id =: param INTO :n,:param3 H> DO
Тут нужен BEGIN H> ret = ret + n; H> param2 = ret; H> SUSPEND;
Тут нужен ещё один END H> END !! H> exit !!
^^^^^^^^^^^
Тут exit не нужен H> SET TERM ; !!
В своей программе замени вызов
EXECUTE PROCEDURE...
на
SELECT * FROM ...
Привет, Tonal-!
Вы пишешь 02 декабря 2006:
T> Разобрался. T> Тебе надо использовать isc_dsql_execute2 или isc_dsql_exec_immed2 — T> только они понимают выходные параметры.
Здравствуйте, Alex.Che, Вы писали:
AC>Привет, Tonal-! AC>Вы пишешь 02 декабря 2006:
T>> Разобрался. T>> Тебе надо использовать isc_dsql_execute2 или isc_dsql_exec_immed2 — T>> только они понимают выходные параметры.
AC>Но фетчить можно только из первой.
А зачем ему фетчить? У него процедура выбора, вызываемая через EXECUTE, стало быть данные вернуться в выходных параметрах.
[Sorry, skipped] AC>> Но фетчить можно только из первой. T> А зачем ему фетчить? У него процедура выбора, вызываемая через EXECUTE, T> стало быть данные вернуться в выходных параметрах.
Независимо от того, что он там изобретает, нужен ему фетч, или нет,
isc_dsql_execute2 универсальнее, гибче и удобнее.
Хотя бы уже тем, что аллокировав стейтмент, мы можем узнать
тип запроса, типы входных и выходных параметров и т.д. и .т.п.
Что в случае isc_dsql_execute_imed2 не представляется возможным.
Здравствуйте, Alex.Che, Вы писали: AC>isc_dsql_execute2 универсальнее, гибче и удобнее.
Ну я как бы с этим не спорю.
Просто привёл список доступных функций для решения его проблемы.
Ну а уж выбирать всяко ему.
Здравствуйте, Alex.Che, Вы писали:
AC>Привет, Hiden! AC>Вы пишешь 01 декабря 2006:
AC>[Sorry, skipped] H>> Написал вот так, но ничего не изменилось H>> SET TERM !! ; H>> CREATE PROCEDURE sp (param INTEGER) H>> RETURNS (param2 INTEGER, param3 VARCHAR(20)) H>> AS H>> DECLARE VARIABLE n INTEGER; H>> DECLARE VARIABLE ret INTEGER; H>> BEGIN H>> ret = 5; H>> FOR SELECT id,name FROM title WHERE id =: param INTO :n,:param3 H>> DO AC>Тут нужен BEGIN H>> ret = ret + n; H>> param2 = ret; H>> SUSPEND; AC>Тут нужен ещё один END H>> END !! H>> exit !! AC>^^^^^^^^^^^ AC>Тут exit не нужен H>> SET TERM ; !!
AC>В своей программе замени вызов AC>EXECUTE PROCEDURE... AC>на AC>SELECT * FROM ...
AC>-- AC>With best regards, Alex Cherednichenko.
Написал процедуру как вы и говорите, даже сделал ее еще проще:
SET TERM !! ;
CREATE PROCEDURE sp (param INTEGER)
RETURNS (param2 INTEGER, param3 VARCHAR(20))
AS
BEGIN
FOR SELECT id,name FROM title WHERE id =: param
INTO :param2,:param3
DO
BEGIN
SUSPEND;
END !!
END !!
exit !!
SET TERM ; !!
но теперь у меня уже выдается ошибка
Dinamic SQL Error
-SQL error code = -104
-Unexpected end of command
а если еще не писать exit !!. то будет следующая ошибка
Expected end of statement, encountered EOF
так как я создаю БД и ХП из makefile при помощи вызова isql, а exit !! прекращает вызов isql
Привет, Hiden!
Вы пишешь 04 декабря 2006:
H> а если еще не писать exit !!. то будет следующая ошибка H> Expected end of statement, encountered EOF H> так как я создаю БД и ХП из makefile при помощи вызова isql, а exit !! H> прекращает вызов isql
Здравствуйте, Tonal-, Вы писали:
T>Здравствуйте, Alex.Che, Вы писали: AC>>isc_dsql_execute2 универсальнее, гибче и удобнее. T>Ну я как бы с этим не спорю. T>Просто привёл список доступных функций для решения его проблемы. T>Ну а уж выбирать всяко ему.
Попробывал использовать isc_dsql_execute2, но результат тот же:
message length error (encountered 0, expected 32)
Привет, Hiden!
Вы пишешь 04 декабря 2006:
H> Попробывал использовать isc_dsql_execute2, но результат тот же: H> message length error (encountered 0, expected 32)
Да не в бобине у тебя дело. (С)
Похоже, у тебя сервер и клент разных версий.
Ищи "лишние" gds32.dll
У "нелишних" сверяй версии.
Здравствуйте, Alex.Che, Вы писали:
AC>Привет, Hiden! AC>Вы пишешь 04 декабря 2006:
H>> Попробывал использовать isc_dsql_execute2, но результат тот же: H>> message length error (encountered 0, expected 32)
AC>Да не в бобине у тебя дело. (С) AC>Похоже, у тебя сервер и клент разных версий. AC>Ищи "лишние" gds32.dll AC>У "нелишних" сверяй версии.
AC>-- AC>With best regards, Alex Cherednichenko.
А в Linux эта библиотека как называется? если так же (gds32.so) то где ее искать, а то что то поиск не может найти
Привет, Hiden!
Вы пишешь 04 декабря 2006:
AC>> Да не в бобине у тебя дело. (С) AC>> Похоже, у тебя сервер и клент разных версий. AC>> Ищи "лишние" gds32.dll AC>> У "нелишних" сверяй версии.
H> А в Linux эта библиотека как называется?
libgds.so — для InterBase, либо же libfbclient.so — для Firebird.
Здравствуйте, Alex.Che, Вы писали:
AC>Привет, Hiden! AC>Вы пишешь 04 декабря 2006:
AC>>> Да не в бобине у тебя дело. (С) AC>>> Похоже, у тебя сервер и клент разных версий. AC>>> Ищи "лишние" gds32.dll AC>>> У "нелишних" сверяй версии.
H>> А в Linux эта библиотека как называется?
AC>libgds.so — для InterBase, либо же libfbclient.so — для Firebird.
AC>-- AC>With best regards, Alex Cherednichenko.
Я нашел четыре библиотеки в home/user/ibc/libgds.so, lib/libgds.so, opt/interbase.prev.lnk/lib/libgds.so, usr/lib/libgds.so
Что теперь с ними делать? Как посмотреть в линуксе их версии и как я понимаю лишние надо удалить или заменить, а какие будут лишние???
Привет, Hiden!
Вы пишешь 04 декабря 2006:
H> Я нашел четыре библиотеки в home/user/ibc/libgds.so, lib/libgds.so, opt/interbase.prev.lnk/lib/libgds.so, usr/lib/libgds.so H> Что теперь с ними делать? Как посмотреть в линуксе их версии.
Тут я помочь не смогу. Я виндузятник, не юниксолог.
Здравствуйте, Hiden, Вы писали:
H>Я нашел четыре библиотеки в home/user/ibc/libgds.so, lib/libgds.so, opt/interbase.prev.lnk/lib/libgds.so, usr/lib/libgds.so H>Что теперь с ними делать? Как посмотреть в линуксе их версии и как я понимаю лишние надо удалить или заменить, а какие будут лишние???
1. Откуда запускается сервак?
2. То что ты нашел — файлы или линки на файлы?
Навскидку — скорее всего оно у тебя хватает либо home/user/ibc/libgds.so, либо lib/libgds.so, но скорее всего второе.
Если сумееш натравить strace на запуск сервака БД — увидиш точно.
[RSDN@Home][1.2.0][alpha][668]
[В доме без жильцов — известных насекомых не обрящешь. [К. Прутков]]
Здравствуйте, Hiden, Вы писали: H>Попробывал использовать isc_dsql_execute2, но результат тот же: H>message length error (encountered 0, expected 32)
Покажи код.
Ты точно задал куды выходные параметры покласть?
Соощение точно при вызове isc_dsql_execute2 вылетает?
Здравствуйте, Tonal-, Вы писали:
T>Здравствуйте, Hiden, Вы писали: H>>Попробывал использовать isc_dsql_execute2, но результат тот же: H>>message length error (encountered 0, expected 32) T>Покажи код. T>Ты точно задал куды выходные параметры покласть? T>Соощение точно при вызове isc_dsql_execute2 вылетает?
while ((fetch_stat = isc_dsql_fetch(status_vector, &stmt, 1, sqlda)) == 0)
{
id[9] = '\0';
name[49] = '\0';
printf("\nid: %s", id);
printf("\nname: %s\n", name);
}
....
если в str1 записывать select то все работает и в id и name записываются данные, а если там указать execute то возникает такая ошибка
может действительно все дело в несовпадении версий клиента и сервера
P.S. Открой доку по функции isc_dsql_execute2 и внимательно вчитайся в эти величественные строки:
XSQLDA* in_xsqlda
Pointer to an optional, previously allocated XSQLDA used for input; if input parameters are not supplied, set this value to NULL
XSQLDA* out_xsqlda
Pointer to an optional, previously allocated XSQLDA used for results of statement execution; if not required, set this value to NULL
T>P.S. Открой доку по функции isc_dsql_execute2 и внимательно вчитайся в эти величественные строки:
T>
T>XSQLDA* in_xsqlda
T>Pointer to an optional, previously allocated XSQLDA used for input;
T>if input parameters are not supplied, set this value to NULL
T>
T>XSQLDA* out_xsqlda
T>Pointer to an optional, previously allocated XSQLDA used for results of statement execution;
T>if not required, set this value to NULL
Сделал как Вы сказали, немного изменил код:
...
int emp_no = 3;
char str1[BUFLEN];
isc_tr_handle trans = NULL;
long status[50];
sprintf(str1, "execute procedure sp %d;",emp_no);