原始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. 3504. [CQOI2014]危桥【最大流】

    Description Alice和Bob居住在一个由N座岛屿组成的国家,岛屿被编号为0到N-1.某些岛屿之间有桥相连,桥上的道路是双 向的,但一次只能供一人通行.其中一些桥由于年久失修成为危桥,最多 ...

  2. BZOJ1014:[JSOI2008]火星人(Splay,hash)

    Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam, 我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 ...

  3. Django中模型(四)

    Django中模型(四) 五.创建对象 1.目的 向数据库中添加数据.当创建对象时,Django不会对数据库进行读写操作,当调用save()方法时,才与数据库交互,将对象保存到数据库中 2.注意 __ ...

  4. js 键盘点击事件

    回车键(Enter)的触发事件  js 代码如下: document.onkeydown = function (e) { if (!e) e = window.event; if ((e.keyCo ...

  5. MAPREDUCE框架结构及核心运行机制

    1.2.1 结构 一个完整的mapreduce程序在分布式运行时有三类实例进程: 1.MRAppMaster:负责整个程序的过程调度及状态协调 2.mapTask:负责map阶段的整个数据处理流程 3 ...

  6. ASP.NET MVC 自动模型验证

    经常看到这个代码 在controller 中写入验证模型,每个需要验证的action 都写-.. ,就问你烦不烦~ 可以利用 ASP.NET MVC 的 action 拦截机制 自动处理. 1 新建验 ...

  7. G1 GC日志:Application time: 0.8766273 seconds

    启动日志一直循环: 1.159: Application time: 0.8766273 seconds 1.160: Total time for which application threads ...

  8. 小程序的get和post需要注意的地方

    在进行异步请求之前先去小程序后台配置好服务器域名. get请求:header: { 'content-type':'json'}就可以. post请求:header: { 'content-type' ...

  9. java的多线程和并发库

    一.多线程基础知识 1.传统使用类Thread和接口Runnable实现 1)在Thread子类覆盖的run方法中编写运行代码 2)在传递给Thread对象的Runnable对象的run方法中编写代码 ...

  10. iOS原生分享功能

    iOS_系统原生分享 - CSDN博客 通过UIActivityViewController实现更多分享服务 - 简书 UIActivity - UIKit _ Apple Developer Doc ...