Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Запрос для курсора с неизвестным количеством таблиц

14K
27 декабря 2009 года
artem_kvadro
63 / / 30.07.2007
Ситуация такая: есть несколько однотипных таблиц. Пользовательская функция обрабатывает в них данные и возвращает таблицу с результатами. В этой функции планирую использовать курсор для обработки данных в исходных таблицах. Проблема в том, что заранее неизвестно количество этих таблиц, а курсор в Transact-SQL объявляется сразу с запросом после ключевого слова FOR. Мой запрос должен строиться из нескольких подзапросов с UNION. Можно было бы использовать строковую переменную с текстом запроса, что-то типа:
 
Код:
DECLARE @Request nvarchar(MAX)
SET @Request = 'SELECT... UNION SELECT ... и т. д.'
DECLARE curs CURSOR FOR @Request

...но компилироваться такое объявление не хочет. Возможно ли как-то по другому объявить курсор? MS SQL 2008.
5
27 декабря 2009 года
hardcase
4.5K / / 09.08.2005
Посмотрите тут. Задача сводится к конструированию строки с запросом и передачи ее в EXEC.
14K
27 декабря 2009 года
artem_kvadro
63 / / 30.07.2007
Спасибо, то что нужно! Вот оно:
 
Код:
declare @query nvarchar(250)
set @query = 'declare cur cursor global forward_only static read_only FOR SELECT MyFiled from ' + @table
exec (@query)
...
14K
28 декабря 2009 года
artem_kvadro
63 / / 30.07.2007
Вот досада! Динамические запросы не работают в пользовательских функциях. :( Зато вроде работают в хранимых процедурах. Попробую создать курсор в хр. процедуре и возвращать его как OUTPUT в функцию...
14K
30 декабря 2009 года
artem_kvadro
63 / / 30.07.2007
Пишу в хранимой процедуре такие вот строчки:
 
Код:
DECLARE @VarValue AS float
DECLARE @Validity AS smallint
DECLARE @Time_ms AS float(53)
...
/*Вот эта работает:*/
INSERT INTO ##xxx VALUES (@VarValue, @Validity, @Time_ms)

/*А вот эта нет:*/
EXEC('INSERT INTO ##xxx VALUES (@VarValue, @Validity, @Time_ms)')

Во втором случае выдается ошибка Must declare the scalar variable "@VarValue". Никак не пойму, почему? Тем более до этого места другие динамические запросы, DECLARE CURSOR, например, работают нормально.

З.Ы. Можно было бы, конечно, конвертировать @VarValue в строковую переменную и таким образом составить запрос, но как-то это нецелесообразно, потому что в цикле эта строчка вызывается порядка 2000 раз.
6
03 января 2010 года
George
4.1K / / 05.01.2007
Цитата: artem_kvadro
Пишу в хранимой процедуре такие вот строчки:
 
Код:
DECLARE @VarValue AS float
DECLARE @Validity AS smallint
DECLARE @Time_ms AS float(53)
...
/*Вот эта работает:*/
INSERT INTO ##xxx VALUES (@VarValue, @Validity, @Time_ms)

/*А вот эта нет:*/
EXEC('INSERT INTO ##xxx VALUES (@VarValue, @Validity, @Time_ms)')

Во втором случае выдается ошибка Must declare the scalar variable "@VarValue". Никак не пойму, почему? Тем более до этого места другие динамические запросы, DECLARE CURSOR, например, работают нормально.

З.Ы. Можно было бы, конечно, конвертировать @VarValue в строковую переменную и таким образом составить запрос, но как-то это нецелесообразно, потому что в цикле эта строчка вызывается порядка 2000 раз.


так по тексту ошибки ж ясно вроде.
попробуйте объявить переменные "внутри" EXEC:
[highlight=sql]
EXEC('
DECLARE @VarValue AS float
DECLARE @Validity AS smallint
DECLARE @Time_ms AS float(53)
INSERT INTO ##xxx VALUES (@VarValue, @Validity, @Time_ms)
')
[/highlight]

14K
04 января 2010 года
artem_kvadro
63 / / 30.07.2007
[QUOTE="Washington"]так по тексту ошибки ж ясно вроде.[/QUOTE]
По тексту ясно, что нужно объявить переменную, но они же у меня уже объявлены выше в теле процедуры. Или я что-то не понимаю в принципе работы динамических запросов? Недавно только начал разбираться с T-SQL.
Так, как Вы предлагаете, пробовал - работает. Но мне нужно сначала в эти переменные считать из курсора каждую @n-ную строку, а потом записать их значения во временную таблицу:
Код:
DECLARE @VarValue AS float
    DECLARE @Validity AS smallint
    DECLARE @Time_ms AS float(53)
...
    DECLARE @InsertTmpTableQuery AS nvarchar(250)
    SET @InsertTmpTableQuery = N'INSERT INTO ' + @TmpTableName +
        N' VALUES (@VarValue, @Validity, @Time_ms)'
...
    /*Выборка из курсора*/
    WHILE @@FETCH_STATUS = 0
    BEGIN
        EXECUTE(@InsertTmpTableQuery)
        FETCH RELATIVE @n FROM curs
            INTO @VarValue, @Validity, @Time_ms
    END
...


Получается, нужно тогда в теле цикла каждый раз составлять строку с запросом с помощью CONVERT, так?
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог