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

Откуда: г.Чернигов
Сообщений: 101
Здравствуйте !

Есть функция. Вот ее фрагмент:

-- Курсор получен и наполнен отсортированными записями списка абонентов
   -- начало цикла перебора записей
   SET @nr = 0
   OPEN @TB
   FETCH NEXT FROM @TB INTO @TB_ID, @TB_Number, @ABONS_FIO, @ABONS_ADR, @ABONS_NOFIX, @REG_Name, @TO_Name, @POS_NAME
   WHILE (@@FETCH_STATUS = 0) 
      BEGIN 
        SET @nr = @nr + 1 -- счетчик записей общий
        FETCH NEXT FROM @TB INTO @TB_ID, @TB_Number, @ABONS_FIO, @ABONS_ADR, @ABONS_NOFIX, @REG_Name, @TO_Name, @POS_NAME
		IF @SearchColumn = 'TB_Number'
		   BEGIN
		     IF @SearchFlag = 1
			    IF @TB_Number = @SearchSample 
				  BEGIN
				    SET @Nrow = @nr
					SET @TbID = @TB_ID
					BREAK
                  END
             ELSE
             IF CHARINDEX(@SearchSample, @TB_Number) > 0
--             IF @TB_Number Like '%'+@SearchSample+'%' 
				  BEGIN
				    SET @Nrow = @nr
					SET @TbID = @TB_ID
					BREAK
                  END
		   END

При точном сравнении (@SearchFlag = 1) все работает как часики
А вот если задать частичное сравнение, то ни LIKE, ни CHARINDEX не "пашут". Результат всегда false, хотя при заданных параметрах (тех самых, что возвращают Ok если задан @SearchFlag = 1), запись найтись обязана

В чем косяк ?

Спасибо за ответы
23 июн 19, 20:05    [21913690]     Ответить | Цитировать Сообщить модератору
 Re: Не работает частичное сравнение в теле UDF  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
MsGuns,

Условия как-то не одинаковы для переменной
IF @SearchColumn = 'TB_Number'
23 июн 19, 20:44    [21913706]     Ответить | Цитировать Сообщить модератору
 Re: Не работает частичное сравнение в теле UDF  [new]
MsGuns
Member

Откуда: г.Чернигов
Сообщений: 101
TaPaK,"TB_Number" - имя колонки View. Функция используется для поиска в этом вью. Задается образец и имя столбца, где искать
23 июн 19, 21:01    [21913707]     Ответить | Цитировать Сообщить модератору
 Re: Не работает частичное сравнение в теле UDF  [new]
invm
Member

Откуда: Москва
Сообщений: 9299
MsGuns
Задается образец и имя столбца, где искать
MsGuns
             IF CHARINDEX(@SearchSample, @TB_Number) > 0
--             IF @TB_Number Like '%'+@SearchSample+'%' 

Это, типа, поиск в колонке, наименование которой задано @TB_Number?
23 июн 19, 21:36    [21913720]     Ответить | Цитировать Сообщить модератору
 Re: Не работает частичное сравнение в теле UDF  [new]
MsGuns
Member

Откуда: г.Чернигов
Сообщений: 101
invm,
@SearchSample - параметр функции, в котором ей передается образец для поиска (строка)
@TB_Number - имя локальной переменной, в которое FETCH запишет содержимое поля TB_Number очередной строки НД

Данная фраза означает: найти вхождение подстроки, заданной @SearchSample, в строку, записанную FETCH NEXT из поля датасета TB_Number в локальную переменную @TB_Number

Тут все верно, иначе не работала бы первая часть логики (там, где @SearchFlag = 1), а она-то как раз и работает !

Имя колонки, где искать, задается в параметре @SearchColumn
23 июн 19, 22:07    [21913725]     Ответить | Цитировать Сообщить модератору
 Re: Не работает частичное сравнение в теле UDF  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31339
MsGuns
В чем косяк ?
У вас ELSE к чему относится, к IF @TB_Number = @SearchSample ?
Не жалейте BEGIN ... END
23 июн 19, 22:53    [21913733]     Ответить | Цитировать Сообщить модератору
 Re: Не работает частичное сравнение в теле UDF  [new]
MsGuns
Member

Откуда: г.Чернигов
Сообщений: 101
alexeyvg
MsGuns
В чем косяк ?
У вас ELSE к чему относится, к IF @TB_Number = @SearchSample ?
Не жалейте BEGIN ... END


Огромное спасибо. После того, как добавил BEGIN .. END заработали все 3 варианта.

Тема закрыта
24 июн 19, 13:13    [21913999]     Ответить | Цитировать Сообщить модератору
 Re: Не работает частичное сравнение в теле UDF  [new]
a_voronin
Member

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

А вы не пытались решить вашу задачу без курсоров?
24 июн 19, 13:24    [21914008]     Ответить | Цитировать Сообщить модератору
 Re: Не работает частичное сравнение в теле UDF  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 940
a_voronin
MsGuns,
А вы не пытались решить вашу задачу без курсоров?

А зачем ему решать эту задачу, если задача стоит решить задачу.
За думать программистам, пишущим на курсорах, не доплачивают.
24 июн 19, 13:46    [21914052]     Ответить | Цитировать Сообщить модератору
 Re: Не работает частичное сравнение в теле UDF  [new]
MsGuns
Member

Откуда: г.Чернигов
Сообщений: 101
a_voronin
MsGuns,

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


Суть проблемы в том, что на странице (ASP.NET NVC) отображается только один лист из списка, выбранного по некоторым критериям (в данном случае - территориальным) и отсортированного по колонке, указанной пользователем. На странице имеется навигация по листам (вперед, назад, перейти к листу). То есть имеется некий "формат" общего списка, отображаемого на клиенте в определенном порядке.

Поиск записи нужен в двух случаях:
1) при добавлении нового абонента пользователь должен увидеть страницу, где новый абонент будет виден, а для этого нужен поиск по ID (для этого есть UDF, подобная этой, но там поиск по ID и все много проще.
2) Для реализации функции поиска по любой из колонок (именно эта UDF).

После нахождения записи списка (абонента) на клиенте должна отобразиться соотв.страница.

Постраничная "резка" выбранного и отсортированного списка выполняется на SQL-сервере ХП, но в эту ХП нужно "дать" номер листа. Вот его-то и определяет приведенная здесь UDF. Которая сначала выбирает весь список, сортирует его, затем ищет искомое, "перебирая" листы. Когда лист найден, он передается ХП (в одном из методов модели MVC) и полученный лист передается Razor, который "собирает" из записей страницу и отправляет ее на клиент браузеру.
24 июн 19, 13:50    [21914059]     Ответить | Цитировать Сообщить модератору
 Re: Не работает частичное сравнение в теле UDF  [new]
MsGuns
Member

Откуда: г.Чернигов
Сообщений: 101
Руслан Дамирович
a_voronin
MsGuns,
А вы не пытались решить вашу задачу без курсоров?

А зачем ему решать эту задачу, если задача стоит решить задачу.
За думать программистам, пишущим на курсорах, не доплачивают.


Ваше замечание в данном случае совершенно не к месту. Мне никто не платит и не "доплачивает". Алгоритмы выдумываю сам и реализую тоже сам. А что они не оптимальны, в этом у меня нет сомнений в большинстве случаев. Если можно решить описанную выше задачу без курсора, буду весьма обязан, если кто-то выскажет подходящие соображения.
24 июн 19, 13:54    [21914071]     Ответить | Цитировать Сообщить модератору
 Re: Не работает частичное сравнение в теле UDF  [new]
MsGuns
Member

Откуда: г.Чернигов
Сообщений: 101
MsGuns
a_voronin
MsGuns,

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


Суть проблемы в том, что на странице (ASP.NET NVC) отображается только один лист из списка, выбранного по некоторым критериям (в данном случае - территориальным) и отсортированного по колонке, указанной пользователем. На странице имеется навигация по листам (вперед, назад, перейти к листу). То есть имеется некий "формат" общего списка, отображаемого на клиенте в определенном порядке.

Поиск записи нужен в двух случаях:
1) при добавлении нового абонента пользователь должен увидеть страницу, где новый абонент будет виден, а для этого нужен поиск по ID (для этого есть UDF, подобная этой, но там поиск по ID и все много проще.
2) Для реализации функции поиска по любой из колонок (именно эта UDF).

После нахождения записи списка (абонента) на клиенте должна отобразиться соотв.страница.

Постраничная "резка" выбранного и отсортированного списка выполняется на SQL-сервере ХП, но в эту ХП нужно "дать" номер листа. Вот его-то и определяет приведенная здесь UDF. Которая сначала выбирает весь список, сортирует его, затем ищет искомое, "перебирая" листы. Когда лист найден, он передается ХП (в одном из методов модели MVC) и полученный лист передается Razor, который "собирает" из записей страницу и отправляет ее на клиент браузеру.


Поправка: вместо "Когда лист найден, он передается ХП" следует читать "Когда лист найден, его номер передается ХП"
24 июн 19, 13:57    [21914074]     Ответить | Цитировать Сообщить модератору
 Re: Не работает частичное сравнение в теле UDF  [new]
MsGuns
Member

Откуда: г.Чернигов
Сообщений: 101
Я отдаю себе отчет, что при поиске (по ID и по "маске") сервер ДВАЖДЫ делает одну и ту работу, выбирая нужные записи в нужном порядке, но "фишка" в том, что функционал поиска добавлен позднее, а менять модель MVC штука не тривиальная. Поэтому к уже имеющейся "постройке" был добавлен новый "флигелек" :) А сервер - он на то и сервер, чтобы работать (шутка, конечно, но в каждой шутке..)
24 июн 19, 14:03    [21914085]     Ответить | Цитировать Сообщить модератору
 Re: Не работает частичное сравнение в теле UDF  [new]
MsGuns
Member

Откуда: г.Чернигов
Сообщений: 101
Если что, вот сама хранимка:
-- =======================================================================================================
--  Процедура выбирает из списка абонентов записи по указанному вх.параметру RegionName или праметру TOName 
--  или все записи, если не указан ни тот, ни другой. 
--  Записи сортируются по колонке, указанной параметром colname,
--  Из отсортированного набота записей выбираются те, которые относятся к листу,
--  указанному параметром NList. Максимальное кол-во строк на листе определяется параметром QRows
-- =======================================================================================================
ALTER PROCEDURE [dbo].[UsSP_FetchTelBookByRegOrTO_List]
	@RegionName nvarchar(max),
	@TOName nvarchar(max),
    @colname sysname,   -- Наименование колонки для сортировки
	@Nlist int,         -- № листа
	@Qrows int          -- Количество строк на листе максимальное 

AS
BEGIN
	SET NOCOUNT ON;
    IF @RegionName > '' -- Указан регион
	   BEGIN
	    -- Извлечь записи по региону, отсортировать по колонке 
     	SELECT * FROM UsV_FullTelBook
		   WHERE REG_Name = @RegionName
           ORDER BY CASE
              WHEN @colname = 'TB_Number' THEN TB_Number
              WHEN @colname = 'ABONS_FIO' THEN ABONS_FIO
              WHEN @colname = 'ABONS_ADR' THEN ABONS_ADR
              WHEN @colname = 'ABONS_NOFIX' THEN ABONS_NOFIX
              WHEN @colname = 'REG_Name' THEN REG_Name
              WHEN @colname = 'TO_Name' THEN TO_Name
              WHEN @colname = 'POS_Name' THEN POS_NAME
              ELSE ABONS_FIO
          END
 		  -- вырезать указанный лист
          offset (@Nlist-1)*@Qrows rows fetch next @Qrows rows only
       END
    ELSE
       IF @TOName > '' -- Указано управление
	      BEGIN
     	   SELECT * FROM UsV_FullTelBook
    		   WHERE TO_Name = @TOName
               ORDER BY CASE
                  WHEN @colname = 'TB_Number' THEN TB_Number
                  WHEN @colname = 'ABONS_FIO' THEN ABONS_FIO
                  WHEN @colname = 'ABONS_ADR' THEN ABONS_ADR
                  WHEN @colname = 'ABONS_NOFIX' THEN ABONS_NOFIX
                  WHEN @colname = 'REG_Name' THEN REG_Name
                  WHEN @colname = 'TO_Name' THEN TO_Name
                  WHEN @colname = 'POS_Name' THEN POS_NAME
                  ELSE ABONS_FIO
               END
 		  -- вырезать указанный лист
          offset (@Nlist-1)*@Qrows rows fetch next @Qrows rows only
		  END
	   ELSE      -- Не указан ни регион, ни управление
	      BEGIN
     	   SELECT * FROM UsV_FullTelBook
               ORDER BY CASE
                  WHEN @colname = 'TB_Number' THEN TB_Number
                  WHEN @colname = 'ABONS_FIO' THEN ABONS_FIO
                  WHEN @colname = 'ABONS_ADR' THEN ABONS_ADR
                  WHEN @colname = 'ABONS_NOFIX' THEN ABONS_NOFIX
                  WHEN @colname = 'REG_Name' THEN REG_Name
                  WHEN @colname = 'TO_Name' THEN TO_Name
                  WHEN @colname = 'POS_Name' THEN POS_NAME
                  ELSE ABONS_FIO
               END
 		  -- вырезать указанный лист
          offset (@Nlist-1)*@Qrows rows fetch next @Qrows rows only
          END
END
24 июн 19, 14:08    [21914091]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить