I have three tables:
RawValuesthat contains Timestamp, Part, PartNumber,ValueKind, ... , ValueMeasurementsthat contains TimeStamp, ID, Value.Hashtablethat contains ID, Part, ValueKind, ...
I have a stream of data that come into RawValue that I cannot modify. It contains all the columns except the ID.
I want to create a trigger on RawValues that insert the values into Hashtable (if they do not yet exist), select the id from Hashtable and then insert the row into Measurements.
This is what I've created:
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
The trigger works correctly but sometime in the stream comes rows in groups, then in this case not all the rows are considered. What can I do? Maybe use a for loop and then access to the arrays? How to do it?
INSERTstatements affects 25 rows, you'll get the trigger fired once, but thenInsertedwill contain 25 rows. You cannot just simply do aSELECT .... FROM Inserted- you'll get only one arbitrary row and ignore all others - typically not what you want to do. You need to completely rewrite your trigger in a set-based fashion