如何在存储过程中创建过滤索引(SQL Server)
我试图使用存储过程创建一个已过滤索引。但是,当代码写入存储过程时没有错误显示,但是当我运行查询时,它无法检测到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
的问题是,你没有'在SQL字符串左右,但如果使用sp_execute_sql你应该实际上只是在SQL中使用@FirstName变量并分别为参数添加值。请参阅示例:https://msdn.microsoft.com/en-us/library/ms188001.aspx
您有几个错误。这是你将用当前的声明得到的。
SELECT dbo.Details.ID
FROM dbo.Details
INNER JOIN dbo.Personal
ON dbo.Personal.ID = Details.ID
WHERE Number =17522AND Name = Simon
如果您在执行查询之前添加PRINT @SQL
,您可以看到它。
- 添加空间之前,并在
'AND Name ='
- 添加额外的报价轮命名
虽然第一是不是一个语法错误,但糟糕的格式化第二个实际上是一个错误,因为这将是认为专栏不是价值'西蒙'。 试试这个:
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 + ''''
@Allan,正确 – 2015-03-02 12:39:40
危险。 SQL注入。 – 2015-03-03 19:32:22
尽管现有的答案(如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注入攻击。
为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,'''')
危险。 SQL注入。 – 2015-03-03 19:32:29
请解释你的答案? – 2015-03-03 19:39:09
咦?我没有答案,因为[艾伦已经给了一个更好的](http://stackoverflow.com/a/28810191/61305)。 – 2015-03-03 19:42:34
这似乎并不具有任何与创建过滤索引... – 2015-03-02 12:26:15
有一些理由使用动态SQL,这不是在这个问题吗?因为这是您应该使用静态SQL的场景的主要示例。正如所写的,这个过程是一个等待发生的SQL注入攻击。 – Allan 2015-03-02 12:28:53
如果您提出包含代码的问题:请不要更改代码,否则答案将无效。 (你只是试着编辑一个答案,所以这段代码适用于你的新问题,这不是这样做的,只是不要改变你的问题!) – knedlsepp 2015-03-02 14:39:53