Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > Хранимая процедура в IB


Автор: SPrograMMer 17.7.2005, 19:29
Создаю инсталяшку для своей проги, прога заточена под InterBase, разные версии которого имеют разные форматы базы данных, поэтому создать чистый *.GDB файл у себя, а потом его просто копировать не подходит, т к используемая у клиента IB может быть другая и соответственно он (IB) может просто не понять структуры того файла, который ему подсовывают. Поэтому делаем так: имеется список SQL запросов, которые последовательно выполняет программы инсталятор. Таблицы (Create Table...), генераторы (Create Generator...), триггеры (Create Trigger..), определение внешних UDF функций (Declare External Function ...), выполняются прекрасно. Прекрасно выполняется и создание хранимой процедуры (Create Procedure...). Но! Для того все это добро "осталось" в базе данных я положительно подтверждаю транзакцию IBTransaction.Commit;, при этом происходит трабла:
Цитата

EIBInterBaseError: "invalid request BLR at offset 178 bad parameter number"

и соответственно все это добро (таблицы, триггеры,...) не сохраняются smile
Что за неверное число параметров?!

Ошибка не возникает если не создавать хранимку.
Что такое происходит и как с этим бороться. Т е как правильно создать и сохранить хранимую процедуру в создаваемой базе данных.

ЗЫ: если это имеет значение: хранимка довольно большая (~1500 символов), имеет входные параметры, ничего не возвращает (нет выходных параметров), нет локальных переменных.

ЗЗЫ: Delphi 2005 for Win32, InterBase 7.5

Автор: Alex 17.7.2005, 20:05
Так сказать практически ничего нельзя, нужно смотреть SQL, узнать чем ты хотя бы выполняешь SQL и т.д.
PS:
Пока напрашивается ответ "Ошибка в 17 строке"

Автор: SPrograMMer 17.7.2005, 22:33
Текст запроса создания процедуры синтаксически правилен, если его выполнить в IBConsole для этой БД - процедура создаётся, а вот в программе - нет....
запросы выполняются через компоненту IBSQL
Вот собственно текст хранимки:
Код

Create procedure CreateReport(Data1 DATE, Data2 DATE)
As
Begin
  Delete From ReportTable;
  Insert InTo ReportTable (IDNames,IDMeassure,KolIn,KolOut,AllSum)
    Select I.IDNames,I.IDMeassure, Sum(Distinct I.Kolvo) As Ik,
      Sum(Distinct O.Kolvo) As Ok,Sum(Distinct I.SumIs) As Isi
    From Inputing I,Outputing O
    Where (I.IDNames=O.IDNames) And (I.IDNakls In (
        Select ID From Nakls Where Data between :Data1 And :Data2)) And
      (O.IDNakls IN (Select ID From Nakls Where Data between :Data1 And :Data2))
    Group By I.IDNames, I.IDMeassure;
  Insert InTo ReportTable (IDNames,IDMeassure,KolIn,KolOut,AllSum)
    Select IDNames,IDMeassure, Sum(Distinct Kolvo) As Ik,
      0, Sum(Distinct SumIs) As Isi
    From Inputing
    Where (IDNames Not In (Select Distinct IDNames From Outputing)) And
      (IDNakls In (Select ID From Nakls Where Data between :Data1 And :Data2))
    Group By IDNames, IDMeassure;
  Insert InTo ReportTable (IDNames,IDMeassure,KolIn,KolOut,AllSum)
    Select IDNames,IDMeassure, 0, Sum(Distinct Kolvo) As Ok, 0
    From Outputing
    Where IDNames Not In (Select Distinct IDNames From Inputing) And
      (IDNakls In (Select ID From Nakls Where Data between :Data1 And :Data2))
    Group By IDNames, IDMeassure;
End

Сначала таблица очищается, потом в неё данные вствляются, три раза...

Автор: Alex 17.7.2005, 23:02
Ну, что тут можно сказать:
1. Если уж хотите пользоваться экспертами, то уж точно не IBConcole, т.к. любой грамотный эксперт скажет, что скрипт для создания процедуры выглядит приблизительно так:
Код

SET TERM ^ ;

CREATE PROCEDURE SORT_TREE_LAMP (
    PARENT_ID BIGINT)
RETURNS (
    ID BIGINT,
    PARENT BIGINT,
    NAME VARCHAR(10000),
    CCOUNT INTEGER,
    SORTINDEX INTEGER,
    IMAGEINDEX INTEGER,
    STATEINDEX INTEGER,
    NODE_LEVEL INTEGER,
    FULLPATH VARCHAR(32765))
AS
DECLARE VARIABLE TEST_PARENT BIGINT;
begin 
  for select ID, PARENT, NAME, CCOUNT, SORTINDEX, IMAGEINDEX, STATEINDEX, FULLPATH 
  from tree_LAMP
  where PARENT = :PARENT_ID 
  order by SORTINDEX 
  into :ID, :PARENT, :NAME , :CCOUNT, :SORTINDEX, :IMAGEINDEX, :STATEINDEX, :FULLPATH 
  do begin 
      NODE_LEVEL = 0; 
      TEST_PARENT = PARENT; 
      while (TEST_PARENT > 0) do begin 
         select tl.PARENT from tree_LAMP tl where tl.ID = :TEST_PARENT
         into :TEST_PARENT; 
         NODE_LEVEL = NODE_LEVEL + 1; 
      end 
      suspend; 
      if (CCOUNT <> 0) then begin 
         TEST_PARENT = ID; 
         for select ID, PARENT, NAME, CCOUNT, SORTINDEX, IMAGEINDEX, STATEINDEX, FULLPATH 
         from SORT_tree_LAMP(:TEST_PARENT)
         into :ID, :PARENT, :NAME, :CCOUNT, :SORTINDEX, :IMAGEINDEX, :STATEINDEX, :FULLPATH 
         do begin 
            NODE_LEVEL = 0; 
            TEST_PARENT = PARENT; 
            while (TEST_PARENT > 0) do begin 
               select tl.PARENT from tree_lamp tl where tl.ID = :TEST_PARENT
               into :TEST_PARENT; 
               NODE_LEVEL = NODE_LEVEL + 1; 
            end 
            suspend; 
         end 
      end 
  end 
end
^

SET TERM ; ^

2. FAQ читать нужно http://vingrad.ru/DELPHI-DLP-001854 smile

Автор: SPrograMMer 18.7.2005, 23:26
Цитата(Alex @ 17.7.2005, 23:02)
FAQ читать нужно http://vingrad.ru/DELPHI-DLP-001854 

ну что ты сразу не сказал?... smile Работает ParamCheck=False smile
Добавлено @ 23:32
Зы: номер 1 не пашет, так как ругается сразу на SET, да и нивозможно в IBX.SQL запихнуть более одного законченого выражения SQL.

Автор: Alex 19.7.2005, 08:07
Цитата(SPrograMMer @ 19.7.2005, 00:26)
Зы: номер 1 не пашет, так как ругается сразу на SET, да и нивозможно в IBX.SQL запихнуть более одного законченого выражения SQL.


SPrograMMer, кто же базу создает с помощью TSQL, базу все обычно создают с помощью скрипта.

Автор: SPrograMMer 21.7.2005, 00:53
Цитата(Alex @ 19.7.2005, 08:07)
кто же базу создает с помощью TSQL, базу все обычно создают с помощью скрипта.

ну.... век живи-век учись. И за это спасибо. smile
Год назад, например, для парадоксовской базы, я вобще писал что-то типа:
Код

with Table1 Do begin
  Active:=False;
  DatabaseName:='MyBase';
  TableType:=ttParadox;
  TableName:='MyTable';
  with FieldDefs Do begin
     with AddFieldDef Do Begin
     ....
     End;
     ...
  End;
  CreateTable;
end



smile smile smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)