Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > БД в Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.05.2009, 20:27   #1
vovk
!=
Участник клуба
 
Аватар для vovk
 
Регистрация: 08.09.2008
Сообщений: 1,751
По умолчанию Firebird FibPlus pFibStoredproc

Firebird 2.1, Delphi 2007, FibPlus 6.9.6
Учусь работать с Firebird, попробовал тут создать хранимую процедуру для добавления записи
Код:
SET TERM ^ ;

RECREATE PROCEDURE PR_ADD_SB_REC (
 SM_NAME  VARCHAR(5),
 DESCRIPT VARCHAR(50))
RETURNS (
 MESS     VARCHAR(31))
AS 
BEGIN
IF (NOT EXISTS(SELECT ID FROM SB_PLAN WHERE SMALL_NAME=:SM_NAME))
THEN
BEGIN
INSERT INTO SB_PLAN (SMALL_NAME, DESCRIPTION) VALUES (:SM_NAME,:DESCRIPT); 
MESS = 'Запись добавлена';
SUSPEND;  
END ELSE
MESS = 'Запись с таким именем уже есть';
END^

SET TERM ; ^
потом в приложении пытаюсь воспользоватся с помощью TpFibStoredproc
Код:
try
 DM_MAIN.FTrsn_update_main.StartTransaction;
  pFIBStoredProc1.ParamByName('SM_NAME').AsString:=edit1.Text;
  pFIBStoredProc1.ParamByName('DESCRIPT').AsString:=edit2.Text;
  pFIBStoredProc1.ExecProc;
  DM_MAIN.FTrsn_update_main.Commit;
 Label1.Caption:= pFIBStoredProc1.Fields[0].AsString;
 
	except
   DM_MAIN.FTrsn_update_main.Rollback;
  Label1.Caption:='Ошибка при добавлении записи';
	 end;
В общемто работает.. так для эксперемента попробовал передать в параметры текст побольше чем переменные в процедуре, получил исключение.. ну того вроде и ожидал. Потом меняю текст на нормальный а процедура не выполняется вылетает с такой ошибкой.
sql error code=-804
sqlda missing or incorrect number/type of vadiables

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

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

Последний раз редактировалось vovk; 26.05.2009 в 06:50.
vovk вне форума Ответить с цитированием
Старый 25.05.2009, 22:43   #2
soleil@mmc
SQL-коддинг
Участник клуба
 
Регистрация: 16.01.2009
Сообщений: 1,192
По умолчанию

бьюсь об заклад, что при таком написании процедуры
Код:
SET TERM ^ ;

RECREATE PROCEDURE PR_ADD_SB_REC (
 SM_NAME  VARCHAR(5),
 DESCRIPT VARCHAR(50))
RETURNS (
 MESS     VARCHAR(31))
AS 
BEGIN
IF (NOT EXISTS(SELECT ID FROM SB_PLAN WHERE SMALL_NAME=:SM_NAME))
THEN
BEGIN
INSERT INTO SB_PLAN (SMALL_NAME, DESCRIPTION) VALUES (:SM_NAME,:DESCRIPT); 
MESS = 'Запись добавлена';
SUSPEND;  
END ELSE
MESS = 'Запись с таким именем уже есть';
END^

SET TERM ; ^
ты не получишь сообщения 'Запись с таким именем уже есть'

Цитата:
Сообщение от vovk Посмотреть сообщение
А да и ещё вопрос в догонку, возможно ли в хранимую процедуру передать как параметр имя таблицы.
возможно
но собсна само выполнение селекта нужно будет писать через execute statement (аналог execute immediate в оракле, если такой есть в файрберде)
soleil@mmc вне форума Ответить с цитированием
Старый 26.05.2009, 04:37   #3
vovk
!=
Участник клуба
 
Аватар для vovk
 
Регистрация: 08.09.2008
Сообщений: 1,751
По умолчанию

Цитата:
бьюсь об заклад, что при таком написании процедуры
так что ты ставил то со своей стороны?
Тут ты не прав я же говорю всё работает. Постановку условия взял из книги Хелен Борри "Firebird Руководство разрабртчика баз данных" единственно нот добавил там
Код:
IF (EXISTS(....)) THEN..
и вообще это моя 2-я хранимая процедура, (поэтому вряд ли она идеально составлена) первая выглядит так
Код:
SET TERM ^ ;

RECREATE PROCEDURE PROC1
RETURNS (
 PAR1 VARCHAR(30))
AS 
BEGIN
par1 = current_user || '  Role' || current_role ;  
suspend;
END^

SET TERM ; ^



Цитата:
но собсна само выполнение селекта нужно будет писать через execute statement
Нашол про execute statement почитал, испугался, передумал В общем для чего хотел использовать лучше по другому сделать. Кому интерестно про execute statement читал тут


Всё вызвал процедуру так
Код:
pFIBStoredProc1.ExecProcedure('PR_ADD_SB_REC',[edit1.Text,edit2.Text]);
теперь работает как ожидалось

ЗЫ спасибо за обсуждение

Последний раз редактировалось vovk; 26.05.2009 в 14:00. Причина: работает
vovk вне форума Ответить с цитированием
Старый 26.05.2009, 15:49   #4
soleil@mmc
SQL-коддинг
Участник клуба
 
Регистрация: 16.01.2009
Сообщений: 1,192
По умолчанию

Цитата:
Сообщение от vovk Посмотреть сообщение
так что ты ставил то со своей стороны?
Тут ты не прав я же говорю всё работает.
кроме чтения правильных книжек еще нужно понимать, что делают операторы
например здесь
Код:
IF (NOT EXISTS(SELECT ID FROM SB_PLAN WHERE SMALL_NAME=:SM_NAME))
THEN
BEGIN
  INSERT INTO SB_PLAN 
  (SMALL_NAME, DESCRIPTION) 
   VALUES (:SM_NAME,:DESCRIPT); 
   
  MESS = 'Запись добавлена';
  SUSPEND;  
END 
ELSE
  MESS = 'Запись с таким именем уже есть';
я разбивочку по коду сделал, а то не читалось
если условие выполнится, то все пучком, а вот если нет, то и мессагу ты не получишь - потому что там нет SUSPEND;

в твоем случае проще писать так
Код:
IF (NOT EXISTS(SELECT ID FROM SB_PLAN WHERE SMALL_NAME=:SM_NAME))
THEN
BEGIN
  INSERT INTO SB_PLAN 
  (SMALL_NAME, DESCRIPTION) 
   VALUES (:SM_NAME,:DESCRIPT); 
   
  MESS = 'Запись добавлена';  
END 
ELSE
  MESS = 'Запись с таким именем уже есть';

SUSPEND;
soleil@mmc вне форума Ответить с цитированием
Старый 26.05.2009, 16:37   #5
vovk
!=
Участник клуба
 
Аватар для vovk
 
Регистрация: 08.09.2008
Сообщений: 1,751
По умолчанию

Цитата:
Сообщение от soleil@mmc Посмотреть сообщение
кроме чтения правильных книжек еще нужно понимать, что делают операторы
например здесь
Я не претендую на абсолютное знание, да и просто на хорошое знание этой темы тоже как бы не претендую. Но у меня в зависимости от параметров приходило и 1 и второе сообщение.

Ради интереса сделал даже так
Код:
SET TERM ^ ;

RECREATE PROCEDURE PR_ADD_SB_REC (
 SM_NAME  VARCHAR(5),
 DESCRIPT VARCHAR(50))
RETURNS (
 MESS     VARCHAR(31))
AS 
BEGIN
IF (NOT EXISTS(SELECT ID FROM SB_PLAN WHERE SMALL_NAME=:SM_NAME))
THEN
BEGIN
/*INSERT INTO SB_PLAN (SMALL_NAME, DESCRIPTION) VALUES (:SM_NAME,:DESCRIPT); */
MESS = 'Запись добавлена';
/*SUSPEND; */ 
END 
ELSE
MESS = 'Запись с таким именем уже есть';
END^

SET TERM ; ^
и в таком виде тоже выдаёт и то и другое значение в зависимости от параметров

пока всё что нашол про Suspend в книге
Цитата:
В выполняемых процедурах SUSPEND имеет точно такойже эффект как и END
я правда ещё не всё прочитал



Сделал как в первоначальном варианте, только без SUSPEND, хмм работает,
переместил SUSPEND до
Код:
MESS = 'Запись добавлена';
запись добавляется сообщение не приходит, мне кажется я вообще зря его поставил это же выполняемая процедура.
Обьясните пожалуйста поподробнее про действие Suspend в процедурах выбора. Если не трудно конечно..

Кажется понял он добавляет строку в буфер строк, то есть нужен только там где многострочный вывод. Я прав?

Нее не только многострочный.. везде где open, а не exec нужен SUSPEND вроде так.
поэксперементировал тут..

Последний раз редактировалось vovk; 26.05.2009 в 17:34.
vovk вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
FireBird Д'якон БД в Delphi 2 04.12.2008 11:15
FireBird 1.5.4 Nikola__ БД в Delphi 2 17.11.2008 14:42
FibPlus v6.45 Timon3 Компоненты Delphi 3 02.06.2008 01:55
FIBPlus Trech БД в Delphi 2 22.05.2008 12:19