Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.09.12;
Скачать: CL | DM;

Вниз

Ошибки выполнения хранимых процедур 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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.075 c
14-1093357407
alsov1
2004-08-24 18:23
2004.09.12
Ищу электронные книги по Ораклу


14-1093409534
rok
2004-08-25 08:52
2004.09.12
Что означает Sys Rq на клавише Print Screen?


3-1092453067
Vitalik
2004-08-14 07:11
2004.09.12
поле типа varbinary


14-1093001164
Грибоедов
2004-08-20 15:26
2004.09.12
Delphi 8. Начало конца.


3-1092660007
Вика
2004-08-16 16:40
2004.09.12
Установка курсора ...