SQL 服务器:函数在触发器中不起作用
SQL Server : function not working in trigger
我有这样的插入触发器:
ALTER TRIGGER [dbo].[trTblNameSetRefNo]
ON [dbo].[TblName]
AFTER INSERT
AS BEGIN
UPDATE TblName
SET RefNumber = dbo.GetNextRefNo(i.SomeField)
FROM TblName
INNER JOIN inserted i on i.ID = TblName.ID
END
但是没用。当我 'hardcode' 字段 RefNumber 时,例如:SET RefNumber = 'test'
,它工作正常。
此外,当我在触发器外部调用函数时,它 return 正确的结果。
这是我的函数,在触发器中必须 return 值:
ALTER FUNCTION [dbo].[GetNextRefNo]
(@ValueField INT)
RETURNS NVARCHAR(250)
AS
BEGIN
DECLARE @lastId INT;
DECLARE @result NVARCHAR(25);
DECLARE @CurrentIdentifier NVARCHAR(25);
SELECT TOP 1
@lastId = CAST(Substring(RefNumber, Charindex('-', RefNumber) + 4, Len(RefNumber )) AS INT) + 1
FROM
TblName
ORDER BY
ID DESC
IF @@ROWCOUNT < 1 --if empty table , set start number
BEGIN
SET @lastId = 1000
END
SELECT @CurrentIdentifier = 'SIT'
SET @result = @CurrentIdentifier + '-' + Substring ( Cast(Year(Getdate()) AS NVARCHAR), 3, 2) + '-' + Cast(@lastId AS NVARCHAR)
RETURN @result
END
知道我做错了什么吗?
你的函数 returns 当 RefNumber = '' 时可能是一个不正确的结果,当 RefNumber = NULL 时它 returns NULL,就像新插入的记录一样。
上面代码的设计太糟糕了。
建议的方法:
使用 ID 字段作为计数器并根据它生成 RefNumber,同时根据需要连接 Year。
示例函数:
ALTER FUNCTION [dbo].[GetNextRefNo] (@ID INT)
returns NVARCHAR(250)
AS
BEGIN
DECLARE @lastId INT;
DECLARE @result NVARCHAR(25);
DECLARE @CurrentIdentifier NVARCHAR(25);
SELECT @CurrentIdentifier = 'SIT'
SET @ID = @ID + 1000
SET @result = @CurrentIdentifier + '-' + Substring ( Cast(Year(Getdate()) AS NVARCHAR), 3, 2) + '-' + Cast(@ID AS NVARCHAR)
RETURN @result
END
示例触发器:
ALTER TRIGGER [dbo].[trTblNameSetRefNo] ON [dbo].[TblName]
AFTER INSERT AS BEGIN
UPDATE TblName
SET RefNumber = dbo.GetNextRefNo(i.ID)
FROM TblName
INNER JOIN inserted i on i.ID = TblName.ID
END
或者创建另一个 table 来保存当前的 RefNumber 种子。
我有这样的插入触发器:
ALTER TRIGGER [dbo].[trTblNameSetRefNo]
ON [dbo].[TblName]
AFTER INSERT
AS BEGIN
UPDATE TblName
SET RefNumber = dbo.GetNextRefNo(i.SomeField)
FROM TblName
INNER JOIN inserted i on i.ID = TblName.ID
END
但是没用。当我 'hardcode' 字段 RefNumber 时,例如:SET RefNumber = 'test'
,它工作正常。
此外,当我在触发器外部调用函数时,它 return 正确的结果。
这是我的函数,在触发器中必须 return 值:
ALTER FUNCTION [dbo].[GetNextRefNo]
(@ValueField INT)
RETURNS NVARCHAR(250)
AS
BEGIN
DECLARE @lastId INT;
DECLARE @result NVARCHAR(25);
DECLARE @CurrentIdentifier NVARCHAR(25);
SELECT TOP 1
@lastId = CAST(Substring(RefNumber, Charindex('-', RefNumber) + 4, Len(RefNumber )) AS INT) + 1
FROM
TblName
ORDER BY
ID DESC
IF @@ROWCOUNT < 1 --if empty table , set start number
BEGIN
SET @lastId = 1000
END
SELECT @CurrentIdentifier = 'SIT'
SET @result = @CurrentIdentifier + '-' + Substring ( Cast(Year(Getdate()) AS NVARCHAR), 3, 2) + '-' + Cast(@lastId AS NVARCHAR)
RETURN @result
END
知道我做错了什么吗?
你的函数 returns 当 RefNumber = '' 时可能是一个不正确的结果,当 RefNumber = NULL 时它 returns NULL,就像新插入的记录一样。
上面代码的设计太糟糕了。
建议的方法:
使用 ID 字段作为计数器并根据它生成 RefNumber,同时根据需要连接 Year。
示例函数:
ALTER FUNCTION [dbo].[GetNextRefNo] (@ID INT)
returns NVARCHAR(250)
AS
BEGIN
DECLARE @lastId INT;
DECLARE @result NVARCHAR(25);
DECLARE @CurrentIdentifier NVARCHAR(25);
SELECT @CurrentIdentifier = 'SIT'
SET @ID = @ID + 1000
SET @result = @CurrentIdentifier + '-' + Substring ( Cast(Year(Getdate()) AS NVARCHAR), 3, 2) + '-' + Cast(@ID AS NVARCHAR)
RETURN @result
END
示例触发器:
ALTER TRIGGER [dbo].[trTblNameSetRefNo] ON [dbo].[TblName]
AFTER INSERT AS BEGIN
UPDATE TblName
SET RefNumber = dbo.GetNextRefNo(i.ID)
FROM TblName
INNER JOIN inserted i on i.ID = TblName.ID
END
或者创建另一个 table 来保存当前的 RefNumber 种子。