此存储过程一直有效,直到我添加变量。 @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
答案 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
,则取决于您。这是有可能的,但我不会走这条路。