【问题标题】:Updating ALL Triggers with "NOT FOR REPLICATION" in SQL Server 2012在 SQL Server 2012 中使用“NOT FOR REPLICATION”更新所有触发器
【发布时间】:2013-08-16 12:10:10
【问题描述】:

我们有 505 个触发器需要设置 NOT FOR REPLICATION 标志。找到了一个搜索“%AS%”的用户查询,并在此之前添加了NOT FOR REPLICATION

问题是它命中第一个 AS 实例,可能是 comment(即-- Trigger to prevent update of LastUpdated column)或触发器名称(即trgLastUpdated)。

以下是我们一直在尝试的。有人对找到正确的AS 以及如何将NOT FOR REPLICATION 放在它之前有任何建议吗?

主要查询:

DROP TABLE #TriggersNFR
CREATE TABLE #TriggersNFR (ServerName varchar(250), Dbname varchar(250),TableName varchar(250), TriggerName varchar(250), FixingScript varchar(max))
exec sp_MSforeachdb '
IF ''?'' NOT IN (''tempdb'',''master'',''model'',''msdb'') BEGIN
USE ?
insert into #TriggersNFR
SELECT @@servername,''?'' DBName,OBJECT_NAME(parent_object_id) TableName,
OBJECT_NAME(o.object_id) [Trigger Name],
STUFF (REPLACE(definition,''CREATE TRIGGER'',''ALTER TRIGGER''),
PATINDEX(''%AS%'',REPLACE(definition,''CREATE TRIGGER'',''ALTER TRIGGER'')),0,''
NOT FOR REPLICATION '')
+ ''
GO
''
from ?.sys.objects o
join ?.sys.sql_modules m
on o.object_id = m.object_id
where o.type = ''TR''
and OBJECTPROPERTY(o.object_id, ''ExecIsTriggerNotForRepl'') = 0
AND OBJECTPROPERTY(o.object_id, ''IsMSShipped'') = 0
END
'

select * from #TriggersNFR
order by Dbname

在 FixingScript 列中有示例输出:

-- =============================================
-- Author:      #####
-- Create date: 9/14/2012
-- Description: Prevents updating of a L
 NOT FOR REPLICATION astUpdated date that would cause app to drop an update when the next one comes along.
-- =============================================
ALTER TRIGGER trgAppUpdates_Upd_LastUpdated
   ON APP_REGISTER_UPDATES
   AFTER UPDATE
AS 
BEGIN

已尝试更改此设置,但结果不成功:

PATINDEX(''%AS%'',

PATINDEX(char(13)+''%AS%''

PATINDEX(''%''+char(13)+''AS%''

PATINDEX(''%''+char(13)+char(10)+''AS%''

【问题讨论】:

    标签: triggers sql-server-2012 database-replication


    【解决方案1】:

    您尝试过''% AS%''(AS 前的空格)吗?

    您是否尝试过区分大小写的搜索?
    PATINDEX(''%AS%'', [skipped], COLLATE SQL_Latin1_General_Cp1_CS_AS) 或任何其他区分大小写的排序规则?

    顺便说一句,非常感谢脚本:)。

    【讨论】:

      【解决方案2】:

      我建议使用SQL Server Management Objects (SMO)

      // compile with: 
      // /r:Microsoft.SqlServer.Smo.dll
      // /r:Microsoft.SqlServer.ConnectionInfo.dll
      // /r:Microsoft.SqlServer.Management.Sdk.Sfc.dll 
      
      // using System;
      // using Microsoft.SqlServer.Management.Smo;
      // using Microsoft.SqlServer.Management.Common;
      
              void M(){
      
                  string sqlServerLogin ="__" ;
                  string password = "__";
                  string remoteSvrName ="__" ;
                  string dbName = "__";
      
                  ServerConnection conn = new ServerConnection(remoteSvrName);
                  conn.LoginSecure = false;
                  conn.Login = sqlServerLogin;
                  conn.Password = password;
                  Server srv = new Server(conn);
      
                  var db = srv.Databases[dbName];
      
                  foreach (Table tab in db.Tables)
                  {
                      foreach (Trigger trig in tab.Triggers)
                      {
                          trig.TextMode = false;
                          trig.NotForReplication = true;
                          trig.TextMode = true;
                          trig.Alter();
      
                          Console.WriteLine(trig.Name);
                      }
                  }
      }
      

      【讨论】:

        【解决方案3】:

        在我的代码中,我使用“case”而不是 PATINDEX

        select
        '
        ---------------------------------------------------- 
        ---------------------------------------------------- 
        ----------------------------------------------------
        DROP TRIGGER [dbo].[' + name + ']
        GO 
        ----------------------------------------------------
        ' + 
        SUBSTRING([definition], 1, FirstAsPosition) + ' NOT FOR REPLICATION ' + 
        SUBSTRING([definition], FirstAsPosition, len([definition]))  
        + '
        GO
        ----------------------------------------------------
        '
        AS SQLTriggersScript
         from 
        (
        select 
            name,[definition],
            case when 
                (case when AsIndex1 = 0 then 1000000 else AsIndex1 end)  
                    < 
                 (case when AsIndex2 = 0 then 1000000 else AsIndex2 end)    
                     then 
                AsIndex1
            else 
                AsIndex2
            end AS FirstAsPosition
          from 
            (
                select 
                    obj.name, [definition], 
                    CHARINDEX(' AS', [definition]) as AsIndex1, 
                    CHARINDEX(CHAR(13)+CHAR(10)+'AS', [definition]) as AsIndex2 
                from sys.sql_modules m
                inner join sys.objects obj on obj.object_id=m.object_id 
                where obj.type ='TR' 
                AND OBJECTPROPERTY(obj.object_id, 'ExecIsTriggerNotForRepl') = 0
                AND OBJECTPROPERTY(obj.object_id, 'IsMSShipped') = 0
            ) as t
        ) as t
        

        【讨论】:

          猜你喜欢
          • 2017-06-20
          • 2015-04-25
          • 2012-08-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-28
          • 1970-01-01
          • 2016-11-03
          相关资源
          最近更新 更多