【发布时间】:2016-02-24 10:14:51
【问题描述】:
我有三张桌子:
-
RawValues包含 Timestamp、Part、PartNumber、ValueKind、...、Value -
Measurements,包含时间戳、ID、值。 -
Hashtable包含 ID、Part、ValueKind、...
我有一个无法修改的数据流进入RawValue。它包含除 ID 之外的所有列。
我想在RawValues 上创建一个触发器,将值插入Hashtable(如果它们尚不存在),从Hashtable 中选择ID,然后将行插入Measurements。
这是我创建的:
CREATE TRIGGER [dbo].[TrigInsertToMeasurements]
ON [dbo].[MeasurementsTemp]
FOR INSERT
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
-- Dichiaro le variaibili --
DECLARE
@TimeStamp datetime,
@MachineType char(10),
@MachineModel char(10),
@MachineNumber int,
@Part char(10),
@PartNumber int,
@ValueKind char(10),
@Value float,
@ID int
-- Assegno i valori --
SELECT
@TimeStamp = TimeStamp,
@MachineType = MachineType,
@MachineModel = MachineModel,
@MachineNumber = MachineNumber,
@Part = Part,
@PartNumber = PartNumber,
@ValueKind = ValueKind,
@Value = Value
FROM
inserted
SELECT @ID=ID FROM [dbo].[Hashtable]
WHERE
@MachineType = [MachineType] AND
@MachineModel = [MachineModel] AND
@MachineNumber = MachineNumber AND
@Part = Part AND
@PartNumber = PartNumber AND
@ValueKind = ValueKind
IF count(@ID) = count(@TimeStamp)
BEGIN
INSERT INTO [dbo].[Measurements] ([TimeStamp], [ID], [Value] ) VALUES (@TimeStamp, @ID, @Value)
END
ELSE BEGIN
BEGIN
IF NOT EXISTS (SELECT [ID] FROM [dbo].[Hashtable] WHERE
@MachineType = [MachineType] AND
@MachineModel = [MachineModel] AND
@MachineNumber = MachineNumber AND
@Part = Part AND
@PartNumber = PartNumber AND
@ValueKind = ValueKind)
BEGIN
INSERT INTO [dbo].[Hashtable] (MachineType, MachineModel, MachineNumber, Part, PartNumber, ValueKind)
VALUES (@MachineType, @MachineModel, @MachineNumber, @Part, @PartNumber, @ValueKind)
END
END
SELECT @ID=ID FROM [dbo].[Hashtable]
WHERE
@MachineType = MachineType AND
@MachineModel = MachineModel AND
@MachineNumber = MachineNumber AND
@Part = Part AND
@PartNumber = PartNumber AND
@ValueKind = ValueKind
INSERT INTO [dbo].[Measurements] ([TimeStamp], [ID], [Value] ) VALUES (@TimeStamp, @ID, @Value)
END
END
GO
ALTER TABLE [dbo].[MeasurementsTemp] ENABLE TRIGGER [TrigInsertToMeasurements]
GO
触发器正常工作,但有时在流中成组出现行,那么在这种情况下,不会考虑所有行。 我能做些什么?也许使用 for 循环然后访问数组?怎么做?
【问题讨论】:
-
您的触发器概念是错误的。触发器不会针对每条记录发生。 INSERTED 可能包含多于 1 行。您需要在触发器中处理它
-
您的触发器有 MAJOR 缺陷,因为您似乎认为它会每行调用一次 - 那是不是 b> 情况。触发器将每条语句触发一次,因此如果您的
INSERT语句影响 25 行,您将触发触发器 一次,但随后Inserted将包含 25行。你不能简单地做一个SELECT .... FROM Inserted- 你只会得到一个任意的行并且忽略所有其他 - 通常不是你想要做的。您需要以基于集合的方式完全重写您的触发器
标签: sql sql-server tsql triggers