标签:位置 alter 山东省 变量 string 参数 exec 存储 str
原始SQL如下:
SELECT MONTH(OrderTime) AS datetype, SUM(DeliveryCount) AS decount, Region FROM (SELECT dbo.mpc_Order.OrderTime, dbo.mpc_Order.Province + ‘-‘ + dbo.mpc_Order.City + ‘-‘ + dbo.mpc_Order.Area AS Region, dbo.mpc_Order_Delivery.DeliveryCount FROM dbo.mpc_Order INNER JOIN dbo.mpc_Order_Delivery ON dbo.mpc_Order.OrderID = dbo.mpc_Order_Delivery.OrderID) AS T1 WHERE Region IN(‘天津市-市辖区-和平区‘,‘吉林省-长春市-市辖区‘) GROUP BY Region, MONTH(OrderTime)
因为项目需要,我需要把IN里的字符串做为一个参数,并写成存储过程进行调用,IN里面明显是一个字符串,所以很自然的写出如下存储过程:
ALTER PROCEDURE [dbo].[QueryAgentOrder] -- Add the parameters for the stored procedure here @Region NVARCHAR(1000), @QueryBy NVARCHAR(10) AS BEGIN DECLARE @SQL NVARCHAR(1000); --SQL DECLARE @PARAM NVARCHAR(1000); --参数 IF @QueryBy = ‘MONTh‘ OR @QueryBy = ‘YEAR‘ BEGIN --SET @Region = ‘‘‘天津市-市辖区-和平区‘‘,‘‘山东省-滨州市-邹平县‘‘‘; SET @SQL = N‘SELECT ‘ + @QueryBy + ‘(OrderTime) AS datetype, SUM(DeliveryCount) AS decount, Region‘; SET @SQL = @SQL + ‘ FROM (SELECT dbo.mpc_Order.OrderTime, ‘; SET @SQL = @SQL + ‘ dbo.mpc_Order.Province + ‘‘-‘‘ + dbo.mpc_Order.City + ‘‘-‘‘ + dbo.mpc_Order.Area AS Region,‘; SET @SQL = @SQL + ‘ dbo.mpc_Order_Delivery.DeliveryCount‘; SET @SQL = @SQL + ‘ FROM dbo.mpc_Order INNER JOIN‘; SET @SQL = @SQL + ‘ dbo.mpc_Order_Delivery ON dbo.mpc_Order.OrderID = dbo.mpc_Order_Delivery.OrderID‘; SET @SQL = @SQL + ‘ ) AS T1‘; IF @Region IS NOT NULL BEGIN --这里传递@Region参数 SET @SQL = @SQL + ‘ WHERE Region IN(@Region)‘; END SET @SQL = @SQL + ‘ GROUP BY Region, ‘ + @QueryBy + ‘(OrderTime)‘; --申明参数 SET @PARAM = N‘@Region NVARCHAR(1000),@QueryBy NVARCHAR(10)‘; --执行存储过程 EXEC sys.sp_executesql @SQL,@PARAM,@Region = @Region,@QueryBy = @QueryBy END END
用以下方式调用,没有得到的记录:
EXEC [dbo].[QueryAgentOrder] @Region = N‘天津市-市辖区-和平区,吉林省-长春市-市辖区‘, @QueryBy = N‘month‘
换一种方式调用,还是不行:
EXEC [dbo].[QueryAgentOrder] @Region = N‘‘‘天津市-市辖区-和平区‘‘,‘‘吉林省-长春市-市辖区‘‘‘, @QueryBy = N‘month‘
其实关键还是出在如何传递Region变量上。后来看到两篇帖子,经过测试,得到两种正确的方法如下:
第一种方法:
在Region两边用单引号和加号+再连接一下,就可以。至于为什么,不清楚。。。
ALTER PROCEDURE [dbo].[QueryAgentOrder] -- Add the parameters for the stored procedure here @Region NVARCHAR(1000), @QueryBy NVARCHAR(10) AS BEGIN DECLARE @SQL NVARCHAR(1000); --SQL DECLARE @PARAM NVARCHAR(1000); --参数 IF @QueryBy = ‘MONTh‘ OR @QueryBy = ‘YEAR‘ BEGIN SET @SQL = N‘SELECT ‘ + @QueryBy + ‘(OrderTime) AS datetype, SUM(DeliveryCount) AS decount, Region‘; SET @SQL = @SQL + ‘ FROM (SELECT dbo.mpc_Order.OrderTime, ‘; SET @SQL = @SQL + ‘ dbo.mpc_Order.Province + ‘‘-‘‘ + dbo.mpc_Order.City + ‘‘-‘‘ + dbo.mpc_Order.Area AS Region,‘; SET @SQL = @SQL + ‘ dbo.mpc_Order_Delivery.DeliveryCount‘; SET @SQL = @SQL + ‘ FROM dbo.mpc_Order INNER JOIN‘; SET @SQL = @SQL + ‘ dbo.mpc_Order_Delivery ON dbo.mpc_Order.OrderID = dbo.mpc_Order_Delivery.OrderID‘; SET @SQL = @SQL + ‘ ) AS T1‘; IF @Region IS NOT NULL BEGIN --在@Region两边加单引号 SET @SQL = @SQL + ‘ WHERE Region IN(‘+ @Region + ‘)‘; END SET @SQL = @SQL + ‘ GROUP BY Region, ‘ + @QueryBy + ‘(OrderTime)‘; --申明参数 SET @PARAM = N‘@Region NVARCHAR(1000),@QueryBy NVARCHAR(10)‘; --执行存储过程 EXEC sys.sp_executesql @SQL,@PARAM,@Region = @Region,@QueryBy = @QueryBy END END
调用方法:
EXEC [dbo].[QueryAgentOrder] @Region = N‘‘‘天津市-市辖区-和平区‘‘,‘‘吉林省-长春市-市辖区‘‘‘, @QueryBy = N‘month‘
调用结果:
第二种方法:
使用一个自定义函数,模拟split实现,然后通过select调用函数,感觉这种方法比较好。
ALTER PROCEDURE [dbo].[QueryAgentOrder] -- Add the parameters for the stored procedure here @Region NVARCHAR(1000), @QueryBy NVARCHAR(10) AS BEGIN DECLARE @SQL NVARCHAR(1000); --SQL DECLARE @PARAM NVARCHAR(1000); --参数 IF @QueryBy = ‘MONTh‘ OR @QueryBy = ‘YEAR‘ BEGIN SET @SQL = N‘SELECT ‘ + @QueryBy + ‘(OrderTime) AS datetype, SUM(DeliveryCount) AS decount, Region‘; SET @SQL = @SQL + ‘ FROM (SELECT dbo.mpc_Order.OrderTime, ‘; SET @SQL = @SQL + ‘ dbo.mpc_Order.Province + ‘‘-‘‘ + dbo.mpc_Order.City + ‘‘-‘‘ + dbo.mpc_Order.Area AS Region,‘; SET @SQL = @SQL + ‘ dbo.mpc_Order_Delivery.DeliveryCount‘; SET @SQL = @SQL + ‘ FROM dbo.mpc_Order INNER JOIN‘; SET @SQL = @SQL + ‘ dbo.mpc_Order_Delivery ON dbo.mpc_Order.OrderID = dbo.mpc_Order_Delivery.OrderID‘; SET @SQL = @SQL + ‘ ) AS T1‘; IF @Region IS NOT NULL BEGIN --通过SPLIT函数分割生成结果集 SET @SQL = @SQL + ‘ WHERE Region IN(SELECT * FROM DBO.F_SPLIT(@Region,‘‘,‘‘))‘; END SET @SQL = @SQL + ‘ GROUP BY Region, ‘ + @QueryBy + ‘(OrderTime)‘; --申明参数 SET @PARAM = N‘@Region NVARCHAR(1000),@QueryBy NVARCHAR(10)‘; --执行存储过程 EXEC sys.sp_executesql @SQL,@PARAM,@Region = @Region,@QueryBy = @QueryBy END END
调用方式也比较简单,相比第一种不用输入那么多的单引号:
EXEC [dbo].[QueryAgentOrder] @Region = N‘天津市-市辖区-和平区,吉林省-长春市-市辖区‘, @QueryBy = N‘month‘
调用结果:
附:分割函数如下:
create function f_split(@SourceSql varchar(8000),@StrSeprate varchar(10)) returns @temp table(a varchar(100)) --实现split功能 的函数 --date :2003-10-14 as begin declare @i int set @SourceSql=rtrim(ltrim(@SourceSql)) --去掉字符中的空格 set @i=charindex(@StrSeprate,@SourceSql) --找分割符在字符中的位置 while @i>=1 begin insert @temp values(left(@SourceSql,@i-1)) set @SourceSql=substring(@SourceSql,@i+1,len(@SourceSql)-@i) set @i=charindex(@StrSeprate,@SourceSql) end if @SourceSql<>‘‘ insert @temp values(@SourceSql) return end
最后
上述两种方法都可以实现在IN中传递字符串变量,对于防注方面,感觉第二种应该比第一种好,有精于此块的朋友,也请不吝赐教。
标签:位置 alter 山东省 变量 string 参数 exec 存储 str
原文地址:https://www.cnblogs.com/superfeeling/p/9650717.html