2016-08-18 2 views
2

Я хочу запустить мою хранимую процедуру для каждого значения в строке, разделенной запятыми. Допустим, что у меня есть ('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 
+0

Вместо «CURSOR» попробуйте выполнить второй SP (вспомогательный SP) в основном SP с помощью команды 'EXEC'. Вы можете обратиться к этому вопросу, если хотите получить более подробную информацию (http://stackoverflow.com/questions/15802511/execute-a-stored-procedure-in-another-stored-procedure-in-sql-server) –

+0

Хм, сделай вы используете 'NVARCHAR' в результате функции и вставляете это в поле' BIGINT'? – anatol

+0

Почему вы позволили себе достичь этой цели? SQL Server имеет типы * designed * для хранения нескольких значений, таких как табличные параметры. Набирая все в цепочку, чтобы потом дать себе задачу распаковать, это кажется загадочным выбором. –

ответ

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  

В этом фрагменте был пропущен еще один FETCH NEXT оператор в WHILE блоке. Также будет правильным использовать WHILE @@FETCH_STATUS = 0 вместо вашего WHILE EXISTS (SELECT FundId FROM @FUNDS), потому что он будет всегда возвращаться true.

+0

Еще один FETCH NEXT все еще там. Я сейчас редактировал вопрос. и я также попытался использовать его с @@ FETCH_STATUS – MaazKhan47

+0

Можете ли вы показать нам код 'dbo.SplitString()' нам? – anatol

+0

Конечно. Добавлено SplitString. Но он отлично работает – MaazKhan47

Смежные вопросы