变量无效

时间:2016-01-05 12:40:57

标签: sql sql-server sql-server-2012

此存储过程一直有效,直到我添加变量。 @sWHERE变量将从固定输入填充。

我不确定我需要修改什么......我试过添加&和+

  

错误: 4145,级别15,状态1,过程spUniqueUPRN,第12行在上下文中指定的非布尔类型的表达式   条件是预期的,靠近'集团'。

存储过程:

USE [DB]
GO 
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO 
ALTER PROCEDURE [dbo].[spUniqueUPRN]    
@sWHERE varchar(Max) 
AS
BEGIN   
SET NOCOUNT ON;   
SELECT  DISTINCT UPRN INTO TBLTEMP FROM TblA
WHERE  @sWHERE
Group BY UPRN
UNION ALL
SELECT  UPRN FROM TblP
Group BY UPRN 
END

版本2基于迄今为止的帮助(没有最近的结果只是一步)

USE [DB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[spUniqueUPRN]    
@sWHERE varchar(Max) 
AS
BEGIN   
SET NOCOUNT ON; 
---------- 
DROP TABLE TBLTEMP

DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = 'UPRN INTO TBLTEMP FROM TblA ' + QUOTENAME(@sWHERE) + '
Group BY UPRN
UNION ALL
SELECT  UPRN FROM TblP
Group BY UPRN 
';
EXEC sp_executesql @SQL;
---------- 
END 

Verion 3

USE [DB]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
ALTER PROCEDURE [dbo].[spUniqueUPRN]    
@sDateFrom Date,
@sDateTo Date,
@sUPRN varchar(Max),
@sRiskRating varchar(10),
@sSurveyCompany varchar(Max),
@sPostcode varchar(10),
@sStreet varchar(Max),
@sRegion Int

AS
BEGIN   
SET NOCOUNT ON; 
---------- 
DROP TABLE TBLTEMP

DECLARE @SQL NVARCHAR(MAX)

SELECT @SQL = 'SELECT UPRN INTO TBLTEMP FROM TblA WHERE 1 = 1 ' 
IF QUOTENAME(@sDateFrom) IS NOT NULL AND QUOTENAME(@sDateTo) IS NOT NULL
    SELECT @SQL = @SQL + ' or SurveyDate BETWEEN ' +  QUOTENAME(@sDateFrom) + ' AND ' + QUOTENAME(@sDateTo) + ''''

IF QUOTENAME(@sRiskRating) IS NOT NULL 
  SELECT @SQL = @SQL + ' or OverAllRiskCategory = ' + QUOTENAME(@sRiskRating)    +''''

IF QUOTENAME(@sUPRN) IS NOT NULL 
  SELECT @SQL = @SQL + ' or UPRN LIKE ' + QUOTENAME(@sUPRN) + ''''

IF QUOTENAME(@sSurveyCompany) IS NOT NULL 
  SELECT @SQL = @SQL + ' or SurveyCompany LIKE ''%' +  QUOTENAME(@sSurveyCompany)  + '%'''

SELECT @SQL = @SQL + ' GROUP BY UPRN '
SELECT @SQL = @SQL + ' UNION ALL '


SELECT  UPRN FROM TblProperty
 IF QUOTENAME(@sPostcode) IS NOT NULL 
  SELECT @SQL = @SQL + ' or Postcode  LIKE ''%' +   QUOTENAME(@sPostcode)  + '%'''

IF QUOTENAME(@sStreet) IS NOT NULL 
  SELECT @SQL = @SQL + ' or Street  LIKE ''%' +  QUOTENAME(@sStreet)  + '%'''

IF QUOTENAME(@sRegion) IS NOT NULL 
  SELECT @SQL = @SQL + 'or Region  LIKE ''%' +  QUOTENAME(@sRegion)  + '%'''

SELECT @SQL = @SQL + 'GROUP BY UPRN'

EXEC sp_executesql @SQL;
---------- 
END

1 个答案:

答案 0 :(得分:1)

首先,要将@sWHERE作为字符串传递给存储过程,您需要使用动态SQL。

在使用动态SQL之前,我强烈建议您阅读 The Curse and Blessings of Dynamic SQL by Erland Sommarskog

您的案例是SELECT * FROM tbl WHERE @condition

  

如果您正在考虑编写程序

CREATE PROCEDURE search_sp @condition varchar(8000) AS 
SELECT * FROM tbl WHERE @condition
     

忘了它。如果您这样做,您还没有完成使用存储过程的过渡,而您仍在组装您的   客户端中的SQL代码。但是这个例子涉及动态搜索条件/动态交叉表。

关键是你可以使用(如评论中所建议的)

DECLARE @sql NVARCHAR(MAX) = 
N'SELECT *
  FROM table_name
  WHERE ' + @sWHERE;

EXEC dbo.sp_executesql
       @sql;

但这是SQL Injection攻击的直接途径。用户可致电:

EXEC dbo.spUniqueUPRN '1=1; DROP TABLE ....; --'

总而言之,如果您使用WHERE @condition,则取决于您。这是有可能的,但我不会走这条路。