проверка результата исполнения запроса MSSQL2000

SQL во всех проявлениях - от ANSI-92 до TSQL.

Модераторы: Yurich, Absurd

igora
Сообщения: 7
Зарегистрирован: 09 июн 2005, 03:51
Откуда: иркутск

подскажите пожалуйста как решить такую проблему. пару лет назад сотворили прогу на Delphi которая копошит базу на MSSQL2000. до 20 клиентов, непосредственно данные меняются хранимыми процедурами. все работало отлично. Недавно попросили дополнить проверкой на задвоенность часть вводимых данных. сделали. эта проверка заметно поднапрягла сервер (2-х головый P-700).
И всплыл такой косяк - юзеры жмут "сохранить", делфийская часть говорит - ОК, а реально в базе остаются старые данные. Я отошел в настоящее время от SQL и смаху не могу внятную проверку на РЕАЛЬНОЕ выполнение запроса на изменение сообразить. Как это можно сделать малой кровью? (в MSAccess есть возможность глянуть сколько записей было реально изменено, а в SQL что-то не нашел подобного) помогите кто знает.
igora
Сообщения: 7
Зарегистрирован: 09 июн 2005, 03:51
Откуда: иркутск

небольшое уточнение про механизм. Делфийская часть запускает соответствующую хранимую процедуру, в которой уже запускается несколько запросов на изменение данных в таблицах, и проверку хочу поставить непосредственно после этих запросов в хранимой процедуре и вернуть наверх результат. То что приходит в голову сейчас - либо.... короче не нравиться.
AndreykA
Сообщения: 48
Зарегистрирован: 15 ноя 2004, 12:55
Откуда: Москва
Контактная информация:

Берешь профайлер и ловишь запросы, которые посылает дельфийская часть когда юзеры жмут ОК. смотришь что за запросы (что за хранимые процедуры вызываются). Далее: если все-таки вызываются процедуры на изменение данных, и даже это нужные процедуры вызываются то делаешь следующим образом. Открываешь Query Analyzer и дебагишь эти процедуры в соответствующем порядке и смотришь что именно они делают. Обрати внимание на работу транзакций - возможно ты начинаешь ее, но не закоммичиваешь в следствие чего данные не сохраняются, или наоборот - в процедуре происходит ошибка, транзакция откатывается а из под делфи эту ошибку не видно и ты поэтому о ней не знаешь...
Вот вобщем несколько советов как отследить и поймать вышеописанный баг. Жлаю удачи, если и так не найдешь - пиши, можно еще чего-нить придумать.
igora
Сообщения: 7
Зарегистрирован: 09 июн 2005, 03:51
Откуда: иркутск

спасибо за придание уверенности куда искать - и нашел. Думать начинал по копии исходников хранимых дома и голова пухла, а заглянул в процедуры в реальной базе - кто-то покапался. Операторы транзакций забиты коментариями ! Выразилось это в том, что редактируемые данные сохранялись через раз, а иногда только и на 3-4-й раз. Поправлю завтра и надеюсь заработает. Вставлю на всякий случай анализ @@transtate (если не ошибаюсь) для определения как завершилась транзакция - правильно? или как по другому?
AndreykA
Сообщения: 48
Зарегистрирован: 15 ноя 2004, 12:55
Откуда: Москва
Контактная информация:

Никогда не пользовался @@transtate.
Я всегда делаю следующим образом:
В начале процедуры пишу:

Код: Выделить всё

DECLARE @error INT, @TranName VARCHAR(30), @errmsg VARCHAR(255);
SET @error = 0;
SET @errmsg = '';
SET @TranName = 'Имя транзакции какое хочешь';

Begin Transaction @TranName;
В теле процедуры после каких-либо действий в которых может возникнуть ошибка:

Код: Выделить всё

SET @error = @@error
IF @error <> 0 BEGIN
  SET @errmsg = 'Произошла такая-то ошибка...'
  GOTO _Error
END

А в конце процедуры:

Код: Выделить всё

_Error:
IF @error <> 0 BEGIN
    ROLLBACK TRANSACTION @TranName;
  IF (@errmsg <> '')
    RAISERROR(@errmsg, 16, 1) WITH SETERROR;
END
ELSE
    COMMIT TRANSACTION @TranName;
igora
Сообщения: 7
Зарегистрирован: 09 июн 2005, 03:51
Откуда: иркутск

Еще одно спасибо. стал использовать @error, но я почему-то думал что запрос на изменение, если не изменит ни одной записи, может в нем не отразится - это же не явная ошибка, если отражается тогда хорошо (может два года назад я это и сам знал :) ).
Но самое нехорошее после этого у меня сейчас это то, что, когда я транзакцию (с @error -ом ) вставил - сохраниться данные за 20 минут смогли только пару раз. всем остальным постояно говорит "ошибка"!
С базой работало 16 человек. Дома (я работал с базой один) все сохранялось отлично. Против первой версии добавлена только проверка на задвоенность при сохранении. Проверяются изменяемые данные, запрос, который ищет задвоенные данные, почти каждый раз обновляется из базы (не кэшируется т.е.) из-за поступающих изменений и из-за разных условий отбора. Может это настолько напрячь сервак что остальные запросы не успевают отработать???? может где-то есть доступ к этим таймерам? Меня это почему все напрягает, потому-что я отошел от этого и времени нету опять вникать - а исправить тем не менее надо :(
Пока вернул старую версию, там хоть на 3-4 сохранений одно недосохранялось (вернее сохранялось но с 2-4 раза), а с транзакцией вааще все встали как кони во ржи! :( Как сделать чтобы пусть медлено, но стабильно сохранялось? как проверка эта должна по доброму быть сделана? Того что помню сам - не хватает, вникать заново - нету времени КАРАУЛ!

Чуть детальней: где лучше ставить операторы транзакции, в делфийской части или непосредственно в хранимке? или без разницы?
AndreykA
Сообщения: 48
Зарегистрирован: 15 ноя 2004, 12:55
Откуда: Москва
Контактная информация:

Все что я писал в предыдущем сообщении относиться к хранимой процедуре сервера - первый кусок кода пишется в самом начале процедуры перед вообще какими то ни было действиями.
Последний кусок наоборот в самом конце уже после всевозможных действий.
А проверка на @@error - пишеться там где на Ваш взгляд может быть ошибка. (А вообще желательно после каждой операции со вставкой или апдейтом таблицы, открытием курсора, выполнения вложенной процедуры и т.п.)
А по поводу как правильно сохраняются данные передаваемые из Делфи - это уже немножко другой вопрос и возможно все дело абсолютно не в транзакциях, а в самом процессе вставки/изменения данных в таблицы.
igora
Сообщения: 7
Зарегистрирован: 09 июн 2005, 03:51
Откуда: иркутск

а такой маленький вопрос. Если какой-то из запросов на изменение внутри транзакции умирает по таймауту (по причине большой загрузки сервера) следующая за этим запросом в процедуре команда (проверка например) выполняется ? а то меня тут через плечо грузят что не выполняется и будет откат транзакции автоматом. А?
AndreykA
Сообщения: 48
Зарегистрирован: 15 ноя 2004, 12:55
Откуда: Москва
Контактная информация:

Тогда скорее всего транзакция откатится. Решить можно попробовать следующим образом - все операции внутри процедуры разбить на более мелкие (по возможности конечно) чтобы они по таймауту не умирали (не успевали умереть). Или сервак помощнее поставить :)
igora
Сообщения: 7
Зарегистрирован: 09 июн 2005, 03:51
Откуда: иркутск

пока натыкал индексации по везде где что-то ищется, и помогло !начали сохраняться и с транзакцией за редким исключением. Но дни были не нагружены. В субботу будет тяжелый день и будет ясно окончательно. Но начальство уже раскрутил на двухголовый пень 2,8 Мгц на Е7520, 2 гига оперативы, :) надеюсь что все заработает и буду спать спокойно.

Но для себя всеже заусило, на досуге хочу разобраться как такие моменты обходить. (да и вдруг все-же придется снова доделывать :) )
Так что если мудрые мысли есть - выслушаю с удовольствием.
Ответить