Объявить курсор в динамическом sql - PullRequest
2 голосов
/ 08 марта 2012

Этот код в процедуре хранения работал годами, теперь в строке OPEN я получаю Курсор с именем ... не существует .

Что-то изменилосьв sp_executesql, что могло привести к сбою?

Есть ли другой способ сделать это (потребность в динамическом SQL заключается в том, что параметр @Types передается как предварительно отформатированная строка для IN оговорка?)

Select @Query = 'DECLARE cur_person CURSOR FOR
                 SELECT *
                 FROM MyTable
                 WHERE PersonID = @PersonnelID
                 AND Type in '  + @Types + '    <== formatted list for IN clause

EXEC sp_executesql @Query
OPEN cur_person                   <== get cursor doesn't exist error

Ответы [ 2 ]

1 голос
/ 08 марта 2012

В вашем примере это означает, что курсор определен локально.

Вы можете определить его глобально с опцией базы данных (CURSOR_DEFAULT), но это может быть не очень хорошая идея.

Еще одна вещь, которую вы можете сделать, это поместить весь код в запрос и выполнить его.

0 голосов
/ 08 марта 2012

Я не знаю, почему это не удается, но вот функция разбиения, которая устраняет необходимость динамического запроса:

CREATE FUNCTION StringToTable (@p_list varchar (MAX), @p_separator varchar (5) =',', @p_distinct bit = null) ВОЗВРАЩАЕТСЯ таблица @ParsedList (элемент varchar (500)), КАК НАЧАТЬ

DECLARE @v_element varchar(500), @Pos int, @v_insert_ind bit

SET @p_list = LTRIM(RTRIM(@p_list))+ @p_separator
SET @Pos = CHARINDEX(@p_separator, @p_list, 1)

IF REPLACE(@p_list, @p_separator, '') <> ''
BEGIN
    WHILE @Pos > 0
    BEGIN
        SET @v_insert_ind = 1
        SET @v_element = LTRIM(RTRIM(LEFT(@p_list, @Pos - 1)))
        IF @v_element <> ''
        BEGIN
            IF (@p_distinct = 1)
            AND (SELECT count(element) FROM @ParsedList WHERE element = @v_element) > 0
                SET @v_insert_ind = 0
            IF @v_insert_ind = 1
            BEGIN
                INSERT INTO @ParsedList (element) 
                VALUES (@v_element)
            END
        END
        --
        SET @p_list = RIGHT(@p_list, LEN(@p_list) - @Pos)
        SET @Pos = CHARINDEX(@p_separator, @p_list, 1)
    END
END

RETURN
END
...