Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Ошибки выполнения хранимых процедур MS SQL при запуске из Delphi [D7, MSSQL]


ANB ©   (2004-08-18 12:21:00) 

Уважаемые мастера. Помогите решить следующую задачу.
Мне нужно выполнить из клиента на Delphi пакет хранимых процедур.
В каждой процедуре происходит массовая обработка данных со вставкой их в различные таблицы.
При запуске процедуры из Delphi, если при обработке очередной записи происходит ошибка (например отвалился инсерт по констрейнту), то прекращается работа всей процедуры. А мне нужно только сохранить эту ошибку в лог и идти дальше.
При выполнении из Query Analyzer (exec MyProc) все так и работает - то есть вываливаются мессаги о всех ошибка - а процедура продолжает работать, пока не обработает все записи.
Как такое же можно сделать из Delphi ?
PS. Процедуры правке не подлежат и я видел живой пример на Visual C++ где все работает, но у меня нет исходников.
Я уже облазил все форумы, нашел как достать print и там же - что задача не решается, но ведь РЕШЕНА ?!


ANB   (2004-08-18 18:51:00) [1]

Кстати, по Вашим советам, я  приготовил компонентик - скриптогонялку (понимает GO). Заодно и обрабатывает тексты ошибок. Если кому надо - выложу в кладовку.


KSergey   (2004-08-18 14:49:00) [2]

> [11] ANB   (18.08.04 14:11)

Дак я же не зря выделил...


ANB   (2004-08-18 14:11:00) [3]

Все проблемы были в CursorLocation:=clUseServer; У меня был параметр clUseClient.


ANB   (2004-08-18 14:10:00) [4]

Всем спасибо. На 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 13:48:00) [5]

Еще раз - процедуры я менять не могу - их большее 100 и у них сложная логика. Как говорится - Солнце всходит и заходит ? Каждый день ? Тогда лучше не трогай !


ANB   (2004-08-18 13:42:00) [6]

Print и через Delphi + ADO (только не через компоненты, а через интерфейс) прекрасно качается. Проблема в обработке ошибок. Процедура действительно отрабатывает вся, но :
1. После первой же ошибки Delphi + ADO считает, что она завалилась. А эти поцедуры по 2-3 часа могут работать. И их нужно по очереди запускать.
2. Вытаскивается только первая ошибка.
Кстати, откопал прикол - если юзать TcsSQLQuery, то приезжает только последняя ошибка.


clickmaker   (2004-08-18 13:14:00) [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
 ...

а дальше на клиенте этот список уже обрабатываешь


KSergey   (2004-08-18 13:11:00) [8]

> [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;


ANB   (2004-08-18 13:04:00) [9]

И правда работает, но мне все равно надо все ошибки вытащить, а они пропадают.


ANB   (2004-08-18 12:59:00) [10]

Без проблем.
Примерно так:
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 без прерывания работы программы. Это самый простой случай процедуры, сами они намного сложнее.


KSergey   (2004-08-18 12:36:00) [11]

Поверьте, процедура всегда продолжает работать до конца (так уж MS SQL устроен). Просто дельфи показывает только первую ошибку.


Ega23   (2004-08-18 12:32:00) [12]

При выполнении из Query Analyzer (exec MyProc) все так и работает - то есть вываливаются мессаги о всех ошибка - а процедура продолжает работать, пока не обработает все записи.

Как это? На код этой процедуры можно взглянуть?


Ega23   (2004-08-18 12:31:00) [13]

При выполнении из Query Analyzer (exec MyProc) все так и работает - то есть вываливаются мессаги о всех ошибка - а процедура продолжает работать, пока не обработает все записи.

Как это? На код этой процедуры можно взглянуть?


Наверх

Титульная страница Поиск, карта сайта Написать письмо