如何使用 sp_executesql 在动态 SQL 中将文本值用作变量
How do I use text values as variables in dynamic SQL using sp_executesql
我有以下 table:
CREATE TABLE Wages (EmpID INT, Amount MONEY)
INSERT INTO Wages VALUES (1,25000), (2,30000), (3,35000), (4, 40000)
SELECT * FROM Wages
我想创建一个使用 sp_executesql 的过程,我不仅可以更改 WHERE 子句中的值,还可以更改关系 - 即大于 (>) 或小于 (<)。
假设我有:
SELECT * FROM Wages WHERE EmpID > 2 AND Amount > 30000
或
SELECT * FROM Wages WHERE EmpID <= 2 AND Amount <= 30000
我该如何编码才能传入“<”或“=”而不是“>”来得到这个:
SELECT * FROM Wages WHERE EmpID < 2 AND Amount < 30000
我试过这个:
DECLARE @Amount MONEY
DECLARE @EmpID INT
DECLARE @EmpSYMBOL NVARCHAR(2)
DECLARE @AmountSYMBOL NVARCHAR(2)
DECLARE @SQL2 NVARCHAR(2000) = 'SELECT * FROM Wages WHERE EmpID '+ @EmpSYMBOL+' @EmpID AND Amount '+ @AmountSYMBOL+' @Amount'
EXEC sp_executesql @SQL2, N'@EmpID INT, @Amount MONEY, @EmpSYMBOL NVARCHAR(2), @AmountSYMBOL NVARCHAR(2)',2, 30000,'<','<';
但是尽管它运行没有错误,但没有任何结果
这returns一个错误:
DECLARE @Amount MONEY
DECLARE @EmpID INT
DECLARE @EmpSYMBOL NVARCHAR(2)
DECLARE @AmountSYMBOL NVARCHAR(2)
DECLARE @SQL2 NVARCHAR(2000) = 'SELECT * FROM Wages WHERE EmpID @EmpSYMBOL @EmpID AND Amount @AmountSYMBOL @Amount'
EXEC sp_executesql @SQL2, N'@EmpID INT, @Amount MONEY, @EmpSYMBOL NVARCHAR(2), @AmountSYMBOL NVARCHAR(2)',2, 30000,'<','<';
编辑
鉴于下面的有用答案,我做了以下事情:
CREATE PROC GetWages @EmpSYMBOL NVARCHAR(2), @EmpID INT,@AmountSYMBOL NVARCHAR(2), @Amount MONEY
AS
IF @EmpID IN (1,2,3,4)
AND (@Amount BETWEEN 25000 AND 40000)
AND @EmpSYMBOL IN('>','<','<>','!=','=', '<=','>=')
AND @AmountSYMBOL IN('>','<','<>','!=','=', '<=','>=')
BEGIN
DECLARE @SQL NVARCHAR(200)='
SELECT * FROM Wages WHERE Amount '+@AmountSYMBOL+' @Amount AND EmpiD '+@EmpSYMBOL+' @EmpID'
EXEC sp_executesql @SQl , N'@Amount MONEY ,@EmpID INT',@Amount, @EmpID
END
ELSE
PRINT 'Input variable(s) out of range'
鉴于我正在做我自己的输入值参数检查,我想我也可以这样做:
ALTER PROC GetWages @EmpSYMBOL NVARCHAR(2), @EmpID INT,@AmountSYMBOL NVARCHAR(2), @Amount MONEY
AS
IF @EmpID IN (1,2,3,4)
AND (@Amount BETWEEN 25000 AND 40000)
AND @EmpSYMBOL IN('>','<','<>','!=','=', '<=','>=')
AND @AmountSYMBOL IN('>','<','<>','!=','=', '<=','>=')
BEGIN
DECLARE @SQL NVARCHAR(200)='
SELECT * FROM Wages WHERE Amount '+@AmountSYMBOL
+' '+CAST(@Amount AS NVARCHAR(8))+' AND EmpiD '
+@EmpSYMBOL+' '+CAST(@EmpID AS NVARCHAR(1))
EXEC sp_executesql @SQl
END
ELSE
PRINT 'Input variable(s) out of range'
试试这样的东西......
DECLARE @Amount MONEY
, @EmpID INT
, @EmpSYMBOL NVARCHAR(2) = '<'
, @AmountSYMBOL NVARCHAR(2) = '<'
, @SQL2 NVARCHAR(MAX);
SET @SQL2 = N' SELECT * FROM Wages '
+ N' WHERE EmpID ' + @EmpSYMBOL + ' @EmpID
AND Amount ' + @AmountSYMBOL + ' @Amount'
EXEC sp_executesql @SQL2
, N'@EmpID INT, @Amount MONEY'
, @EmpID = 2
, @Amount =30000
重要提示
没有一种安全的方法可以在不经历很多麻烦的情况下接受比较运算符作为参数。上面的例子很容易出现SQL-Injection。
我有以下 table:
CREATE TABLE Wages (EmpID INT, Amount MONEY)
INSERT INTO Wages VALUES (1,25000), (2,30000), (3,35000), (4, 40000)
SELECT * FROM Wages
我想创建一个使用 sp_executesql 的过程,我不仅可以更改 WHERE 子句中的值,还可以更改关系 - 即大于 (>) 或小于 (<)。
假设我有:
SELECT * FROM Wages WHERE EmpID > 2 AND Amount > 30000
或
SELECT * FROM Wages WHERE EmpID <= 2 AND Amount <= 30000
我该如何编码才能传入“<”或“=”而不是“>”来得到这个:
SELECT * FROM Wages WHERE EmpID < 2 AND Amount < 30000
我试过这个:
DECLARE @Amount MONEY
DECLARE @EmpID INT
DECLARE @EmpSYMBOL NVARCHAR(2)
DECLARE @AmountSYMBOL NVARCHAR(2)
DECLARE @SQL2 NVARCHAR(2000) = 'SELECT * FROM Wages WHERE EmpID '+ @EmpSYMBOL+' @EmpID AND Amount '+ @AmountSYMBOL+' @Amount'
EXEC sp_executesql @SQL2, N'@EmpID INT, @Amount MONEY, @EmpSYMBOL NVARCHAR(2), @AmountSYMBOL NVARCHAR(2)',2, 30000,'<','<';
但是尽管它运行没有错误,但没有任何结果
这returns一个错误:
DECLARE @Amount MONEY
DECLARE @EmpID INT
DECLARE @EmpSYMBOL NVARCHAR(2)
DECLARE @AmountSYMBOL NVARCHAR(2)
DECLARE @SQL2 NVARCHAR(2000) = 'SELECT * FROM Wages WHERE EmpID @EmpSYMBOL @EmpID AND Amount @AmountSYMBOL @Amount'
EXEC sp_executesql @SQL2, N'@EmpID INT, @Amount MONEY, @EmpSYMBOL NVARCHAR(2), @AmountSYMBOL NVARCHAR(2)',2, 30000,'<','<';
编辑 鉴于下面的有用答案,我做了以下事情:
CREATE PROC GetWages @EmpSYMBOL NVARCHAR(2), @EmpID INT,@AmountSYMBOL NVARCHAR(2), @Amount MONEY
AS
IF @EmpID IN (1,2,3,4)
AND (@Amount BETWEEN 25000 AND 40000)
AND @EmpSYMBOL IN('>','<','<>','!=','=', '<=','>=')
AND @AmountSYMBOL IN('>','<','<>','!=','=', '<=','>=')
BEGIN
DECLARE @SQL NVARCHAR(200)='
SELECT * FROM Wages WHERE Amount '+@AmountSYMBOL+' @Amount AND EmpiD '+@EmpSYMBOL+' @EmpID'
EXEC sp_executesql @SQl , N'@Amount MONEY ,@EmpID INT',@Amount, @EmpID
END
ELSE
PRINT 'Input variable(s) out of range'
鉴于我正在做我自己的输入值参数检查,我想我也可以这样做:
ALTER PROC GetWages @EmpSYMBOL NVARCHAR(2), @EmpID INT,@AmountSYMBOL NVARCHAR(2), @Amount MONEY
AS
IF @EmpID IN (1,2,3,4)
AND (@Amount BETWEEN 25000 AND 40000)
AND @EmpSYMBOL IN('>','<','<>','!=','=', '<=','>=')
AND @AmountSYMBOL IN('>','<','<>','!=','=', '<=','>=')
BEGIN
DECLARE @SQL NVARCHAR(200)='
SELECT * FROM Wages WHERE Amount '+@AmountSYMBOL
+' '+CAST(@Amount AS NVARCHAR(8))+' AND EmpiD '
+@EmpSYMBOL+' '+CAST(@EmpID AS NVARCHAR(1))
EXEC sp_executesql @SQl
END
ELSE
PRINT 'Input variable(s) out of range'
试试这样的东西......
DECLARE @Amount MONEY
, @EmpID INT
, @EmpSYMBOL NVARCHAR(2) = '<'
, @AmountSYMBOL NVARCHAR(2) = '<'
, @SQL2 NVARCHAR(MAX);
SET @SQL2 = N' SELECT * FROM Wages '
+ N' WHERE EmpID ' + @EmpSYMBOL + ' @EmpID
AND Amount ' + @AmountSYMBOL + ' @Amount'
EXEC sp_executesql @SQL2
, N'@EmpID INT, @Amount MONEY'
, @EmpID = 2
, @Amount =30000
重要提示
没有一种安全的方法可以在不经历很多麻烦的情况下接受比较运算符作为参数。上面的例子很容易出现SQL-Injection。