原始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. 【NOI2008】假面舞会

    题目描述 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会. 今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具.每个面具都有一个编号,主办方会把此编号 ...

  2. matlab中的unique函数详解

    https://blog.csdn.net/sinat_40282753/article/details/78373532

  3. selenium + python自动化测试unittest框架学习(三)webdriver元素定位(一)

    1.Webdriver原理 webdirver是一款web自动化操作工具,为浏览器提供统一的webdriver接口,由client也就是我们的测试脚本提交请求,remote server浏览器进行响应 ...

  4. ssh框架错误:org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role。

    在做ssh项目练习的时候出现问题: org.hibernate.LazyInitializationException: failed to lazily initialize a collectio ...

  5. html标签种类

    标签 描述 <!--...--> 定义注释. <!DOCTYPE> 定义文档类型. <a> 定义锚. <abbr> 定义缩写. <acronym& ...

  6. 如何快速找到指定端口被哪个程序占用并释放该端口(解决bindException)

    首先打开打开任务管理器,选择性能模块,下方有打开资源监视器,或者直接搜索资源监视器 在资源监视器中点击侦听端口模块,即可看到正在使用网络端口的应用程序名和pid,如果被占用可以直接使用命令行关闭即可 ...

  7. 在金融服务计算中,必须要使用BigDecimal

    在Java程序开发过程中,比较初级(工作经验受限)的开发人员,把注意力全部放在了一些高大上的新技术中,往往忽略了一些初级问题.. 金融服务系统中,对金额的敏感至关重要,账户余额.还款金额.代收本金.代 ...

  8. Oracle 的PL/SQL语言使用

    --PL/SQL语言(procedure language 过程化语言) --1.声明类型 declare k number; m ; --Character String buffer too sm ...

  9. 随机获取UDID

    (NSString *)uuidString { CFUUIDRef uuid_ref = CFUUIDCreate(NULL); CFStringRef uuid_string_ref= CFUUI ...

  10. OO第三次博客作业——规格

    OO第三次博客作业——规格 一.调研结果: 规格的历史: 引自博文链接:http://blog.sina.com.cn/s/blog_473d5bba010001x9.html 传统科学的特点是发现世 ...