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

Откуда:
Сообщений: 698
Есть в MS SQL оператор цикла

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

for i:=1 to end of MyTable 
begin
 Set @my_var=Pole[i]
 ...
 i:=i+1
end


так правильно будет через курсор?

DECLARE My_Cursor Local FOR 
SELECT * MyTable

OPEN My_Cursor 
FETCH NEXT FROM My_Cursor INTO @my_var
...

CLOSE klient_cursor
DEALLOCATE klient_cursor
31 окт 13, 15:17    [15059151]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10234
Блог
А зачем тут вообще курсор!?
select @my_var = isnull( @my_var, '' ) + [Pole[i]] from MyTable
31 окт 13, 15:19    [15059162]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
Сергей Викт.
Member

Откуда: Москва
Сообщений: 888
Ольга Семенова
Есть в MS SQL оператор цикла

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

for i:=1 to end of MyTable 
begin
 Set @my_var=Pole[i]
 ...
 i:=i+1
end


так правильно будет через курсор?

DECLARE My_Cursor Local FOR 
SELECT * MyTable

OPEN My_Cursor 
FETCH NEXT FROM My_Cursor INTO @my_var
...

CLOSE klient_cursor
DEALLOCATE klient_cursor


Да, можно и курсором.
Только ещё после первого Fetch
WHILE @@Fetch_STATUS=0
BEGIN
...
FETCH NEXT FROM My_Cursor INTO @my_var
END
31 окт 13, 15:19    [15059166]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
Ольга Семенова
Member

Откуда:
Сообщений: 698
Knyazev Alexey
А зачем тут вообще курсор!?
select @my_var = isnull( @my_var, '' ) + [Pole[i]] from MyTable


а i как увеличивать каждый раз делать i+1 ?
31 окт 13, 15:28    [15059216]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
Ольга Семенова
Member

Откуда:
Сообщений: 698
Сергей Викт.
Да, можно и курсором.
Только ещё после первого Fetch
WHILE @@Fetch_STATUS=0
BEGIN
...
FETCH NEXT FROM My_Cursor INTO @my_var
END



т.е. так?

DECLARE My_Cursor Local FOR 
SELECT * MyTable
OPEN My_Cursor 
FETCH NEXT FROM My_Cursor INTO @my_var
WHILE @@Fetch_STATUS=0
BEGIN
FETCH NEXT FROM My_Cursor INTO @my_var
...
END
CLOSE klient_cursor
DEALLOCATE klient_cursor
31 окт 13, 15:36    [15059257]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Ольга Семенова,

нет, вот так
DECLARE My_Cursor Local FOR 
SELECT * MyTable
OPEN My_Cursor 
FETCH NEXT FROM My_Cursor INTO @my_var
WHILE @@Fetch_STATUS=0
BEGIN
...
FETCH NEXT FROM My_Cursor INTO @my_var
END
CLOSE My_Cursor
DEALLOCATE My_Cursor
31 окт 13, 15:39    [15059272]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
Ольга Семенова
Member

Откуда:
Сообщений: 698
пиш утак
DECLARE My_Cursor Local FOR 
SELECT * FRROM MyTable
OPEN My_Cursor 
FETCH NEXT FROM My_Cursor INTO @my_var
WHILE @@Fetch_STATUS=0
BEGIN
...
FETCH NEXT FROM My_Cursor INTO @my_var
END
CLOSE My_Cursor
DEALLOCATE My_Cursor


ругается на Incorrect Syntax near keyword 'For'
31 окт 13, 16:16    [15059543]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
Konst_One
Member

Откуда:
Сообщений: 11538
SELECT * FRROM MyTable
31 окт 13, 16:17    [15059557]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
с уважением, но
Гость333
Ольга Семенова,

нет, вот так
DECLARE My_Cursor Local FOR 
SELECT Pole FROM MyTable
OPEN My_Cursor 
DECLARE @my_var int -- varchar ? 
FETCH NEXT FROM My_Cursor INTO @my_var
WHILE @@Fetch_STATUS=0
BEGIN
...
FETCH NEXT FROM My_Cursor INTO @my_var
END
CLOSE My_Cursor
DEALLOCATE My_Cursor
Ольга Семенова,

SQL хорош прежде всего операциями над множествами, а не над массивами
Почти любая попытка заставить обрабатывать данные как массивы (с номерами строк, последовательной обработкой строк и т.п.) приводит к замедлению выполнения запроса
31 окт 13, 16:18    [15059562]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
Konst_One
Member

Откуда:
Сообщений: 11538
и укажите конкретную колонку таблицы в опеределении курсора, раз вы фетчите в одну переменную
31 окт 13, 16:19    [15059567]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
Ольга Семенова
Member

Откуда:
Сообщений: 698
разобралась DECLARE My_Cursor CURSOR Local FOR
31 окт 13, 16:24    [15059612]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
Ольга Семенова
Member

Откуда:
Сообщений: 698
все работает, но только берется ПЕРВАЯ запись из таблицы MyTable :(
и все... внешний цикл по перебору данных из курсора останавливается

отрабатывает только внутренний цикл while 30 раз всего лишь с одной переменной равной ПЕРВОЙ записи из курсора

Use MyDB
go
DECLARE @var1 varchar(200), @var2 varchar(200), @date_from datetime, @date_to datetime
DECLARE @tmp1 varchar(200), @tmp2 varchar(200), @tmp3 varchar(500)

SET @date_from = CAST('2013-10-01' AS datetime)
SET @date_to = CAST('2013-10-31' AS datetime)

Declare My_cursor CURSOR local  FOR 
Select Pole From MyTable
Open My_cursor
Fetch next from My_cursor into @var2
while @@Fetch_STATUS=0
Begin
 
WHILE @date_from < @date_to
  BEGIN
    set @tmp1 = CONVERT(CHAR(10),@date_from,120)
    set @tmp2 = REPLACE(@tmp1, '-', '_')
    print @var2
    set @tmp3 = 'Insert into MyTempTable ([SysTime],[MessageType]) select [SysTime],[MessageType] from  T_Billing_' + @tmp2 + '_00_00_00 where PoleB=''' + @var2 + ''''
    EXEC(@tmp3)
    SET @date_from = DATEADD(day, 1, @date_from)
 END

 Fetch next from My_cursor into @var2
END
Close My_cursor
Deallocate My_cursor
31 окт 13, 16:45    [15059797]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Cygapb-007
с уважением, но

Ну как бы это всё да :)
Моей целью было лишь перенести "три точки" в начало цикла, надо было на это прямо указать. Иначе первая запись курсора пропадёт, не будет обработана.
31 окт 13, 16:47    [15059824]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
Ольга Семенова
Member

Откуда:
Сообщений: 698
Гость333
Cygapb-007
с уважением, но

Ну как бы это всё да :)
Моей целью было лишь перенести "три точки" в начало цикла, надо было на это прямо указать. Иначе первая запись курсора пропадёт, не будет обработана.


Мне нужно во внешнем цикле получать данные из курсора (с первой по последнюю запись) и передавать в качестве переменной во внутренний цикл While.

подскажите где нарушила последовательность?
31 окт 13, 17:00    [15059954]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
qwerty112
Guest
Ольга Семенова
Мне нужно во внешнем цикле получать данные из курсора (с первой по последнюю запись) и передавать в качестве переменной во внутренний цикл While.

подскажите где нарушила последовательность?

Ольга Семенова
все работает, но только берется ПЕРВАЯ запись из таблицы MyTable :(
и все... внешний цикл по перебору данных из курсора останавливается

отрабатывает только внутренний цикл while 30 раз всего лишь с одной переменной равной ПЕРВОЙ записи из курсора

Use MyDB
go
DECLARE @var1 varchar(200), @var2 varchar(200), @date_from datetime, @date_to datetime
DECLARE @tmp1 varchar(200), @tmp2 varchar(200), @tmp3 varchar(500)

--SET @date_from = CAST('2013-10-01' AS datetime)
--SET @date_to = CAST('2013-10-31' AS datetime)

Declare My_cursor CURSOR local  FOR 
Select Pole From MyTable
Open My_cursor
Fetch next from My_cursor into @var2
while @@Fetch_STATUS=0
Begin
 
SET @date_from = CAST('2013-10-01' AS datetime)
SET @date_to = CAST('2013-10-31' AS datetime)

WHILE @date_from < @date_to
  BEGIN
    set @tmp1 = CONVERT(CHAR(10),@date_from,120)
    set @tmp2 = REPLACE(@tmp1, '-', '_')
    print @var2
    set @tmp3 = 'Insert into MyTempTable ([SysTime],[MessageType]) select [SysTime],[MessageType] from  T_Billing_' + @tmp2 + '_00_00_00 where PoleB=''' + @var2 + ''''
    EXEC(@tmp3)
    SET @date_from = DATEADD(day, 1, @date_from)
 END

 Fetch next from My_cursor into @var2
END
Close My_cursor
Deallocate My_cursor

@date_from и @date_to - пониже, вроде нужно ...
31 окт 13, 17:07    [15060009]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
Ольга Семенова
Member

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

нет - тут все верно отрабатывает. ровно 30 дней и 30 записей на вкладке Messages "X row(s) affected"
ставлю 2 месяца и в два раза больше сообщений
а вот print @var2 везде одно и то же выдает. как будто внешний цикл 1 раз только отрабытывает вместо например 100 раз (100 кол-во записей в MyTable)
31 окт 13, 17:16    [15060085]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Ольга Семенова,

У вас "print @var2" не там стоит. Перенесите его из внутреннего цикла во внешний.
31 окт 13, 17:22    [15060112]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
Konst_One
Member

Откуда:
Сообщений: 11538
Use MyDB
go
DECLARE @var1 varchar(200), @var2 varchar(200), @date_from datetime, @date_to datetime
DECLARE @tmp1 varchar(200), @tmp2 varchar(200), @tmp3 varchar(500)

--SET @date_from = CAST('2013-10-01' AS datetime)
--SET @date_to = CAST('2013-10-31' AS datetime)

Declare My_cursor CURSOR local  FOR 
Select Pole From MyTable
Open My_cursor
Fetch next from My_cursor into @var2
while @@Fetch_STATUS=0
Begin
 
SET @date_from = CAST('2013-10-01' AS datetime)
SET @date_to = CAST('2013-10-31' AS datetime)

WHILE @date_from < @date_to
  BEGIN
    set @tmp1 = CONVERT(CHAR(10),@date_from,120)
    set @tmp2 = REPLACE(@tmp1, '-', '_')
    print @var2
    set @tmp3 = 'Insert into MyTempTable ([SysTime],[MessageType]) select [SysTime],[MessageType] from  T_Billing_' + @tmp2 + '_00_00_00 where PoleB=''' + @var2 + ''''
    EXEC(@tmp3)
    SET @date_from = DATEADD(day, 1, @date_from)
 END
 SET @date_from = CAST('2013-10-01' AS datetime);
 Fetch next from My_cursor into @var2
END
Close My_cursor
Deallocate My_cursor
31 окт 13, 17:22    [15060113]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
Ольга Семенова
Member

Откуда:
Сообщений: 698
Declare My_cursor CURSOR local  FOR 
Select Pole From MyTable
Open My_cursor
Fetch next from My_cursor into @var2
while @@Fetch_STATUS=0
Begin
 
SET @date_from = CAST('2013-10-01' AS datetime)
SET @date_to = CAST('2013-10-31' AS datetime)
print @var2

WHILE @date_from < @date_to
  BEGIN
    set @tmp1 = CONVERT(CHAR(10),@date_from,120)
    set @tmp2 = REPLACE(@tmp1, '-', '_')
    print @var2
    set @tmp3 = 'Insert into MyTempTable ([SysTime],[MessageType]) select [SysTime],[MessageType] from  T_Billing_' + @tmp2 + '_00_00_00 where PoleB=''' + @var2 + ''''
    EXEC(@tmp3)
    SET @date_from = DATEADD(day, 1, @date_from)
 END

 Fetch next from My_cursor into @var2
END
Close My_cursor
Deallocate My_cursor


такая отладка выдает:
Первая запись
"X row(s) affected"
"X row(s) affected"
"X row(s) affected"
...
Вторая запись
Третья запись
...
Сотая запись

а должно быть
Первая запись
"X row(s) affected"
"X row(s) affected"
"X row(s) affected"
...
Вторая запись
"X row(s) affected"
"X row(s) affected"
"X row(s) affected"
...
Третья запись
"X row(s) affected"
"X row(s) affected"
"X row(s) affected"
...
Сотая запись
"X row(s) affected"
"X row(s) affected"
"X row(s) affected"
...
31 окт 13, 17:30    [15060150]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
Ольга Семенова
Member

Откуда:
Сообщений: 698
точно
перенос вниз помогло. СПАСИБО

SET @date_from = CAST('2013-10-01' AS datetime)
SET @date_to = CAST('2013-10-31' AS datetime)

уже 5 минут запрос выполняется вместо 15 секунд
31 окт 13, 17:38    [15060200]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
declare @date_from datetime = '2013-10-01', @date_to datetime = '2013-10-31'
declare @sql varchar(max)
select @sql=STUFF(x.cmd,1,1,'')
from (
   select ';Insert MyTempTable(SysTime,MessageType)select SysTime,MessageType from T_Billing_' + c.date + '_00_00_00 t join MyTable m on m.Pole=t.PoleB'
   from master..spt_values v 
   cross apply (select REPLACE(CONVERT(CHAR(10),DATEADD(day, v.number, @date_from),120), '-', '_') ) c(date)
   where v.type='P' and v.number < DATEDIFF(DAY,@date_from,@date_to)
   for xml path('')
   )x(cmd)
print @sql
--exec(@sql)
31 окт 13, 17:46    [15060249]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с циклом.  [new]
prog882
Guest
Ольга Семенова,
declare @date_from date = '20131001', @date_to date = '20131031'
;with cte as (
select c_date = @date_from
union all
select c_date = dateadd(day,1,c_date) from cte where c_date < @date_to)
select 
'Insert into MyTempTable ([SysTime],[MessageType]) select [SysTime],[MessageType] from T_Billing_' + convert(varchar,c.c_date)+ '_00_00_00 tb inner join MyTable mt on tb.PoleB = mt.PoleB'
from cte c
1 ноя 13, 08:22    [15062332]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить