原始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中传递字符串变量,对于防注方面,感觉第二种应该比第一种好,有精于此块的朋友,也请不吝赐教。

如何在存储过程的IN操作中传递字符串变量的更多相关文章

  1. 【问题】Asp.net MVC 的cshtml页面中调用JS方法传递字符串变量参数

    [问题]Asp.net MVC 的cshtml页面中调用JS方法传递字符串变量参数. [解决]直接对变量加引号,如: <button onclick="deleteProduct('@ ...

  2. 如何在django的filter中传递字符串变量作为查询条件(动态改变查询条件)

    一般来说在需要查询数据的时候都是以下形式 ret=Articles.objects.filter(id=1) 然而如果要动态的改变查询的条件怎么办呢? 如下代码 def getModelResult( ...

  3. JS 拼装代码的HTML onClick方法传递字符串

    有时会在JS中拼装HTML代码,这时在HTML中出现的onClick()方法中: 1.出现传递Num型的数据,直接拼装进去即可: 2.可能会出现传递字符串的情况,处理方法比较特殊,如下: a:直接字符 ...

  4. Shell如何传递字符串

    Shell 在写函数的时候,有时候需要传递字符串,由于字符串中有空格,所以结果总是不对,下面写个小例子,解决这个问题: #!/bin/bash # value init TT="adb sh ...

  5. Oracle 在函数或存储过程中执行sql查询字符串并将结果值赋值给变量

    请看黄色部分 --区县指标 THEN TVALUE_SQL := 'SELECT TO_CHAR(' || CUR_ROW.MAIN_FIELD || ') FROM ' || CUR_ROW.END ...

  6. setTimeout 里 传递字符串代码报错

    js高程 第三版 p203 重点:超时调用的代码都是在全局作用域中执行的,因此函数中this 的值在非严格模 式下指向window 对象,在严格模式下是undefined. 不过这里仅仅解释前半句: ...

  7. JS函数传递字符串参数(符号转义)

    原文链接:https://blog.csdn.net/Myname_China/article/details/82907965 JS函数传递字符串参数,如果没有转义处理,在接收的时候无法正确的接收字 ...

  8. c++字符串变量---8

    原创博客:转载请标明出处:http://www.cnblogs.com/zxouxuewei/ 一.字符串变量的定义 1>.对于C与C++来说是没有字符串型的数据类型的,在C++中是通过包含st ...

  9. 常见问题一之拼接表格 js传递参数变量 Json接收值

    1.前台拼接表格时,有时候需要使用拼接html字符串,需要多次循环拼接的,放在方法里边: //ary可以是数组中的一组数据.function(ary){var MyHtml="<tr& ...

随机推荐

  1. BurpSuite Intruder 4种攻击模式

    BurpSuite intruder attack-type 4种爆破模式 Sniper 单参数爆破,多参数时同一个字典按顺序替换各参数,总之初始值有一个参数不变 Battering ram 多参数同 ...

  2. leetcode64. Minimum Path Sum

    这个题是从左上角到右下角的路径和最小,实际就是一道dp题. 第一种写法是只初始化(0,0)位置,第二种写法则是把第一行.第一列都初始化了.个人更喜欢第二种写法,简单一点. dp的右下角的值就为最终的值 ...

  3. Linux中PATH环境变量的作用和使用方法

    关于PATH的作用:PATH说简单点就是一个字符串变量,当输入命令的时候LINUX会去查找PATH里面记录的路径.比如在根目录/下可以输入命令ls,在/usr目录下也可以输入ls,但其实ls这个命令根 ...

  4. 在Windos上安装Nginx

    官网地址:http://nginx.org/en/download.html 1.下载 2.解压 3.启动 4.访问 打开cmd cd到nginx路径,使用命令关闭它 nginx.exe -s sto ...

  5. MVC 当中 [ValidateAntiForgeryToken] 的作用

     ValidateAntiForgeryToken 防止CSRF(跨网站请求伪造) 用途:防止CSRF(跨网站请求伪造). 用法:在View->Form表单中:<%:Html.AntiFo ...

  6. Linux-- 目录基本操作(2)

    cp 复制文件或目录 用法:cp [OPTION] SOURCE源文件 DIRECTORY目标文件,具体可以查看 man cp 以常用的参数举例 [root@hs-192-168-33-206 tom ...

  7. spring 包的依赖关系

    转自:http://www.cnblogs.com/ywlaker/p/6136625.html 很多人都在用spring开发java项目,但是配置maven依赖的时候并不能明确要配置哪些spring ...

  8. python3爬虫-爬取B站排行榜信息

    import requests, re, time, os category_dic = { "all": "全站榜", "origin": ...

  9. vlookup函数使用---execl公式

    目录 vlookup函数使用---execl公式 1.用途: 2.函数语法: 3.使用方式: 4.实际案例+步骤解析 5.常见错误 vlookup函数使用---execl公式 1.用途: 我们有一张工 ...

  10. mysql使用Sql获取13位时间戳

    SELECT REPLACE(unix_timestamp(current_timestamp(3)),'.','');