Как избежать ошибки T-SQL в хранимой процедуре? - PullRequest
1 голос
/ 14 января 2011

У меня есть несколько баз данных, которыми я управляю, и каждая нуждается в копии определенной хранимой процедуры.

Проблема в том, что хранимая процедура вставляется в таблицу для всех баз данных, кроме одной. Для этой одной базы данных таблица является секционированной и не обновляемой, и мне не нужно вставлять.

Я пытался сделать что-то вроде следующего:

CREATE PROCEDURE st_doit AS
    -- Do lots of other stuff...
    IF(DB_NAME() <> 'db3') BEGIN
       INSERT INTO mytable...;
    END

Я по-прежнему получаю сообщение об ошибке при попытке выполнить хранимую процедуру в db3 из-за оператора INSERT, хотя в этой базе данных вставка фактически не будет выполняться. Обертывание INSERT в блоке TRY...CATCH тоже не помогло.

Для простоты обслуживания я ДЕЙСТВИТЕЛЬНО хотел бы избежать специальной копии процедуры в db3. Обычно я не помещал бы такое выражение IF в процедуру, но в данном конкретном случае это действительно лучшее решение, и со временем оно не превратится в гнездо других особых случаев.

Итак, как заставить SQL Server просто выполнить хранимую процедуру и только выдать ошибку, если я действительно попытаюсь вставить в таблицу?

Редактировать: Поскольку использование динамического SQL было для меня слишком сложным, мое конечное решение состояло в том, чтобы оставить блок IF в качестве ловушки, но закомментировать блок, вызывающий сбой, в db3. Не идеально, но работает. К счастью, я не буду часто менять этот SP, но мне нужна «полная» копия в каждой базе данных.

Ответы [ 3 ]

3 голосов
/ 14 января 2011

Я думаю, что единственный способ - использовать динамический sql

if( objectproperty(object_id('dbo.MyTable'), 'isUserTable') = 1 ) begin
    -- insert the value 32 into MyColumn of MyTable
    exec sp_executesql 
        N'insert into MyTable(MyColumn) values(@MyColumnParam)',
        N'@MyColumnParam int',
        32

end
2 голосов
/ 14 января 2011

Вы должны были бы "скрыть" ВСТАВКУ от SQL Server, используя динамический SQL.

CREATE PROCEDURE st_doit AS
    -- Do lots of other stuff...
    IF(DB_NAME() <> 'db3') BEGIN
       EXEC SP_EXECUTESQL N'INSERT INTO mytable...';
    END
0 голосов
/ 15 января 2011

Возможно ли / удобнее иметь SP для детали в блоке IF? Только для DB3 это будет фиктивный SP, который ничего не делает, и для всех остальных, выполняющих фактическую вставку. Исходный SP будет одинаковым для каждой БД.

РЕДАКТИРОВАТЬ: Конечно, это потребовало бы поддержки двух «одинаковых» SP, но я могу представить некоторую практичность такого подхода, когда начальный SP довольно сложный, и поэтому особый случай может быть легче поддерживать для второй, меньший, который делает или не делает вставку.

...