Форум: "Базы";
Текущий архив: 2004.09.12;
Скачать: [xml.tar.bz2];
ВнизОшибки выполнения хранимых процедур MS SQL при запуске из Delphi Найти похожие ветки
← →
ANB (2004-08-18 12:21) [0]Уважаемые мастера. Помогите решить следующую задачу.
Мне нужно выполнить из клиента на Delphi пакет хранимых процедур.
В каждой процедуре происходит массовая обработка данных со вставкой их в различные таблицы.
При запуске процедуры из Delphi, если при обработке очередной записи происходит ошибка (например отвалился инсерт по констрейнту), то прекращается работа всей процедуры. А мне нужно только сохранить эту ошибку в лог и идти дальше.
При выполнении из Query Analyzer (exec MyProc) все так и работает - то есть вываливаются мессаги о всех ошибка - а процедура продолжает работать, пока не обработает все записи.
Как такое же можно сделать из Delphi ?
PS. Процедуры правке не подлежат и я видел живой пример на Visual C++ где все работает, но у меня нет исходников.
Я уже облазил все форумы, нашел как достать print и там же - что задача не решается, но ведь РЕШЕНА ?!
← →
Ega23 © (2004-08-18 12:31) [1]При выполнении из Query Analyzer (exec MyProc) все так и работает - то есть вываливаются мессаги о всех ошибка - а процедура продолжает работать, пока не обработает все записи.
Как это? На код этой процедуры можно взглянуть?
← →
Ega23 © (2004-08-18 12:32) [2]При выполнении из Query Analyzer (exec MyProc) все так и работает - то есть вываливаются мессаги о всех ошибка - а процедура продолжает работать, пока не обработает все записи.
Как это? На код этой процедуры можно взглянуть?
← →
KSergey © (2004-08-18 12:36) [3]Поверьте, процедура всегда продолжает работать до конца (так уж MS SQL устроен). Просто дельфи показывает только первую ошибку.
← →
ANB (2004-08-18 12:59) [4]Без проблем.
Примерно так:
create table _Test
(
ID int not null
)
go
create procedure _MyTest as
insert into _Test (ID) values (1) -- Отработает
insert into _Test (ID) values (null) -- Ошибка
insert into _Test (ID) values (null) -- Ошибка
insert into _Test (ID) values (null) -- Ошибка
insert into _Test (ID) values (null) -- Ошибка
insert into _Test (ID) values (null) -- Ошибка
insert into _Test (ID) values (null) -- Ошибка
insert into _Test (ID) values (2) -- Отработает
go
-- В Query Analyzer будет 6 ошибок.
-- Из под Delphi - заваливается на первом же инсерте
exec _MyTest
go
Общая проблема - вытащить ВСЕ сообщения MS SQL без прерывания работы программы. Это самый простой случай процедуры, сами они намного сложнее.
← →
ANB (2004-08-18 13:04) [5]И правда работает, но мне все равно надо все ошибки вытащить, а они пропадают.
← →
KSergey © (2004-08-18 13:11) [6]> [5] ANB (18.08.04 13:04)
> И правда работает, но мне все равно надо все ошибки вытащить,
> а они пропадают.
Было здесь обсуждение, вот что сохранилось
Но не проверял
Пример отлова Print от сервера: (GreenSunrise GreenSunrise@mail.ru)
Вот абсолютно рабочий, только что проверенный пример:
Запустите в Query Analyzer"е:
create table t1
(
col1 int,
col2 varchar(10)
)
go
create trigger ins_t1 on t1 for insert
as
begin
set nocount on
print "Message from trigger ins_t1"
raiserror ("Some error was occured", 16, 1)
print "Another message from trigger ins_t1"
end
go
А теперь тест на VBS (достаточно создать файл с расширением vbs, поместить туда следующий скрипт и запустить его):
on error resume next
Dim oConnect
Set oConnect = CreateObject("ADODB.Connection")
oConnect.Open "Provider=SQLOLEDB.1;Password=kuku01;Persist Security Info=True;User ID=sa;Initial Catalog=sql2;Data Source=LADY\INS1"
oConnect.Execute "insert into t1 (col1, col2) values (1, "a")"
For each Error in oConnect.Errors
MsgBox Error.Description
Next
Кто скажет, что это не работает, пусть первый бросит в меня камень.
Обсуждение:
print "Message from trigger ins_t1"
raiserror ("Some error was occured", 16, 1)
print "Another message from trigger ins_t1"
Хе а ты попробуй без средней строчки
--
Без средней тоже самое, только два сообщения вместо трех.
--
в дульфях у меня без raiserror 0 с ним 3
--
С Дельфями не работаю, так что в данном случае помочь не могу. Если борланд (или как там его теперь зовут) меняет поведение ADO, это имхо хреново. В простейшем скрипте, где чистое ADO, как видите, все нормально.
P.S. В триггере не забыли set nocount on поставить? Точно не забыли?
--
В делфях тоже работает без raiserror
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
Connection.Connected := True;
Connection.Execute("insert into t1 (col1, col2) values (1, ""a"")");
Connection.Errors.Refresh; //
for i := 0 to Connection.Errors.Count-1 do
ShowMessage( Connection.Errors.Item[i].Description );
Connection.Connected := false;
end;
--
все равно не пашет
может чтото в настройках не так...
--
CursorLocation:=clUseServer;
← →
clickmaker © (2004-08-18 13:14) [7]можно через out-параметр, например
create procedure _MyTest (@errors varchar(255) out)
as begin
declare @RetCode int
select @errors = ""
insert into _Test (ID) values (1)
select @RetCode = @@error
if @RetCode != 0 select @errors = @errors + "," + @RetCode
...
а дальше на клиенте этот список уже обрабатываешь
← →
ANB (2004-08-18 13:42) [8]Print и через Delphi + ADO (только не через компоненты, а через интерфейс) прекрасно качается. Проблема в обработке ошибок. Процедура действительно отрабатывает вся, но :
1. После первой же ошибки Delphi + ADO считает, что она завалилась. А эти поцедуры по 2-3 часа могут работать. И их нужно по очереди запускать.
2. Вытаскивается только первая ошибка.
Кстати, откопал прикол - если юзать TcsSQLQuery, то приезжает только последняя ошибка.
← →
ANB (2004-08-18 13:48) [9]Еще раз - процедуры я менять не могу - их большее 100 и у них сложная логика. Как говорится - Солнце всходит и заходит ? Каждый день ? Тогда лучше не трогай !
← →
ANB (2004-08-18 14:10) [10]Всем спасибо. На Delphi 7 прекрасно работает пример
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
Connection.Connected := True;
Connection.Execute("insert into t1 (col1, col2) values (1, ""a"")");
Connection.Errors.Refresh; //
for i := 0 to Connection.Errors.Count-1 do
ShowMessage( Connection.Errors.Item[i].Description );
Connection.Connected := false;
end;
Только чтобы не было лишних проблем пришлось добавить :
try
Connection.Execute("insert into t1 (col1, col2) values (1, ""a"")");
except
end;
← →
ANB (2004-08-18 14:11) [11]Все проблемы были в CursorLocation:=clUseServer; У меня был параметр clUseClient.
← →
KSergey © (2004-08-18 14:49) [12]> [11] ANB (18.08.04 14:11)
Дак я же не зря выделил...
← →
ANB (2004-08-18 18:51) [13]Кстати, по Вашим советам, я приготовил компонентик - скриптогонялку (понимает GO). Заодно и обрабатывает тексты ошибок. Если кому надо - выложу в кладовку.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2004.09.12;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.03 c