Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Динамический запроса в курсоре  [new]
VASABI
Member

Откуда:
Сообщений: 63
Всем доброго времени суток=)

Пример:
DECLARE @getSelect VARCHAR(100)
DECLARE @dateSQL Datetime

SET @getSelect = 'SELECT GETDATE()'

DECLARE Value CURSOR LOCAL FORWARD_ONLY READ_ONLY
FOR EXEC (@getSelect)    -- вот тут у нас ошибка
OPEN Value
FETCH NEXT FROM Value INTO @dateSQL

WHILE @@FETCH_STATUS = 0
BEGIN

PRINT @dateSQL	

FETCH NEXT FROM Value INTO @dateSQL
END 
CLOSE Value
DEALLOCATE Value


Подскажите пожалуйста как вызвать из курсора динамический запрос?
8 окт 12, 09:44    [13282423]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запроса в курсоре  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
VASABI,

1. C чего Вы взяли, что в объявлении курсора межет быть EXEC()? Там может стоять тольеко SELECT.
2. Судя по самомУ вопросу, Вам не стОит сейчас пытаться пользоваться курсором.
Когда появится опыт, будете правильно определять, когда курсор совершенно необходим, а это бывает очень-очень редко.
Подозреваю, что сейчас не такой случай. Просто по теории вероятностей, ибо Вы ничего не говорите о задаче
3. Что Вы пытаетесь сделать? Динамически сформировать курсор?
Так это делается вызовом sp_executesql с параметром output типа CURSOR.
8 окт 12, 09:57    [13282477]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запроса в курсоре  [new]
VASABI
Member

Откуда:
Сообщений: 63
iap,

В оригинале задача следующая:
1. Выполняется запрос, который во временную таблицу складывает два параметра: 1_время и 1_данные.
2. Создается цикл который переберает список условий выборки для следующего селекта(таких селектов может быть много), который и должен выполнится в курсоре, чтобы получить 2_время и 2_данные, которые нужно положить во временную таблицу 2_данные, где 1_время = 2_время.
8 окт 12, 10:11    [13282553]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запроса в курсоре  [new]
VASABI
Member

Откуда:
Сообщений: 63
iap,

По поводу sp_executesql вкурсе, но думал можно как-то проще, а я не знаю.
8 окт 12, 10:18    [13282597]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запроса в курсоре  [new]
Glory
Member

Откуда:
Сообщений: 104751
VASABI
Создается цикл

Т.е. постановкой задачи запрещается использовать запросы ?
8 окт 12, 10:20    [13282602]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запроса в курсоре  [new]
VASABI
Member

Откуда:
Сообщений: 63
Glory,

Понимаете, задачу можно решить и запросами, но в этом случае длина процедуры вырастает на сотни строк. А при небольших усилиях можно сократить до 50 строк.
8 окт 12, 10:25    [13282635]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запроса в курсоре  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
VASABI
Glory,

Понимаете, задачу можно решить и запросами, но в этом случае длина процедуры вырастает на сотни строк. А при небольших усилиях можно сократить до 50 строк.
Всё! Занавес!
8 окт 12, 10:29    [13282645]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запроса в курсоре  [new]
VASABI
Member

Откуда:
Сообщений: 63
Ладно, всем спасибо за неоцененную помощь.
8 окт 12, 10:34    [13282670]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запроса в курсоре  [new]
Glory
Member

Откуда:
Сообщений: 104751
VASABI
Понимаете, задачу можно решить и запросами, но в этом случае длина процедуры вырастает на сотни строк. А при небольших усилиях можно сократить до 50 строк.

А по-моему, там будет 2 строки - по одной для каждого пункта задачи.
8 окт 12, 10:54    [13282813]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запроса в курсоре  [new]
VASABI
Member

Откуда:
Сообщений: 63
Glory,

ну мне далеко до гуру в t-sql.

Вся задача изначально была таковой: есть таблица(history) в которой, как понятно из названия=), храняться исторические архивы. Поля таблицы: id,hist_id, hist_value, hist_date.
Так же таблица с описанием исторических данных(например hist_type) в котором интересующие нас поля: hist_id, hist_name.

Пример:

histiry
id | hist_id | hist_value | hist_date
1 | 1 | 33 | 2012-10-08
2 | 1 | 21 | 2012-10-07
3 | 2 | 12 | 2012-10-07

hist_type

hist_id | hist_name
1 | one
2 | two

Результирующий таблица с данными после селекта такая:

hist_date | one | two
2012-10-08 | 33 | null
2012-10-07 | 21 | 12

В результате построеный мною запрос выполняется жутко долго=) вот я и решил попробовать другие способы.
8 окт 12, 12:30    [13283540]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запроса в курсоре  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1162
VASABI
В результате построеный мною запрос выполняется жутко долго=) вот я и решил попробовать другие способы.

Может все таки не будете скрытничать, и покажете запрос?
8 окт 12, 13:08    [13283909]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запроса в курсоре  [new]
VASABI
Member

Откуда:
Сообщений: 63
Minamoto,

Сам запрос приводил в своей теме ранее: https://www.sql.ru/forum/actualthread.aspx?tid=974162

Но продублирую его=)
SELECT dp.obj_id, vh_1.valuedate, vh_1.value state_engine_su, vh_2.value i_ph_a, vh_3.value i_ph_b, vh_4.value i_ph_c, 
vh_5.value u_line_ab, vh_6.value u_line_bc, vh_7.value u_line_ac, vh_8.value temper_engine, vh_9.value pressure_env, vh_10.value imbamp_su, vh_11.value imbvolt_su, vh_12.value download_su, vh_13.value resistizol, vh_14.value reasonendstop_su, vh_15.value sost_mode 

FROM d_param dp
LEFT JOIN v_hist AS vh_1 ON dp.param_id = vh_1.param_id 
LEFT JOIN d_param_type AS dpt_1 ON dp.param_type_id = dpt_1.param_type_id AND dpt_1.param_type = 'state_engine_su'

LEFT JOIN d_param AS dp_2 ON dp.obj_id = dp_2.obj_id
LEFT JOIN d_param_type AS dpt_2 ON dp_2.param_type_id = dpt_2.param_type_id AND dpt_2.param_type = 'i_ph_a'
LEFT JOIN v_hist AS vh_2 ON dp_2.param_id = vh_2.param_id AND vh_1.valuedate = vh_2.valuedate

LEFT JOIN d_param AS dp_3 ON dp.obj_id = dp_3.obj_id
LEFT JOIN d_param_type AS dpt_3 ON dp_3.param_type_id = dpt_3.param_type_id AND dpt_3.param_type = 'i_ph_b'
LEFT JOIN v_hist AS vh_3 ON dp_3.param_id = vh_3.param_id AND vh_1.valuedate = vh_3.valuedate

LEFT JOIN d_param AS dp_4 ON dp.obj_id = dp_4.obj_id
LEFT JOIN d_param_type AS dpt_4 ON dp_4.param_type_id = dpt_4.param_type_id AND dpt_4.param_type = 'i_ph_c'
LEFT JOIN v_hist AS vh_4 ON dp_4.param_id = vh_4.param_id AND vh_1.valuedate = vh_4.valuedate

LEFT JOIN d_param AS dp_5 ON dp.obj_id = dp_5.obj_id
LEFT JOIN d_param_type AS dpt_5 ON dp_5.param_type_id = dpt_5.param_type_id AND dpt_5.param_type = 'u_line_ab'
LEFT JOIN v_hist AS vh_5 ON dp_5.param_id = vh_5.param_id AND vh_1.valuedate = vh_5.valuedate

LEFT JOIN d_param AS dp_6 ON dp.obj_id = dp_6.obj_id
LEFT JOIN d_param_type AS dpt_6 ON dp_6.param_type_id = dpt_6.param_type_id AND dpt_6.param_type = 'u_line_bc'
LEFT JOIN v_hist AS vh_6 ON dp_6.param_id = vh_6.param_id AND vh_1.valuedate = vh_6.valuedate

LEFT JOIN d_param AS dp_7 ON dp.obj_id = dp_7.obj_id
LEFT JOIN d_param_type AS dpt_7 ON dp_7.param_type_id = dpt_7.param_type_id AND dpt_7.param_type = 'u_line_bc'
LEFT JOIN v_hist AS vh_7 ON dp_7.param_id = vh_7.param_id AND vh_1.valuedate = vh_7.valuedate

LEFT JOIN d_param AS dp_8 ON dp.obj_id = dp_8.obj_id
LEFT JOIN d_param_type AS dpt_8 ON dp_8.param_type_id = dpt_8.param_type_id AND dpt_8.param_type = 'temper_engine'
LEFT JOIN v_hist AS vh_8 ON dp_8.param_id = vh_8.param_id AND vh_1.valuedate = vh_8.valuedate

LEFT JOIN d_param AS dp_9 ON dp.obj_id = dp_9.obj_id
LEFT JOIN d_param_type AS dpt_9 ON dp_9.param_type_id = dpt_9.param_type_id AND dpt_9.param_type = 'imbamp_su'
LEFT JOIN v_hist AS vh_9 ON dp_9.param_id = vh_9.param_id AND vh_1.valuedate = vh_9.valuedate

LEFT JOIN d_param AS dp_10 ON dp.obj_id = dp_10.obj_id
LEFT JOIN d_param_type AS dpt_10 ON dp_10.param_type_id = dpt_10.param_type_id AND dpt_10.param_type = 'pressure_env'
LEFT JOIN v_hist AS vh_10 ON dp_10.param_id = vh_10.param_id AND vh_1.valuedate = vh_10.valuedate

LEFT JOIN d_param AS dp_11 ON dp.obj_id = dp_11.obj_id
LEFT JOIN d_param_type AS dpt_11 ON dp_11.param_type_id = dpt_11.param_type_id AND dpt_11.param_type = 'imbvolt_su'
LEFT JOIN v_hist AS vh_11 ON dp_11.param_id = vh_11.param_id AND vh_1.valuedate = vh_11.valuedate

LEFT JOIN d_param AS dp_12 ON dp.obj_id = dp_12.obj_id
LEFT JOIN d_param_type AS dpt_12 ON dp_12.param_type_id = dpt_12.param_type_id AND dpt_12.param_type = 'download_su'
LEFT JOIN v_hist AS vh_12 ON dp_12.param_id = vh_12.param_id AND vh_1.valuedate = vh_12.valuedate

LEFT JOIN d_param AS dp_13 ON dp.obj_id = dp_13.obj_id
LEFT JOIN d_param_type AS dpt_13 ON dp_13.param_type_id = dpt_13.param_type_id AND dpt_13.param_type = 'resistizol'
LEFT JOIN v_hist AS vh_13 ON dp_13.param_id = vh_13.param_id AND vh_1.valuedate = vh_13.valuedate

LEFT JOIN d_param AS dp_14 ON dp.obj_id = dp_14.obj_id
LEFT JOIN d_param_type AS dpt_14 ON dp_14.param_type_id = dpt_14.param_type_id AND dpt_14.param_type = 'reasonendstop_su'
LEFT JOIN v_hist AS vh_14 ON dp_14.param_id = vh_14.param_id AND vh_1.valuedate = vh_14.valuedate

LEFT JOIN d_param AS dp_15 ON dp.obj_id = dp_15.obj_id
LEFT JOIN d_param_type AS dpt_15 ON dp_15.param_type_id = dpt_15.param_type_id AND dpt_15.param_type = 'sost_mode'
LEFT JOIN v_hist AS vh_15 ON dp_15.param_id = vh_15.param_id AND vh_1.valuedate = vh_15.valuedate

WHERE dp.obj_id in (SELECT su.obj_id 
FROM d_obj kust, d_obj gzu, d_obj skv, d_obj su,d_obj_type dot
WHERE kust.obj_id = 1371 
AND kust.obj_id = gzu.obj_pid
AND gzu.obj_id = skv.obj_pid
AND skv.obj_id = su.obj_pid
AND su.obj_type_id = dot.obj_type_id
AND dot.obj_type = 'su_ecn')
AND vh_1.valuedate > '2012-10-01' AND vh_1.valuedate < '2012-10-03'
AND dpt_1.param_type_id IS NOT NULL
AND dpt_2.param_type_id IS NOT NULL
AND dpt_3.param_type_id IS NOT NULL
AND dpt_4.param_type_id IS NOT NULL
AND dpt_5.param_type_id IS NOT NULL
AND dpt_6.param_type_id IS NOT NULL
AND dpt_7.param_type_id IS NOT NULL
AND dpt_8.param_type_id IS NOT NULL
AND dpt_9.param_type_id IS NOT NULL
AND dpt_10.param_type_id IS NOT NULL
AND dpt_11.param_type_id IS NOT NULL
AND dpt_12.param_type_id IS NOT NULL
AND dpt_13.param_type_id IS NOT NULL
AND dpt_14.param_type_id IS NOT NULL
AND dpt_15.param_type_id IS NOT NULL
AND vh_1.value IS NOT NULL
8 окт 12, 13:23    [13284042]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запроса в курсоре  [new]
1q1
Guest
что-то не заметно, что вы поправили запрос, как вам рекомендовали еще 3 дня назад =)
8 окт 12, 13:28    [13284088]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запроса в курсоре  [new]
VASABI
Member

Откуда:
Сообщений: 63
1q1,

Правил=) просто не осталось другого исходника запроса, результат тот же по скорости выполнения=) Использовать PIVOT т.к. есть машины даже с mssql2000.
8 окт 12, 13:36    [13284168]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запроса в курсоре  [new]
VASABI
Member

Откуда:
Сообщений: 63
VASABI
1q1,

Использовать PIVOT т.к. есть машины даже с mssql2000.
*
Использовать PIVOT не могу т.к. есть машины даже с mssql2000.
8 окт 12, 13:37    [13284175]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запроса в курсоре  [new]
Glory
Member

Откуда:
Сообщений: 104751
VASABI
Использовать PIVOT т.к. есть машины даже с mssql2000.

PIVOT легко эмулируется через CASE и GROUP BY
8 окт 12, 13:38    [13284183]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запроса в курсоре  [new]
Гузы
Guest
VASABI,
Если уж совсем никуды, я бы переделал это так:
LEFT JOIN
(
select  ...
from
 d_param AS dp_2 ON dp.obj_id = dp_2.obj_id
JOIN d_param_type AS dpt_2 ON dp_2.param_type_id = dpt_2.param_type_id AND dpt_2.param_type = 'i_ph_a'
 JOIN v_hist AS vh_2 ON dp_2.param_id = vh_2.param_id AND vh_1.valuedate = vh_2.valuedate
)t2 on ....

Детали прописывать лениво. Глядишь, полегчает...
8 окт 12, 17:19    [13286133]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запроса в курсоре  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
VASABI
который переберает список условий выборки для следующего селекта(таких селектов может быть много), который и должен выполнится в курсоре

Ну и делайте каждый раз новую временную таблицу, делов-то.
А то сейчас Вам тут насоветуют.
Правильно, конечно, советуют. Но оно Вам нужно?
10 окт 12, 17:08    [13297737]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить