Второй раз сталкиваюсь с неспортивным поведением со стороны MSSQL. И дабы встретив третий не тратить на него полдня документирую.

Имеется:

  1. два слинкованных MSSQL-сервера
  2. подключение к одному из них
  3. хранимая процедура на другом

Требуется:

  • вызвать эту процедуру c набором параметров и получить результат.

Решение:

exec LINKED_SERVER.SELECTED_DATABASE.dbo.procedure_name @param_2=value, @param_1=value, @param_3=value…

Ничего не предвещает беды. Небо чистое, коннект уверенный, лаг умеренный… и тут… растёт напряжение, давит тишина, в жилах стынет кровь и появляется леденящий душу ПИЗДЕЦ!

Я не случайно параметры написал “вразнобой”. Казалось бы ничего криминального – они же именованы. И всё отлично покуда все параметры принимают какие-либо значения. Но как только окажется что @param_2=null (или @param_1) вы будете приятно удивлены загадочными сообщениями вроде “а почему это параметр_2 не передан?” или “зачем параметр_1 ты передал мне два раза?”. И будете долго биться в истерике, когда окажется, что выполняя запрос сразу на нужном сервере, вы получаете нормальный результат без каких-либо сообщений об ошибках. Мистика?

Как удалось выяснить – параметр, который null на линкованный сервер попадает уже без имени (т.е. не “@param_2=null, @param_1=value, @param_2=value”, a “NULL, @param_1=value, @param_3=value” и как следствие – этот самый NULL в данном случае будет считаться первым входным параметром в процедуре…

Решение было тривиальным(и глупым) – вынести все параметры, которые могут быть null, в конец объявления. Но если кто-то объяснит суть описываемого явления, и красивый выход из такого положения – буду очень признателен.

NULL без палочки
Tagged on:     

One thought on “NULL без палочки

  • 24.01.2008 at 19:40
    Permalink

    Не знаю конкретно как в MSSQL, но вообще в SQL принято работать с NULL как
    param_2 IS NULL, а выражение типа param_2=null даст неопределенность независимо от значения param_2

Leave a Reply