IF EXISTS (SELECT * FROM sys.triggers WHERE parent_class = 0 AND name = 'tt')
DROP TRIGGER tt ON DATABASE;
GO
CREATE TRIGGER tt ON DATABASE
FOR CREATE_TABLE
AS
BEGIN 
    SET CONCAT_NULL_YIELDS_NULL ON
    DECLARE @AffectedTable nvarchar(255),@backUpTable nvarchar(255),@create_Script nvarchar(max)
    --获取建表的语句
    SELECT  @create_Script=EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)')
    --获取表的名称
    SELECT  @AffectedTable = EVENTDATA().value('(/EVENT_INSTANCE/ObjectName)[1]','nvarchar(255)')
    --定义一个备份的表名称
    SELECT  @backUpTable ='admin.'+@AffectedTable    --替换表名
    SELECT  @create_Script=REPLACE(@create_Script,@AffectedTable,@backUpTable)
    --执行建表语句
    EXEC(@create_Script)
    --给创建的表加一个DML触发器
    EXEC('
        CREATE TRIGGER tt_'+@AffectedTable+' ON '+@AffectedTable+'
        FOR INSERT
        AS 
        BEGIN
            INSERT INTO '+@backUpTable+' SELECT * FROM INSERTED
        END'
    )
    SET CONCAT_NULL_YIELDS_NULL OFF
END 
这是一个DDL触发器,用于在用户新增表的时候把该表备份,同时把该备份的表指定到另外一个架构下
但是我在数据库里操作都是没问题的,完美备份。 但是在客户端就报错。求大神指点!!

解决方案 »

  1.   


    ************** 异常文本 **************
    System.Exception: Error1 in SQL ---> System.Data.SqlClient.SqlException: SELECT 失败,因为下列 SET 选项的设置不正确:'ARITHABORT'。请确保 SET 选项可正确用于计算列和/或查询通知和/或 xml 数据类型方法的索引视图和/或索引。
       在 System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
       在 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
       在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
       在 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
       在 System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async)
       在 System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
       在 System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
       在 x662c37ca81a84177.xde5a5bc74acf4615(SqlConnection xa7996d266379ca40, String x1a5c049afbd11148)
       --- 内部异常堆栈跟踪的结尾 ---
       在 x662c37ca81a84177.xde5a5bc74acf4615(SqlConnection xa7996d266379ca40, String x1a5c049afbd11148)
       在 x5885c7b0b05b341e.ACJY6VPtdF3tSh(xD(Object , EventArgs )
       在 System.Windows.Forms.Control.OnClick(EventArgs e)
       在 System.Windows.Forms.Button.OnClick(EventArgs e)
       在 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       在 System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       在 System.Windows.Forms.Control.WndProc(Message& m)
       在 System.Windows.Forms.ButtonBase.WndProc(Message& m)
       在 System.Windows.Forms.Button.WndProc(Message& m)
       在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       在 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
      

  2.   

    SELECT @backUpTable ='admin.'+@AffectedTable --替换表名
    问题可能出在这里客户端的脚本可能已经含有架构名了,你这样替换
    那就是把create table dbo.tb
    替换成 create table dbo.admin.tb
    能不出错吗
      

  3.   

    好像是你这两句的影响,能去掉吗?
    SET CONCAT_NULL_YIELDS_NULL ON
    SET CONCAT_NULL_YIELDS_NULL OFF
      

  4.   

    汤哥啊,不能这么搞我呀,这是你告诉我的呀我试了能替换的啊, 替换的表名就是 admin.的
      

  5.   

    这两个要不要都都一样的,默认就是on  可以去掉
    SQL Server 的未来版本中,CONCAT_NULL_YIELDS_NULL 将始终为 ON
      

  6.   

    你自己想一下啊
    你的脚本 可能是create table 数据库.架构.表
    也可能是 create table 数据库..表
    create table 架构.表
    create table 表
    直接盲目的去替换,这太粗鲁了吧
      

  7.   

    IF EXISTS (SELECT * FROM sys.triggers WHERE parent_class = 0 AND name = 'tt')
    DROP TRIGGER tt ON DATABASE;
    GO
    CREATE TRIGGER tt ON DATABASE
    FOR CREATE_TABLE
    AS
    BEGIN  
    SET ARITHABORT  ON  SET CONCAT_NULL_YIELDS_NULL ON  DECLARE @AffectedTable nvarchar(255),@backUpTable nvarchar(255),@create_Script nvarchar(max)
      --获取建表的语句
      SELECT @create_Script=EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)')
      --获取表的名称
      SELECT @AffectedTable = EVENTDATA().value('(/EVENT_INSTANCE/ObjectName)[1]','nvarchar(255)')
      --定义一个备份的表名称
      SELECT @backUpTable ='admin.'+@AffectedTable --替换表名
      SELECT @create_Script=REPLACE(@create_Script,@AffectedTable,@backUpTable)
      --执行建表语句
      EXEC(@create_Script)
      --给创建的表加一个DML触发器
      EXEC('
      CREATE TRIGGER tt_'+@AffectedTable+' ON '+@AffectedTable+'
      FOR INSERT
      AS  
      BEGIN
      INSERT INTO '+@backUpTable+' SELECT * FROM INSERTED
      END'
      )
      SET CONCAT_NULL_YIELDS_NULL OFF
    END  加上红色的那句试试。你是否xml 数据类型方法有索引视图或索引。
      

  8.   

    都讨论到人道的问题上拉?
    思路可以是:
    建了表之后,使用select * into 动态表名 from 新建的表 
    然后把 动态表名 的架构修改。好像不用你的那个那么复杂吧
      

  9.   

    我知道啊,我是说先建表再改架构嘛。对咯,你可以用excute as user这个语句,当你创建的时候,用具有那个架构的用户来执行就可以了。
      

  10.   


    啊啊啊,我不会用 excute as user 这个语句
      

  11.   


    execute as user 去找联机丛书吧。