【问题标题】:Trigger to insert NULL values (SQL Server 2012)插入 NULL 值的触发器 (SQL Server 2012)
【发布时间】:2013-12-16 20:51:22
【问题描述】:

几天前,我正在开发一个 MFC 应用程序,它作为我的数据库的客户端。在此应用程序中,在某些情况下,新记录的某些字段可能为空,当我用数据填充某些对象时,这将表示“零”(null)。因此,为了处理这些零值,我试图创建一个触发器,它会自动将这些零值替换为 NULL,因此不会有任何外键冲突。以下是我目前实现的:

use SomeDatabase SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create trigger SomeTrigger
on MyTable
after insert, update
as
begin
declare @Attribute1 int
declare @Attribute2 int
declare @Attribute3 int
declare @Attribute4 int
set @Attribute1 = (select Slot1 from INSERTED)
set @Attribute2 = (select Slot2 from INSERTED)
set @Attribute3 = (select Slot3 from INSERTED)
set @Attribute4 = (select Slot4 from INSERTED)
if (@Attribute1 = 0)
begin TRANSACTION
SET Slot1 NULL
end
if (@Attribute2 = 0)
begin TRANSACTION
SET Slot2 NULL
end
if(@Attribute3 = 0)
begin TRANSACTION
SET Slot3 NULL
end
if (@Attribute4 = 0)
begin TRANSACTION
SET Slot4 NULL
end
end
go

我很确定有比这个更好的方法,但我相信最奇怪的是 SQL Server 只在最后两个“if”和最后一个“end”和“go”处指责错误。有谁知道更好的解决方案?提前致谢!

【问题讨论】:

  • P.S.您的触发器代码表明您将 SQL Server 中的触发器视为单行操作。但是,与其他一些 DBMS(如 Oracle 和 MySQL)不同,触发器不会为每一行运行一次。相反,已插入和已删除元表已修改所有行。那么,您能看到SET @Var = Slot1 FROM Inserted 将如何丢弃多行插入的值吗?当您学习在 SQL Server 中编写触发器时,请牢记这一点。

标签: sql sql-server mfc triggers


【解决方案1】:

1) 如果您可以更改客户端应用程序 (MFC),那么您应该这样做。

2) 如果您使用存储过程来插入或更新行,那么您可以在这些 SP 中进行这些转换。例如:

ALTER STORED PROCEDURE dbo.MyTable_Insert
(
@Slot1 INT,
@Slot2 INT,
@Slot3 INT,
@Slot4 INT
)
AS
BEGIN
SELECT @Slot1 = NULLIF(@Slot1, 0), 
    @Slot2 = NULLIF(@Slot2, 0), 
    @Slot3 = NULLIF(@Slot3, 0), 
    @Slot4 = NULLIF(@Slot4, 0);

INSERT INTO dbo.MyTable (Slot1, Slot2, Slot3, Slot4)
VALUES (@Slot1, @Slot2, @Slot3, @Slot4);
END

3) 如果你不能,那么你可以使用 INSTEAD OF 触发器:

CREATE TRIGGER trgBeforeIU_SomeTrigger
ON dbo.MyTable
INSTEAD OF INSERT, UPDATE
AS
BEGIN
    INSERT INTO dbo.MyTable (Slot1, Slot2, Slot3, Slot4)
    SELECT  NULLIF(Slot1, 0), 
        NULLIF(Slot2, 0),
        NULLIF(Slot3, 0),
        NULLIF(Slot4, 0)
    FROM inserted;
END;

【讨论】:

  • 感谢您的提示!问题:如果我应该更改 MFC 代码,我应该使用 nullptr 还是类似的东西?
  • @Mudkip:我会使用CRecordset::SetFieldNull (ref) 和CRecordset::IsFieldNull (ref) 方法。
  • 大家好——如果您喜欢 cmets/answer,您可以投票给他们,您知道!我讨厌在没有一票的情况下看到所有这些很棒的信息。
猜你喜欢
  • 1970-01-01
  • 2015-04-25
  • 1970-01-01
  • 2013-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多