Как проверить, доступна ли таблица для удаления и создания триггера? - PullRequest
1 голос
/ 15 декабря 2011

У меня длинный скрипт в SQL Server 2000 (17 000 строк и больше).

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

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

Мне нужна полуавтоматическая установка, и у меня есть как минимум два варианта:

а) пессимистический подход: Подтвердите доступность всех таблиц в начале и покажите предупреждение + "set exec off", если какая-то таблица используется (очень маловероятно, что она будет использоваться между запуском и созданием триггера)

б) оптимистический подход: Покажите предупреждение в начале, когда какая-либо таблица используется, и оставьте его мне, если установка может продолжиться, инкапсулируя ошибочные триггеры с помощью set exec off / on code. Я могу сделать это, потому что код триггера, как правило, очень стабильный (несколько лет)

В любом случае, мне просто нужно знать, доступна ли таблица для удаления / создания триггера без остановки моего процесса (блокировка таблицы?). Я вошел в BOL и некоторые форумы, но я действительно не знаю, что искать.

обновление:
Используйте этот выбор, чтобы найти значения Type_Id & Mode_Id & Sts_Id ...
(у меня 5, 6 и 1 соответственно, но МОГУТ быть другие, те, что пришли только из первоначального тестирования)
%%% ПРЕДУПРЕЖДЕНИЕ: помните, MS может ИЗМЕНИТЬ или УСТАРЕТЬ их, поскольку это НЕ лучший способ сделать это, но единственный, который я нашел, пока ...

use <your_db_here>  
go  

declare @TblNam varchar(100)  
select  @TblNam = '<your_[usr.]table_name_here>'  

select  convert (smallint, l.req_spid)  spId,
        coalesce(s.loginame,'')         UsrNam,
        coalesce(s.hostname,'')         HstNam,
        l.rsc_dbid                      dbId,
        db_name(l.rsc_dbid)             dbNam,
        l.rsc_objid                     objId,
        object_name(l.rsc_objid)        objNam,
        l.rsc_indid                     indId,
        substring(v.name, 1, 4)         Type,
        substring(l.rsc_text, 1, 16)    Resource,
        substring(u.name, 1, 8)         Mode,
        substring(x.name, 1, 5)         Status,
        l.rsc_type                      Type_Id,
        l.req_mode+1                    Mode_Id,
        l.req_status                    Sts_Id

   from master.dbo.syslockinfo  l                                                   inner join  
        master.dbo.spt_values   v   on v.type = 'LR' and v.number = l.rsc_type      inner join  
        master.dbo.spt_values   x   on x.type = 'LS' and x.number = l.req_status    inner join  
        master.dbo.spt_values   u   on u.type =  'L' and u.number = l.req_mode+1  
        master.dbo.sysprocesses s   on s.spid = l.req_spid

  where db_name(l.rsc_dbid) = db_name()  
    and v.name      = 'TAB'  
    and l.rsc_objid = object_id(@TblNam)  

1 Ответ

1 голос
/ 16 декабря 2011

этот подход лучше, чем копаться в системных таблицах:

set lock_timeout 1
select top 1 * from <your_[usr.]table_name_here> (tablockx)
select @@error
...