【问题标题】:Run stored procedure for each value in a comma separated string为逗号分隔的字符串中的每个值运行存储过程
【发布时间】:2016-12-24 22:58:29
【问题描述】:

我想为逗号分隔字符串中的每个值运行我的存储过程。假设我有 ('10,20,30') 所以 sp 应该先运行 10,然后运行 ​​20 和 30,并在单个表中返回结果。 Sp 将为每个值返回单行。 我已经使用光标尝试过,但没有按预期工作。

SET ANSI_NULLS OFF
GO   

SET QUOTED_IDENTIFIER OFF
GO

ALTER PROCEDURE [dbo].[z_Formulas2]
(
    @Fund_ID nvarchar,      --('32,25,201')
    @XFund_ID bigint, 
    @Start_Dated datetime,
    @End_Dated datetime
)   
AS
    DECLARE @FUNDS TABLE(FundId BIGINT)
    INSERT INTO @FUNDS
    SELECT item FROM dbo.SplitString(@Fund_ID, ',') --Split string parse csv into table
    SELECT * FROM @FUNDS
    DECLARE @MyCursor CURSOR;
    DECLARE @CurFund BIGINT;

BEGIN
SET @MyCursor = CURSOR FOR SELECT FundId FROM @FUNDS   
OPEN @MyCursor 
FETCH NEXT FROM @MyCursor 
INTO @CurFund

WHILE EXISTS (SELECT FundId FROM @FUNDS)
BEGIN... --Logic part
 FETCH NEXT FROM @MyCursor 
 INTO @CurFund 
END

CLOSE @MyCursor ;
DEALLOCATE @MyCursor;
END

//dbo.SplitString

ALTER FUNCTION [dbo].[SplitString]
(    
      @Input NVARCHAR(MAX),
      @Character CHAR(1)
)
RETURNS @Output TABLE (
      Item NVARCHAR(1000)
)
AS
BEGIN
      DECLARE @StartIndex INT, @EndIndex INT

      SET @StartIndex = 1
      IF SUBSTRING(@Input, LEN(@Input) - 1, LEN(@Input)) <> @Character
      BEGIN
            SET @Input = @Input + @Character
      END

      WHILE CHARINDEX(@Character, @Input) > 0
      BEGIN
            SET @EndIndex = CHARINDEX(@Character, @Input)

            INSERT INTO @Output(Item)
            SELECT SUBSTRING(@Input, @StartIndex, @EndIndex - 1)

            SET @Input = SUBSTRING(@Input, @EndIndex + 1, LEN(@Input))
      END

      RETURN
END

【问题讨论】:

  • 尝试使用EXEC 命令在主 SP 中执行第二个 SP(子 SP),而不是 CURSOR。如果您想了解更多详细信息,可以参考这个问题(stackoverflow.com/questions/15802511/…
  • 嗯,你在函数结果中使用NVARCHAR并将其插入BIGINT字段吗?
  • 为什么要让自己走到这一步? SQL Server 具有设计 用于保存多个值的类型,例如表值参数。把所有东西都塞进一个字符串,然后给自己解包的任务似乎是一个神秘的选择。
  • @BPavanKumar 为什么不使用 CURSOR.. 有什么原因吗?
  • @MaazKhan47 游标被称为内存猪是有原因的,尽管在你的情况下它并不重要。查看此站点以更好地了解问题 (support.microsoft.com/en-us/kb/837957)

标签: sql .net sql-server stored-procedures cursor


【解决方案1】:

似乎无法正确使用光标。

DECLARE @MyCursor CURSOR;
DECLARE @CurFund BIGINT;
BEGIN
    SET @MyCursor = CURSOR FOR SELECT FundId FROM @FUNDS   
    OPEN @MyCursor 
        FETCH NEXT FROM @MyCursor 
        INTO @CurFund

        WHILE EXISTS (SELECT FundId FROM @FUNDS)
        BEGIN
             --Logic part
        END
    CLOSE @MyCursor ;
    DEALLOCATE @MyCursor;
END    

在这个 sn-p 中,WHILE 块中的另一个 FETCH NEXT 运算符被跳过。使用WHILE @@FETCH_STATUS = 0 代替您的WHILE EXISTS (SELECT FundId FROM @FUNDS) 也是正确的,因为它将始终返回true

【讨论】:

  • 另一个 FETCH NEXT 仍然存在。我现在已经编辑了问题。我也尝试过将它与@@FETCH_STATUS 一起使用
  • 当然。添加了拆分字符串。但它工作得很好
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-29
  • 2011-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-16
相关资源
最近更新 更多