2015-03-02 156 views
-5

我試圖使用存儲過程創建一個已過濾索引。但是,當代碼寫入存儲過程時沒有錯誤顯示,但是當我運行查詢時,它無法檢測到FirstName參數。如何在存儲過程中創建過濾索引(SQL Server)

名字從BorrowerPersonal表

CardNumber從BorrowerCard表

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
ALTER PROCEDURE [dbo].[BorrowerCardG11Match] 

@CardNo VARCHAR(20), 
@FirstName VARCHAR(30) 

AS 
BEGIN 
DECLARE @SQL NVARCHAR(Max) 
SET @CardNo = 17522 
SET @FirstName = 'Simon' 

     SET @SQL = N'SELECT dbo.BorrowerCard.BorrowerCardID 
      FROM dbo.BorrowerCard 
      INNER JOIN dbo.BorrowerPersonal 
      ON dbo.BorrowerPersonal.BorrowerPersonalID = BorrowerCard.BorrowerPersonalID 
      WHERE CardNumber =' + CAST(@CardNo AS VARCHAR(20)) 
      SET @SQL += 'AND NameFirst = ' + CAST(@FirstName AS VARCHAR(30)) 

        EXECUTE sys.sp_executesql @SQL 
END 
+3

這似乎並不具有任何與創建過濾索引... – 2015-03-02 12:26:15

+2

有一些理由使用動態SQL,這不是在這個問題嗎?因爲這是您應該使用靜態SQL的場景的主要示例。正如所寫的,這個過程是一個等待發生的SQL注入攻擊。 – Allan 2015-03-02 12:28:53

+0

如果您提出包含代碼的問題:請不要更改代碼,否則答案將無效。 (你只是試着編輯一個答案,所以這段代碼適用於你的新問題,這不是這樣做的,只是不要改變你的問題!) – knedlsepp 2015-03-02 14:39:53

回答

-1

您有幾個錯誤。這是你將用當前的聲明得到的。

SELECT dbo.Details.ID 
      FROM dbo.Details 
      INNER JOIN dbo.Personal 
      ON dbo.Personal.ID = Details.ID 
      WHERE Number =17522AND Name = Simon 

如果您在執行查詢之前添加PRINT @SQL,您可以看到它。

  1. 添加空間之前,並在'AND Name ='
  2. 添加額外的報價輪命名

雖然第一是不是一個語法錯誤,但糟糕的格式化第二個實際上是一個錯誤,因爲這將是認爲專欄不是價值'西蒙'。 試試這個:

SET @SQL = N'SELECT dbo.Details.ID 
     FROM dbo.Details 
     INNER JOIN dbo.Personal 
     ON dbo.Personal.ID = Details.ID 
     WHERE Number =' + '''' + @No + '''' + 
       ' AND Name = N' + '''' + @First + '''' 
+0

@Allan,正確 – 2015-03-02 12:39:40

+1

危險。 SQL注入。 – 2015-03-03 19:32:22

2

儘管現有的答案(如Giorgi的Nakeuri的)顯示,使動態SQL的工作方式,如規定的問題,沒有理由使用動態SQL擺在首位。除非有更多的這個程序不是已經提交,解決這個問題的最好的辦法是使用靜態SQL它重新寫:

ALTER PROCEDURE [dbo].[BorrowerCardG11Match] 

@No VARCHAR(20), 
@First VARCHAR(30) 

AS 
BEGIN 
SET @No = 17522 
SET @First = 'Simon' 

      SELECT dbo.Details.ID 
      FROM dbo.Details 
      INNER JOIN dbo.Personal 
      ON dbo.Personal.ID 
       = Details.ID 
      WHERE Number = @No 
       AND First = @Name 

END 

如果你不能做到這一點,你會更好的結合這兩個變量你有,而不是它們串聯:

ALTER PROCEDURE [dbo].[BorrowerCardG11Match] 

@No VARCHAR(20), 
@Name VARCHAR(30) 

AS 
BEGIN 
DECLARE @SQL NVARCHAR(Max) 
DECLARE @SQLParams NVARCHAR(Max) 
SET @No = 17522 
SET @First = 'Simon' 

     SET @SQL = N'SELECT dbo.Details.ID 
      FROM dbo.Details 
      INNER JOIN dbo.Personal 
      ON dbo.Personal.ID 
       = Details.ID 
      WHERE Number = @No 
       AND Name = @First' 
     SET @SQLParams = N'@No varchar(20), @First varchar(30)' 

     EXECUTE sys.sp_executesql @SQL, SQLParams, 
            @[email protected], @[email protected] 
END 

這些解決方案阻止你不必置單引號和防止SQL注入攻擊。

-1

sql server 2012可以使用concat -

set @SQL = concat('SELECT dbo.Details.ID 
      FROM dbo.Details 
      INNER JOIN dbo.Personal 
      ON dbo.Personal.ID 
       = Details.ID 
      WHERE Number =''' ,@No,'''',' AND Name = ''',@First,'''') 
+0

危險。 SQL注入。 – 2015-03-03 19:32:29

+0

請解釋你的答案? – 2015-03-03 19:39:09

+0

咦?我沒有答案,因爲[艾倫已經給了一個更好的](http://stackoverflow.com/a/28810191/61305)。 – 2015-03-03 19:42:34

相關問題