如何在存储过程中创建过滤索引(SQL Server)

时间:2015-03-02 12:21:54

标签: sql-server stored-procedures

我尝试使用存储过程创建过滤索引。但是,在存储过程中编写代码时没有显示错误,但是当我运行查询时,它无法检测到FirstName参数。

BorrowerPersonal表中的FirstName

BorrowerCard表中的CardNumber

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

4 个答案:

答案 0 :(得分:4)

问题是你没有''在SQL中的字符串周围,但是如果使用sp_execute_sql,实际上应该只使用SQL中的@FirstName变量并单独添加参数的值。请参阅示例:https://msdn.microsoft.com/en-us/library/ms188001.aspx

答案 1 :(得分:2)

虽然现有的答案(例如Giorgi Nakeuri' s)显示了使动态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, 
                                  @No=@No, @Name=@Name   
END

这些解决方案可以防止您必须连接单引号并防止SQL注入攻击。

答案 2 :(得分:-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. 之前的AND之前添加空格
  3. 在名称
  4. 周围添加其他引号

    虽然第一个不是语法错误但是格式错误第二个实际上是错误,因为在这里它将被视为列而不是值'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 = N' + '''' + @First + ''''
    

答案 3 :(得分:-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,'''')