原始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. UVa 10288 - Coupons(数学期望 + 递推)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  2. 【jQuery】todolist

    1 2 3 用npm命令下载依赖,优点:不用去网上找链接,代码都一样 4.jQuery自动下载进node_modules文件下 npm install jquery --save  这句命令的意思是保 ...

  3. 5、Spring-Cloud-声明式调用 Feign(上)

    5.1.写一个 Feign 害户端 新建项目: 依赖: <dependency> <groupId>org.springframework.boot</groupId&g ...

  4. cloudstack 用admin 账号创建虚拟机只是提示insufficient resource

    报错: com.cloud.exception.ResourceUnavailableException: Resource [DataCenter:1] is unreachable: Unable ...

  5. Spring Cloud Sleuth 之Greenwich版本全攻略

    微服务架构是一个分布式架构,微服务系统按业务划分服务单元,一个微服务系统往往有很多个服务单元.由于服务单元数量众多,业务的复杂性较高,如果出现了错误和异常,很难去定位.主要体现在一个请求可能需要调用很 ...

  6. DG不同步,MRP0进程打不开

    问题描述:主库备库之前正常连接,但是昨天磁盘空间满了之后,由于不知什么原因将备库重做日志删了,今天早上发现DG不同步的报警. 当时思路如下:1.通过select thread#,low_sequenc ...

  7. 『ACM C++』 PTA 天梯赛练习集L1 | 025-026

    满课一天,做25的时候还疯狂WA,进度可以说是很慢了 哭泣 ------------------------------------------------L1-025---------------- ...

  8. BZOJ 3053: The Closest M Points(K-D Tree)

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1235  Solved: 418[Submit][Status][Discuss] Descripti ...

  9. Spring AOP代理模式

    代理模式 代理模式是一种设计模式,提供了对目标对象的另外的访问方式.即通过代理访问目标对象. 好处:可以再目标对象实现的基础上,增加额外的功能的操作.扩展目标对象的功能,而不改变现有的功能逻辑. 1. ...

  10. 大数据学习--day14(String--StringBuffer--StringBuilder 源码分析、性能比较)

    String--StringBuffer--StringBuilder 源码分析.性能比较 站在优秀博客的肩上看问题:https://www.cnblogs.com/dolphin0520/p/377 ...