码迷,mamicode.com
首页 > 其他好文 > 详细

如何在存储过程的IN操作中传递字符串变量

时间:2018-09-15 13:48:26      阅读:311      评论:0      收藏:0      [点我收藏+]

标签:位置   alter   山东省   变量   string   参数   exec   存储   str   

原始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 = NSELECT  + @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 = Nmonth

换一种方式调用,还是不行:

EXEC    [dbo].[QueryAgentOrder]
        @Region = N‘‘‘天津市-市辖区-和平区‘‘,‘‘吉林省-长春市-市辖区‘‘‘,
        @QueryBy = Nmonth

 

其实关键还是出在如何传递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 = NSELECT  + @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 = Nmonth

调用结果:

技术分享图片

第二种方法:

 使用一个自定义函数,模拟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 = NSELECT  + @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 = Nmonth

调用结果:

技术分享图片

附:分割函数如下:

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操作中传递字符串变量

标签:位置   alter   山东省   变量   string   参数   exec   存储   str   

原文地址:https://www.cnblogs.com/superfeeling/p/9650717.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!