Хранимая процедура работает правильно только иногда - PullRequest
0 голосов
/ 27 февраля 2020

Моя проблема: у меня есть хранимая процедура, которая только иногда запускается правильно, иногда не запускается вообще, а иногда частично (некоторые строки, которые вставляются в таблицу, не все). Я использую lazarus 2.0.6 на 64-битной Win10 и TODBCConnection для подключения к SQL Server 2012.

Сама хранимая процедура правильная, в SQL Server Management Studio она работает без проблем. Хранимая процедура записывает записи в 4 разные таблицы; в зависимости от параметров примерно 1-400 записей на таблицу.

Код:

con:TODBCConnection;
tra:TSQLTransaction;
qry:TSQLQuery;

con:=TODBCConnection.Create(nil);
tra:=TSQLTransaction.Create(nil);
qry:=TSQLQuery.Create(nil);

tra.DataBase:=con;
qry.DataBase:=con;
qry.Transaction:=tra;

con.Params.Clear;
con.Params.Add('DRIVER=SQL Server');
con.Params.Add('SERVER=xxxxx');
con.Params.Add('DATABASE='+DATENBANK_NAME);
con.Params.Add('Trusted_Connection=Yes');
con.Params.Add('AUTOCOMMIT=1');
con.Open; 

// call the procedure
sql:='EXEC dm.createStorage2 @St_Geraet='Q', @St_Bezeichnung='Q-Freezer -80', @St_Temperatur=-80, @St_Raum='Keller', @St_Gebaeude='ABC', 
@St_AnzFaecher=2, @St_AnzTuermeProFach=5, @St_MoeglicheSchubladenkombinationenProTurm='4,3', @St_MoeglicheBoxenkombinationenProSchublade='3,4', 
@St_MoeglicheBoxKapazitaeten='16,25,100', @schubladenProTurm=4, @boxenProSchublade=3, @boxkapazitaet=16;';

qry.SQL.Text:=sql;
qry.ExecSQL;

// alternatively, this will also not work:
// con.ExecuteDirect(sql);

con.Close();
qry.Free;
tra.Free;
con.Free;

Если я установлю точку останова на qry.ExecSQL; и перешагну через нее - это сработает?!

Кажется, он не ждет, пока qry.ExecSQL; завершит sh, и сразу же освобождает ресурсы. Что я могу сделать, чтобы заставить код ждать, пока qry.ExecSQL; не закончится?

Редактировать: похоже, проблема в том, что qry.ExecSQL; работает асинхронно, а не синхронно, как и должно быть. Как я могу сказать, что этот вызов выполняется синхронно?

Заранее спасибо.

1 Ответ

0 голосов
/ 28 февраля 2020

разобрались: это ошибка в sqldb.pas, в сочетании с odb c он не может определить, когда закончена хранимая процедура. поэтому программа немедленно переходит к следующей команде, которая в моем случае была освобождением экземпляра базы данных, в результате чего команда sql была прервана. теперь используется библиотека "zeos" (https://zeoslib.sourceforge.io), и она работает как шарм.

uses
Classes, SysUtils, ZConnection, ZDataset;

...

con:=TZConnection.Create(nil);
qry:=TZQuery.Create(nil);

qry.Connection:=con;

con.Protocol:='ado';
con.Database:='DRIVER=SQL Server;Trusted_Connection=Yes;SERVER=xxxx;DATABASE='+DATENBANK_NAME;
con.Connected:=true;

остальное идентично старому коду, с одним исключением: con.close(); становится con.connected:=false;

...