插入时的SQL触发器以调用函数和操作值

时间:2015-06-18 11:47:29

标签: sql sql-server

我知道在插入时设置触发器以调用函数并将标识符SiteID传递给该函数然后对另一个表中的变量进行操作时出现问题。

我有表格,其中插入了值:

CREATE TABLE [dbo].[Tests] (
   [Id]     INT       IDENTITY (1, 1) NOT NULL,
   [SiteID] NVARCHAR (128) NOT NULL,
   [Date]   NVARCHAR (MAX) NULL,
   [Time]   NVARCHAR (MAX) NULL,
   [Tub]    NVARCHAR (MAX) NULL,
   [FCl]    FLOAT (53)     NOT NULL
   PRIMARY KEY CLUSTERED ([Id] ASC)
);

每次将值插入Tests表时,我希望调用一个函数,使用表Review执行简单计算(请参阅下面帖子中的触发器):

CREATE TABLE [dbo].[Review] (
   [SiteID] NVARCHAR (128) NOT NULL,
   [TubNum] INT NOT NULL,
   [Supplied]  INT  NULL,
   [Performed] INT  NULL,
   [Remaining] INT  NULL 
   PRIMARY KEY CLUSTERED ([SiteID] ASC)
);

到目前为止,这是我的sqlfiddle,但是,我无法使用我正在处理的函数保存它,它们位于:

触发器 - 不确定如何传递插入的SiteID或调用函数:

CREATE TRIGGER [dbo].[TRIG_MyTable]
ON [dbo].[Tests]
AFTER INSERT
 AS
   CALL CalcRemaining() //how to pass it SiteID?

和函数本身:

CREATE FUNCTION [dbo].[CalcRemaining](@ID NVARCHAR (128))
RETURNS NULL
AS
BEGIN
   SELECT (Supplied, Performed FROM Review WHERE SiteID = ID);
   Performed = Performed + 1;
   INSERT INTO Review (Performed, Remaining) VALUES (Performed, (Supplied-Performed))
RETURN;
END

这个想法是,插入行中的SiteID在被调用时传递给函数,然后selects函数SuppliedPerformed用于匹配{来自SiteID表的{1}}。 Review值增加1,并删除新值以及检索到的Performed值,并将其写入Supplied表中的Remaining字段。

2 个答案:

答案 0 :(得分:2)

如果我在评论中询问的假设是有效的(可以始终计算RemainingPerformed),这就是我如何实现数据库结构,没有触发器或函数:

基础表:

CREATE TABLE dbo.Tests (
   [Id]     INT       IDENTITY (1, 1) NOT NULL,
   [SiteID] NVARCHAR (128) NOT NULL,
   [Date]   NVARCHAR (MAX) NULL,
   [Time]   NVARCHAR (MAX) NULL,
   [Tub]    NVARCHAR (MAX) NULL,
   [FCl]    FLOAT (53)     NOT NULL
   PRIMARY KEY CLUSTERED ([Id] ASC)
);
GO
CREATE TABLE dbo._Review (
   [SiteID] NVARCHAR (128) NOT NULL,
   [TubNum] INT NOT NULL,
   [Supplied]  INT  NULL,
   PRIMARY KEY CLUSTERED ([SiteID] ASC)
);

然后是一个计算Performed的视图:

CREATE VIEW dbo._Tests_Count
WITH SCHEMABINDING
AS
    SELECT
        SiteID,
        COUNT_BIG(*) as Performed
    FROM
        dbo.Tests t
    GROUP BY SiteID
GO
CREATE UNIQUE CLUSTERED INDEX IX_Tests_Count ON dbo._Tests_Count (SiteID)

最后是一个重新创建原始Review表的视图:

CREATE VIEW dbo.Review
WITH SCHEMABINDING
AS
    SELECT
        r.SiteID,
        r.TubNum,
        r.Supplied,
        COALESCE(tc.Performed,0) as Performed,
        r.Supplied - COALESCE(tc.Performed,0) as Remaining
    FROM
        dbo._Review r
            left join
        dbo._Tests_Count tc WITH (NOEXPAND)
            on
                r.SiteID = tc.SiteID
GO

如果需要,此时可以在此Review视图上创建触发器,以允许对其执行任何INSERTDELETEUPDATE s而不是_Review,如果你不能改变一些调用代码。

答案 1 :(得分:-1)

你必须完全确定你一次只操作一行!

CREATE TRIGGER [dbo].[TRIG_MyTable]
ON [dbo].[Tests]
AFTER INSERT
 AS
DECLARE @SiteID NVARCHAR (128)
SELECT @SiteID = ID FROM inserted
   CALL CalcRemaining(@SiteID)