我在比较TSQL中的两个变量时遇到了一些问题。
这是代码
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sspUpdateActivityDate] (
@e nvarchar(15),
@i nvarchar(11),
@c nvarchar(50),
@u nvarchar(50)
)
AS
BEGIN
DECLARE @var_Count int
DECLARE @var_RecordLimit int
SET @var_RecordLimit = 20
SELECT @var_Count = COUNT(*) FROM tblLastAccess WHERE employeeID = @e
IF @var_Count > @var_RecordLimit
BEGIN
DELETE FROM tblLastAccess
WHERE lastDate NOT IN (
SELECT TOP @var_RecordLimit lastDate
FROM tblLastAccess
WHERE employeeID = @e
ORDER BY lastDate DESC
)
END
INSERT INTO tblLastAccess(employeeID, ip, computerName, username) VALUES (@e, @i, @c, @u)
END
错误说
Msg 102,Level 15,State 1,Procedure sspUpdateActivityDate,Line 19
附近的语法不正确
' @ var_RecordLimit'。
在@var_Count和@var_RecordLimit之间进行比较之后的哪些点(根据我的理解)
想法是添加记录但动态限制记录计数,我最初设置为20. IF中的代码块是删除 TOP n 旁边的记录强>价值。
我顺便使用SQL Server 2000。
请指导我。
这是为了更新目的,这就是为什么我使用ALTER而不是CREATE
答案 0 :(得分:2)
您不能以这种方式在TOP
子句中使用变量;你必须在那里使用一个常数值。您通常会使用动态SQL来执行此类操作,其中查询依赖于示例中的变量值。所以,你可以这样做:
DECLARE @SQL NVARCHAR(1000)
SET @SQL = 'DELETE FROM tblLastAccess WHERE lastDate NOT IN ('
+'SELECT TOP'
+ cast(@var_RecordLimit as varchar)
+ ' lastDate FROM tblLastAccess WHERE employeeID = @empID ORDER BY lastDate DESC)'
EXECUTE sp_executesql @SQL, N'@empID nvarchar(15)', @e
请注意,由于@e
是一个输入参数,它会打开SQL注入的动态查询,因此我们将其替换为动态查询中的另一个参数@empID
,然后传递实际值执行它。
答案 1 :(得分:2)
只需将变量括在括号中即可正常工作
SELECT TOP (@var_RecordLimit) lastDate
FROM tblLastAccess
WHERE employeeID = @e
ORDER BY lastDate DESC