проверка результата исполнения запроса MSSQL2000
подскажите пожалуйста как решить такую проблему. пару лет назад сотворили прогу на Delphi которая копошит базу на MSSQL2000. до 20 клиентов, непосредственно данные меняются хранимыми процедурами. все работало отлично. Недавно попросили дополнить проверкой на задвоенность часть вводимых данных. сделали. эта проверка заметно поднапрягла сервер (2-х головый P-700).
И всплыл такой косяк - юзеры жмут "сохранить", делфийская часть говорит - ОК, а реально в базе остаются старые данные. Я отошел в настоящее время от SQL и смаху не могу внятную проверку на РЕАЛЬНОЕ выполнение запроса на изменение сообразить. Как это можно сделать малой кровью? (в MSAccess есть возможность глянуть сколько записей было реально изменено, а в SQL что-то не нашел подобного) помогите кто знает.
И всплыл такой косяк - юзеры жмут "сохранить", делфийская часть говорит - ОК, а реально в базе остаются старые данные. Я отошел в настоящее время от SQL и смаху не могу внятную проверку на РЕАЛЬНОЕ выполнение запроса на изменение сообразить. Как это можно сделать малой кровью? (в MSAccess есть возможность глянуть сколько записей было реально изменено, а в SQL что-то не нашел подобного) помогите кто знает.
небольшое уточнение про механизм. Делфийская часть запускает соответствующую хранимую процедуру, в которой уже запускается несколько запросов на изменение данных в таблицах, и проверку хочу поставить непосредственно после этих запросов в хранимой процедуре и вернуть наверх результат. То что приходит в голову сейчас - либо.... короче не нравиться.
Берешь профайлер и ловишь запросы, которые посылает дельфийская часть когда юзеры жмут ОК. смотришь что за запросы (что за хранимые процедуры вызываются). Далее: если все-таки вызываются процедуры на изменение данных, и даже это нужные процедуры вызываются то делаешь следующим образом. Открываешь Query Analyzer и дебагишь эти процедуры в соответствующем порядке и смотришь что именно они делают. Обрати внимание на работу транзакций - возможно ты начинаешь ее, но не закоммичиваешь в следствие чего данные не сохраняются, или наоборот - в процедуре происходит ошибка, транзакция откатывается а из под делфи эту ошибку не видно и ты поэтому о ней не знаешь...
Вот вобщем несколько советов как отследить и поймать вышеописанный баг. Жлаю удачи, если и так не найдешь - пиши, можно еще чего-нить придумать.
Вот вобщем несколько советов как отследить и поймать вышеописанный баг. Жлаю удачи, если и так не найдешь - пиши, можно еще чего-нить придумать.
спасибо за придание уверенности куда искать - и нашел. Думать начинал по копии исходников хранимых дома и голова пухла, а заглянул в процедуры в реальной базе - кто-то покапался. Операторы транзакций забиты коментариями ! Выразилось это в том, что редактируемые данные сохранялись через раз, а иногда только и на 3-4-й раз. Поправлю завтра и надеюсь заработает. Вставлю на всякий случай анализ @@transtate (если не ошибаюсь) для определения как завершилась транзакция - правильно? или как по другому?
Никогда не пользовался @@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;
Еще одно спасибо. стал использовать @error, но я почему-то думал что запрос на изменение, если не изменит ни одной записи, может в нем не отразится - это же не явная ошибка, если отражается тогда хорошо (может два года назад я это и сам знал
).
Но самое нехорошее после этого у меня сейчас это то, что, когда я транзакцию (с @error -ом ) вставил - сохраниться данные за 20 минут смогли только пару раз. всем остальным постояно говорит "ошибка"!
С базой работало 16 человек. Дома (я работал с базой один) все сохранялось отлично. Против первой версии добавлена только проверка на задвоенность при сохранении. Проверяются изменяемые данные, запрос, который ищет задвоенные данные, почти каждый раз обновляется из базы (не кэшируется т.е.) из-за поступающих изменений и из-за разных условий отбора. Может это настолько напрячь сервак что остальные запросы не успевают отработать???? может где-то есть доступ к этим таймерам? Меня это почему все напрягает, потому-что я отошел от этого и времени нету опять вникать - а исправить тем не менее надо
Пока вернул старую версию, там хоть на 3-4 сохранений одно недосохранялось (вернее сохранялось но с 2-4 раза), а с транзакцией вааще все встали как кони во ржи!
Как сделать чтобы пусть медлено, но стабильно сохранялось? как проверка эта должна по доброму быть сделана? Того что помню сам - не хватает, вникать заново - нету времени КАРАУЛ!
Чуть детальней: где лучше ставить операторы транзакции, в делфийской части или непосредственно в хранимке? или без разницы?

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

Пока вернул старую версию, там хоть на 3-4 сохранений одно недосохранялось (вернее сохранялось но с 2-4 раза), а с транзакцией вааще все встали как кони во ржи!

Чуть детальней: где лучше ставить операторы транзакции, в делфийской части или непосредственно в хранимке? или без разницы?
Все что я писал в предыдущем сообщении относиться к хранимой процедуре сервера - первый кусок кода пишется в самом начале процедуры перед вообще какими то ни было действиями.
Последний кусок наоборот в самом конце уже после всевозможных действий.
А проверка на @@error - пишеться там где на Ваш взгляд может быть ошибка. (А вообще желательно после каждой операции со вставкой или апдейтом таблицы, открытием курсора, выполнения вложенной процедуры и т.п.)
А по поводу как правильно сохраняются данные передаваемые из Делфи - это уже немножко другой вопрос и возможно все дело абсолютно не в транзакциях, а в самом процессе вставки/изменения данных в таблицы.
Последний кусок наоборот в самом конце уже после всевозможных действий.
А проверка на @@error - пишеться там где на Ваш взгляд может быть ошибка. (А вообще желательно после каждой операции со вставкой или апдейтом таблицы, открытием курсора, выполнения вложенной процедуры и т.п.)
А по поводу как правильно сохраняются данные передаваемые из Делфи - это уже немножко другой вопрос и возможно все дело абсолютно не в транзакциях, а в самом процессе вставки/изменения данных в таблицы.
а такой маленький вопрос. Если какой-то из запросов на изменение внутри транзакции умирает по таймауту (по причине большой загрузки сервера) следующая за этим запросом в процедуре команда (проверка например) выполняется ? а то меня тут через плечо грузят что не выполняется и будет откат транзакции автоматом. А?
Тогда скорее всего транзакция откатится. Решить можно попробовать следующим образом - все операции внутри процедуры разбить на более мелкие (по возможности конечно) чтобы они по таймауту не умирали (не успевали умереть). Или сервак помощнее поставить 

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

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

Так что если мудрые мысли есть - выслушаю с удовольствием.