2016-07-05 4 views
0

を使用して、動的SQLにおける変数としてテキスト値を使用してください:は、どのように私は次の表を持ってsp_executesqlを

CREATE TABLE Wages (EmpID INT, Amount MONEY) 
INSERT INTO Wages VALUES (1,25000), (2,30000), (3,35000), (4, 40000) 

SELECT * FROM Wages 

私はWHERE内の値だけではなく、私は変更することができますsp_executesqlをを使用してプロシージャを作成したいです関係よりも大きい(>)か(<)より小さい。

私が持っていたとしましょう:

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,'<','<'; 

EDIT

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 '[email protected]+' @Amount AND EmpiD '[email protected]+' @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 '[email protected] 
+' '+CAST(@Amount AS NVARCHAR(8))+' AND EmpiD ' 
[email protected]+' '+CAST(@EmpID AS NVARCHAR(1)) 

EXEC sp_executesql @SQl 
END 
ELSE 
PRINT 'Input variable(s) out of range' 
+0

もう2番目は間違いです。このように比較をパラメータ化することはできません。 SQL文字列がnullであるため、最初の文字列は機能しません。シンボル変数に値がないため、NULL値を連結しました。比較引数を渡す必要はなく、exec呼び出しの前にSQL文字列を作成するだけです。 – shawnt00

+0

ええ、私はちょっとうまく動作しないことを知っていた。 – SteelyDanFan

答えて

1

はこのような何か.....

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インジェクションを受けやすい例です。

+0

ありがとうとコメントが記されています - それが理由だったのだろうかと思いました。この特定の手順に関連して、それ以外のものは使用できますが、<,>または=(または任意の2つを組み合わせたもの)は使用できますか? – SteelyDanFan

+1

上記の例で行ったように、sqlにパラメータを直接連結しないでください。いくつかのチェックを追加してSQLに連結してから、悪意のあるユーザーがSQLインジェクションを追加した場合にチェックがキャッチされますSQLは決して実行されません。パラメータを 'navarchar(2)'だけにして良い選択をしました。 –

+0

それを見て、私の編集 – SteelyDanFan

関連する問題