原始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. Java并发案例05---Master-Worker模式

    Master-Worker 模式是常用的并行计算模式.它的核心思想是系统由两类进程协同工作,Master和Worker进程.Master负责接收和分配任务,Worker负责处理子任务.当各个Worke ...

  2. 【[CQOI2015]选数】

    这道题自然是可以反演的 按照反演的套路我们先设出两个函数 \(F(n)\)表示从\([L,H]\)中任选\(N\)个数的最大公约数是\(n\)或者\(n\)的倍数的情况数 \(f(n)\)表示从\([ ...

  3. 在 Linux 下搭建 Git 服务器(yum安装)

    服务端(linux): 1. 安装git [root@localhost ~]# yum -y install git 2. 增加一个git账户 为了管理的方便,在linux下面增添一个 " ...

  4. HDU 1165 公式推导题

    题目链接: acm.hdu.edu.cn/showproblem.php?pid=1165 Eddy's research II Time Limit: 4000/2000 MS (Java/Othe ...

  5. oracle数据库——常用的数据类型

    2018-12-19    23:08:03 oracle数据库中常用的数据类型有23种,我们把数据类型分为字符型.数字型.日期型和其他数据类型. 一.字符型: 数据类型 取值范围 (字节) 说明 v ...

  6. 工具 | Axure基础操作 No.6

    这个是基础教程最后一篇,但是这仅仅是个开始,需要学的东西还有很多.坚持! 1.生成部分原型页面 不能单独生成子级的页面,会自动的勾选上父级.如果想单独的生成的话,就得把这个页面的级别提高,变成一级页面 ...

  7. C# lambda 和 Linq

    本章节给大家带来的是Lambda 和 Linq 的关系 Lambda : 是实例化委托的一个参数,也就是一个方法 Linq:是基于委托(lambda)的封装,代码重用,逻辑解耦,是一个帮助类库,lin ...

  8. CH4402 小Z的袜子(莫队)

    描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只袜子从1到N编号, ...

  9. 谈谈对html5的了解

    1.良好的移动性,以移动端设备为主. 2.响应式设计,以适应自动变化的屏幕尺寸. 3.支持离线缓存技术,webStorage本地缓存. 4.新增canvas,video,audio等新.标签元素.新增 ...

  10. MongoDB模糊查询 工具

    {"Exception":{$regex:"定时发送邮件"}}    //模糊查询条件 {"DateTime":-1}         // ...