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

Откуда:
Сообщений: 129
CREATE PROCEDURE [dbo].[MyProcedure] 
(
    @classifier varchar(max) = '' -- коды классификаторов
)
AS
BEGIN
    DECLARE @outerCounter INT;
	   SET @outerCounter = 0;
    DECLARE @innerCounter INT;
	   

    DECLARE @whereStatement     VARCHAR(max);
	   SET @whereStatement = NULL;
    DECLARE @subWhereStatement  VARCHAR(max);
    DECLARE @outerCycle TABLE   (item VARCHAR(max)); 
    
    DECLARE @outerItem VARCHAR(max);
    DECLARE @innerItem VARCHAR(max);

    /* Раздляем входную строку по основному разделителю */
    INSERT @outerCycle SELECT item FROM dbo.CalcHelperString_Split(@classifier,';');

    /* Объявляем внешний курсор */
    DECLARE outerCurs CURSOR FOR
    SELECT item FROM @outerCycle;
    OPEN outerCurs; 
    WHILE (1=1)
    BEGIN 
        FETCH FROM outerCurs 
        INTO @outerItem;   
	   IF @@fetch_status = -1 BREAK; 
           IF @@fetch_status = -2 CONTINUE;

	   SET @outerCounter = @outerCounter + 1;
	   SET @innerCounter = 0;

	   DECLARE @innerCycle TABLE (item VARCHAR(max));
	   INSERT @innerCycle SELECT item FROM dbo.CalcHelperString_Split(@outerItem,',')
	   
	   SET @subWhereStatement = NULL;

	   DECLARE innerCurs CURSOR FOR
	   SELECT item FROM @innerCycle;
	   OPEN innerCurs; 
	   WHILE (1=1)
	   BEGIN
		  FETCH FROM innerCurs 
		  INTO @innerItem;   

		  IF @@fetch_status = -1 break; 
		  IF @@fetch_status = -2 continue;

		  SET @innerCounter = @innerCounter + 1;

		  IF (ISNULL(@subWhereStatement, 'emptyString') <> 'emptyString')
			 BEGIN
				SET @subWhereStatement = @subWhereStatement + ' OR class._Fld10056RRef = ' + @innerItem;
			 END
		  ELSE
			 BEGIN
				SET @subWhereStatement = 'class._Fld10056RRef = ' + @innerItem;
			 END
	   END
	   DEALLOCATE innerCurs

	   

	   IF (ISNULL(@whereStatement, 'emptyString') <> 'emptyString')
		  BEGIN
			 SET @whereStatement = 'AND ' + '(' + @subWhereStatement + ')';
		  END
	   ELSE
		  BEGIN
			 SET @whereStatement = '(' + @subWhereStatement + ')';
		  END

	   SET @whereStatement = ' WHERE ' + @whereStatement
    END
    DEALLOCATE outerCurs;

    SELECT @subWhereStatement as SubWhereStatement;
    SELECT @whereStatement as WhereStatement;

    DECLARE @selectCommand nvarchar(max) = 
    'SELECT class._Reference48_IDRRef
    FROM [1cbase_history].dbo._Reference48_VT10054 AS class'
    + @whereStatement;

    SELECT @selectCommand as SELECTCOMMAND;
				
    SELECT @innerCounter as innerCounter;
    SELECT @outerCounter as outerCounter;

END


примечание.
dbo.CalcHelperString_Split(@classifier,';') 
- эта процедура разбивает строку по указанному разделителю. работает 100% корректно.

Есть вот такая процедура. На выходе должен получиться текст запроса.

Вызов:


[dbo].[MyProcedure]
		@classifier = '0x80AD20CF3046813911E1952DF921D043,0x80AD20CF3046813911E1952DF921D095;0x80AD20CF3046813911E1952DF921D044,0x80AD20CF3046813911E1952DF921D096'


Ожидание:

SELECT class._Reference48_IDRRef
    FROM [1cbase_history].dbo._Reference48_VT10054 AS class WHERE
     (class._Fld10056RRef = 0x80AD20CF3046813911E1952DF921D043 OR class._Fld10056RRef = 0x80AD20CF3046813911E1952DF921D095) AND  
 (class._Fld10056RRef = 0x80AD20CF3046813911E1952DF921D044 OR class._Fld10056RRef = 0x80AD20CF3046813911E1952DF921D096)


Реальность:


SELECT class._Reference48_IDRRef
    FROM [1cbase_history].dbo._Reference48_VT10054 AS class WHERE AND 
    (class._Fld10056RRef = 0x80AD20CF3046813911E1952DF921D043 OR class._Fld10056RRef = 0x80AD20CF3046813911E1952DF921D095 
    OR class._Fld10056RRef = 0x80AD20CF3046813911E1952DF921D044 OR class._Fld10056RRef = 0x80AD20CF3046813911E1952DF921D096)



Счетчики итераций внешнего и внутреннего FETCH FROM 2 и 4 соответственно. Не пойму в чем трабл.
18 ноя 14, 13:29    [16865080]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
Glory
Member

Откуда:
Сообщений: 104760
А причем тут fetch,если за полдстановку AND отвечает условие IF (ISNULL(@whereStatement, 'emptyString') <> 'emptyString')
18 ноя 14, 13:40    [16865182]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
monstrilla
Member

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

как я понимаю, вложенный фетч отрабатывает 4 раза подряд, а не 1 оутер - 2 вложенных, 1 оутер - 2 вложенных. потому и результат такой. вот только не знаю, как поправить.
18 ноя 14, 13:42    [16865193]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
Glory
Member

Откуда:
Сообщений: 104760
monstrilla
как я понимаю, вложенный фетч отрабатывает 4 раза подряд,

fetch отрабатывает столко раз, сколько выполняется цикл.
Почему это не может быть 4 ?
Вы хотите сказать, что внутренний цикл выполняется большее число раз, чем есть в таблице @innerCycle ?
18 ноя 14, 13:48    [16865234]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
monstrilla
Member

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

внутренний цикл не может отрабатывать 4 раза подряд из-за входных данных, которые я указал.

должно быть: 1 оутер - 2 иннер, 1 оутер - 2 иннер - выход из процедуры. судя по результату подозреваю, что отрабатывает как-то так:

1 оутер - 4 иннер - 1 оутер. бред, наверное, но другого объяснения у меня нет
18 ноя 14, 13:52    [16865267]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
Glory
Member

Откуда:
Сообщений: 104760
monstrilla
внутренний цикл не может отрабатывать 4 раза подряд из-за входных данных, которые я указал.

Что значит "не может" ? сколько записей в @innerCycle перед началом цикла ?
18 ноя 14, 13:54    [16865286]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
а вообще конечно... исходя из параметров и результата ожидания И
    DECLARE @selectCommand nvarchar(max) = 
    'SELECT class._Reference48_IDRRef
    FROM [1cbase_history].dbo._Reference48_VT10054 AS class'
    + @whereStatement;

в теле процедуры - ето творения называеться НАФИГА ДЕЛАТЬ ПРОСТО ЕСЛИ МОЖНО ПИСЕЦ КАК СЛОЖНО :)
18 ноя 14, 13:55    [16865289]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
monstrilla
Member

Откуда:
Сообщений: 129
Glory, на каждой итерации внешнего цикла там 2 записи
18 ноя 14, 14:00    [16865313]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
monstrilla
Member

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

а вот щас посмотрел по отладчику и выяснилось, что четыре. плохо, должно быть две
18 ноя 14, 14:06    [16865349]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
Glory
Member

Откуда:
Сообщений: 104760
monstrilla
на каждой итерации внешнего цикла там 2 записи

Это вы с помощью чего установили ? Отладочных выводов ? Дебаггера ?
18 ноя 14, 14:07    [16865355]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
Glory
Member

Откуда:
Сообщений: 104760
monstrilla
а вот щас посмотрел по отладчику и выяснилось, что четыре. плохо, должно быть две

Потому что
DECLARE @innerCycle TABLE (item VARCHAR(max));
Не пересоздает таблицу

declare @i int
set @i = 1
while @i < 4
begin
	print @i
	declare @t table(f1 int)
	insert @t values(@i)
	set @i = @i + 1
	select * from @t
end
18 ноя 14, 14:09    [16865369]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
monstrilla
Member

Откуда:
Сообщений: 129
Glory, да, я уже понял, что надо либо пересоздавать либо чистить. пишу на скл второй день, шарписты мы :)
18 ноя 14, 14:12    [16865394]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
monstrilla
Member

Откуда:
Сообщений: 129
Перенес объявление до внешнего курсора

 DECLARE @innerCycle TABLE (item VARCHAR(max));

    /* Объявляем внешний курсор */
    DECLARE outerCurs CURSOR FOR
    SELECT item FROM @outerCycle;
    OPEN outerCurs; 
    WHILE (1=1)
...


Перед заполнением очищаю таблицу на каждой итерации внешнего курсора
DELETE FROM @innerCycle
INSERT @innerCycle SELECT item FROM dbo.CalcHelperString_Split(@outerItem,',')


Результат выдается другой, но все равно неверный

SELECT class._Reference48_IDRRef
    FROM [1cbase_history].dbo._Reference48_VT10054 AS class WHERE AND (class._Fld10056RRef = 0x80AD20CF3046813911E1952DF921D044 OR class._Fld10056RRef = 0x80AD20CF3046813911E1952DF921D096)


Теперь две внутренние итерации куда-то пропадают...
18 ноя 14, 14:19    [16865449]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
Glory
Member

Откуда:
Сообщений: 104760
monstrilla
Теперь две внутренние итерации куда-то пропадают...

Дебаггер или отладочные выводы вам помогут
18 ноя 14, 14:20    [16865456]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
monstrilla
Member

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

дебагера нет. только селекты. если бы они помогали, я бы не стал постить вопрос :(
18 ноя 14, 14:26    [16865508]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
Glory
Member

Откуда:
Сообщений: 104760
monstrilla
если бы они помогали, я бы не стал постить вопрос

Вы не можете понять по select-ам какие фрагменты вашего кода выполнятся что ли ?
Или вывести значения переменных до и после команд, которые их изменяют ?
18 ноя 14, 14:28    [16865519]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
monstrilla
Member

Откуда:
Сообщений: 129
Glory, лан, спасибо, я уже все починил :)

после вижуал-студии с отладчиком, решарпером и прочими вкусностями, лично мне очень неудобно и непривычно работать с СКЛ. более того, знаний у меня в нем практически нуль, все гуглю на ходу, поэтому уверенности нет как работает та или иная конструкция. т.е. пишешь в надежде, что заведется, а не пишешь и знаешь, что заведется (как если бы я писал на C# - WPF). вот.
18 ноя 14, 14:43    [16865653]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
Glory
Member

Откуда:
Сообщений: 104760
monstrilla
после вижуал-студии с отладчиком, решарпером и прочими вкусностями, лично мне очень неудобно и непривычно работать с СКЛ.

Что вам помешало воспользоваться отладчиком MSSQL ?

monstrilla
более того, знаний у меня в нем практически нуль, все гуглю на ходу, поэтому уверенности нет как работает та или иная конструкция. т.е. пишешь в надежде, что заведется, а не пишешь и знаешь, что заведется

Ваш SQL код противоречит самим принципам SQL.
SQL подразумевает работу с наборами данных, а не с отдельными записями в цкиках
18 ноя 14, 14:49    [16865721]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
monstrilla
Member

Откуда:
Сообщений: 129
Glory, очевидно, то, что у меня он в силу каких-то причин не работает.

автор
Ваш SQL код противоречит самим принципам SQL.


не сомневаюсь, ведь я новичок. возможно вы можете предложить более качественное с точки зрения SQL решение? всего-то нужно собрать тело запроса в зависимости от входных данных. я уверен, что для специалиста это простейшая задачка. на шарпе я метод, который собирает такую такую строку минут за пять напишу.
18 ноя 14, 15:01    [16865826]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
Glory
Member

Откуда:
Сообщений: 104760
monstrilla
ведь я новичок. возможно вы можете предложить более качественное с точки зрения SQL решение?

Вы слышали о том, что в запросе можно использовать несколько таблиц ?
А не "раскладывать" записи одной таблицы в длинный фильтр WHERE
18 ноя 14, 15:03    [16865844]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
monstrilla
Member

Откуда:
Сообщений: 129
Glory, про запрос из нескольких таблиц я слышал, но у меня данные тянутся из одной. просто условие на выборку формируется динамически. проиллюстрируйте кодом вашу мысль, пожалуйста.

я наврал, про пять минут, потратил десять :(
18 ноя 14, 15:16    [16865945]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
Glory
Member

Откуда:
Сообщений: 104760
monstrilla
росто условие на выборку формируется динамически.

У вас, где есть список, который вы сначала
- парсите в таблицу
- потом опять из таблицу собираете в строку

Справшивается - что мешает сразу иметь спискок в виде таблицы и делать соединение ?
18 ноя 14, 15:19    [16865979]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
monstrilla
Member

Откуда:
Сообщений: 129
Glory, нет. строка приходит извне, из приложения. сам я ее ни из чего не парсю. это мои входные данные.
18 ноя 14, 15:26    [16866054]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
Glory
Member

Откуда:
Сообщений: 104760
monstrilla
сам я ее ни из чего не парсю.

Ну да, ну да "- эта процедура разбивает строку по указанному разделителю. работает 100% корректно. "
18 ноя 14, 15:31    [16866097]     Ответить | Цитировать Сообщить модератору
 Re: Вложенный FETCH FROM дает странный результат  [new]
monstrilla
Member

Откуда:
Сообщений: 129
Glory, теперь понял о чем вы. я не скл-щик, у меня мозг по-другому думает, потому и подход такой.
18 ноя 14, 15:35    [16866128]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить