SQL Server 触发器插入/更新特定列

Posted

技术标签:

【中文标题】SQL Server 触发器插入/更新特定列【英文标题】:SQL Server trigger Insert/Update specific column 【发布时间】:2019-07-21 16:01:35 【问题描述】:

关键是要触发:

检查包含ConnectionField nvarchar(50)列的配置表 它应该返回将用作键的字符串值(columnName

所以在表Workers 上插入/更新时,代码应将我的Xfield 值设置为ConnectionField 列中的值,从Configuration 表中读取。

简而言之,因为这一切都很混乱。我希望能够让我的最终用户根据他的选择触发器在配置中写下他将使用哪个列作为唯一列(工人 ID、SNSID、名称等...)需要将该字段值放入我的 Xfield

不要问为什么。真的很混乱。

我已经编写了一个触发器,它可以做到这一点,但它只是卡在无限循环中的某个地方

CREATE TRIGGER [dbo].Tr_ConnectionField 
ON [dbo].Workers
FOR INSERT, UPDATE 
AS
    SET NOCOUNT ON;

    DECLARE @ID BIGINT
    DECLARE @tmpUpit CURSOR;
    DECLARE @ConFieldSETUP NVARCHAR(50)

    -- Here I will read the field from configuration which will be used as key
    SET @ConFieldSETUP = (SELECT TOP 1 ISNULL(ConnectionField, 'SNSID') 
                          FROM ConfigurationTable)

    BEGIN
        SET @tmpUpit = CURSOR LOCAL SCROLL FOR
            SELECT i.id FROM inserted i

        OPEN @tmpUpit
    END

    FETCH NEXT FROM @tmpUpit INTO @ID 

    WHILE @@fetch_status = 0
    BEGIN
        -- Here I will use the configuration columns value to my Xfield
        UPDATE Workers 
        SET Xfield = (SELECT @ConFieldSETUP 
                      FROM Workers cld 
                      WHERE cld.Id = @ID) 
        WHERE Id = @ID
    END

    FETCH NEXT FROM @tmpUpit INTO @ID

    DEALLOCATE @tmpUpit 

【问题讨论】:

首先,您的触发器将Xfield 设置为变量@ConFieldSETUP 的值,例如'SNSID'。要使用@ConFieldSETUP 作为列的名称,您需要动态 sql。或者更好地使用case 表达式来根据@ConFieldSETUP 选择源列之一。接下来,使用 inserted 连接而不是光标。最后,使用***.com/questions/1529412/… 方法之一防止触发递归 你的第二个 FETCH NEXT 需要在循环中,而不是在它之后。 旁白:top 通常与order by 一起出现。 @Serg 好吧,你愿意说我需要某种字符串变量,它将字符串作为查询连接,然后执行它或?我不知道你在动态查询下是什么意思。 是的,将字符串连接为查询然后执行它称为动态sql。但是在触发器中使用它是有问题的,动态 sql 无法访问 inserted deleted 表。如果您仍然需要,我会建议使用来自inserted 的表参数为Ids 的存储过程。 【参考方案1】:

试试

CREATE TRIGGER [dbo].Tr_ConnectionField ON [dbo].Textt
FOR INSERT, UPDATE AS

    SET NOCOUNT ON;
    DECLARE @ConFieldSETUP nvarchar(50);
    -- Stop recursion for the trigger
    IF TRIGGER_NESTLEVEL(OBJECT_ID('dbo.Tr_ConnectionField')) > 1
        RETURN;
    -- Here i will read the field from configuration which will be used as key
    SET @ConFieldSETUP = (SELECT TOP 1 ISNULL(ConnectionField, 'SNSID') 
                          FROM ConfigurationTable
                          -- ORDER BY ...          
                          );
    -- Update Xfield depending on configuration
    UPDATE w
        SET Xfield = CASE @ConFieldSETUP 
                         WHEN 'SNSID' THEN w.SNSID
                         WHEN 'Name'  THEN w.Name
                         ...
                     END
    FROM Workers w
    JOIN inserted i ON i.Id = w.Id;

【讨论】:

在我将此标记为解决方案之前?这适用于批量插入吗?即Insert into Workers Select .... From AnotherTable ??我只是因为这个原因才使用光标 @ProgramerAnel,您应该将FIRE_TRIGGERS 参数添加到BULK INSERT 命令docs.microsoft.com/en-us/sql/t-sql/statements/… Insert .. select from AnotherTable 是常规插入,前提是 AnotherTable 不是 OPENROWSET(BULK...) 请参阅 docs.microsoft.com/en-us/sql/relational-databases/import-export/… 的 BULK 操作列表 @ProgramerAnel case 表达式返回单个数据类型:“返回 result_expressions可选 else_result_expression 中的类型集中的最高优先级类型我>。”将容纳The Answer 的Xfield 的数据类型是什么?

以上是关于SQL Server 触发器插入/更新特定列的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQL Server 触发器中复制插入、更新、删除的行

sql server 数据库里设置了当插入数据时,便触发器插入更新时间,但我导入数据时,触发器却没有工作。

sql 检测更新触发器中修改的字段(sql server 2005)?

Sql Server 2005 - 插入更新触发器 - 获取更新,插入行

SQL Server 触发器切换插入、删除、更新

如何知道我在 SQL Server 中使用插入触发器的最后日期?