我有两个相关的表格:
create table readData
(
readDataId int identity primary key,
dp4 varchar(300),
fields....
);
create table calculatedData
(
calculatedDataId int identity primary key,
readDataId int foreign key references readData (readDataId),
fields...
calculated field 1,
calculated field 2,
calculated field 3,
etc..
);
表中的dp4字段如下所示:'138,73,117,112'。
我有一个处理它的存储过程。数据被插入到calculateData表的某些字段中,插入到select中,然后我需要将dp4字段分解为四个变量,进行一些计算并更新calculatedData中的计算字段。 必须为每一行完成此操作。
我写了一个函数来分解dp4字段然后我在触发器中使用它:
CREATE TRIGGER trgAfterInsert ON calculatedData
FOR INSERT
AS
declare @readDataId int;
declare @dp4 varchar(300);
declare @dp0 varchar(300);
declare @dp1 varchar(300);
declare @dp2 varchar(300);
declare @dp3 varchar(300);
declare @dp0Int int;
declare @dp1Int int;
declare @dp2Int int;
declare @dp3Int int;
select @readDataId=i.readDataId from inserted i;
select @dp4=dp4 from readData where readDataId=@readDataId;
select @dp0=dp from dbo.splitstring(@dp4) where id=1;
select @dp1=dp from dbo.splitstring(@dp4) where id=2;
select @dp2=dp from dbo.splitstring(@dp4) where id=3;
select @dp3=dp from dbo.splitstring(@dp4) where id=4;
select @dp0Int=cast(@dp0 as int);
select @dp1Int=cast(@dp1 as int);
select @dp2Int=cast(@dp2 as int);
select @dp3Int=cast(@dp3 as int);
update calculatedData set TotalReads=@dp0Int+@dp1Int+@dp2Int+@dp3Int where readDataId=@readDataId
GO
这只是一个用这个字段计算^^
只有当我运行它时,才意识到触发器不是每一行都发生,而是每个语句。例如,TotalReads字段仅针对一行进行更新。 所以我开始阅读游标但不能写一个来处理我的需求。
我会赞美任何帮助。如果有一种更有效的方法,没有光标,我很想知道。
谢谢!
修改
这是splitString函数:
CREATE FUNCTION dbo.splitstring ( @stringToSplit VARCHAR(MAX) )
RETURNS
@returnList TABLE ([id] [int] identity,[dp] [nvarchar] (500))
AS
BEGIN
DECLARE @name NVARCHAR(255)
DECLARE @pos INT
WHILE CHARINDEX(',', @stringToSplit) > 0
BEGIN
SELECT @pos = CHARINDEX(',', @stringToSplit)
SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1)
INSERT INTO @returnList
SELECT @name
SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)
END
INSERT INTO @returnList
SELECT @stringToSplit
RETURN
END
答案 0 :(得分:0)
你的问题从这里开始:
select @readDataId=i.readDataId from inserted i;
为了提高效率,SQL Server不会在每次插入行时触发触发器。它将为多行触发一次触发器。我从来没有挖得足够深,无法找出阈值是什么,所以我只是假设inserted
表中会有多行。
光标在关系世界中是个坏词。几乎每次你想到使用它,你都做错了。这是基于您的代码的即兴版本:
CREATE TRIGGER trgAfterInsert ON calculatedData
FOR INSERT
AS
DECLARE @tmp TABLE (
readDataID int,
dp int
)
INSERT INTO @tmp (readDataID, dp)
SELECT i.readDataID,
CAST(s.dp AS INT)
FROM inserted i
CROSS APPLY dbo.SplitString(i.dp4) s
UPDATE c
SET c.TotalReads = SUM(tmp.dp)
FROM @tmp tmp
INNER JOIN calculatedData c ON tmp.readDataId = c.readDataID
GO
由于缺乏数据,我还没有测试过这段代码。它应该给你一个指针。如果您需要帮助,请发布一些数据。