0

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

问题是它命中了 AS 的第一个实例,它可能是注释(ie -- Trigger to prevent update of LastUpdated column) 或触发器名称(ie 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%''
4

3 回答 3

1

您是否尝试''% AS%''过(AS 之前的空格)?

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

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

于 2013-09-13T04:05:18.067 回答
0

我建议使用SQL Server 管理对象 (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);
                }
            }
}
于 2014-12-29T15:12:21.137 回答
0

在我的代码中,我使用“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
于 2015-06-17T01:09:04.800 回答