Фильтруй!

Эта статья — продолжение темы, начатой в «NAV+SQL: подружки-хохотушки» и «Как мы победили»

По поводу преобразования фильтра поля в условие SQL-запроса – Петр «grif» Иванов (grif@bk.ru) любезно разрешил нам опубликовать его собственную функцию по преобразованию фильтра NAV в SQL. Вот она:

CREATE FUNCTION dbo.Fn_Filter_Convert (@variable  VARCHAR(20), @cd VARCHAR(250))

RETURNS VARCHAR(1024)
AS

BEGIN
  -- Функция преобразует фильтр Navision в операторы SQL для использования в WHERE
  DECLARE @str VARCHAR(1024);
  DECLARE @i INT, @pos INT, @pos2 INT;
  DECLARE @tmp VARCHAR(250);
  DECLARE @var VARCHAR(100)

  IF @cd = '' RETURN @variable + ' LIKE ''%'''

  SET @var = '[#VAR#]'
  SET @str = @cd
  SET @str = REPLACE(@str, '%', '[%]')
  SET @str = REPLACE(@str, '_', '[_]')
  SET @str = REPLACE(@str, '*', '%')
  SET @str = REPLACE(@str, '?', '_')
  SET @str = REPLACE(@str, '|', ''' OR ' + @var + ' LIKE ''')
  SET @str = REPLACE(@str, '&', ''' AND ' + @var + ' LIKE ''')
  SET @str = @var + ' LIKE ''' + @str + ''''
  SET @str = REPLACE(@str, ')''', ''')')

  WHILE CHARINDEX(@var+' LIKE ''(', @str) <> 0
    SET @str = REPLACE(@str,@var+' LIKE ''(', '(' + @var + ' LIKE ''')

  SET @str = REPLACE(@str, 'LIKE ''<>','NOT LIKE ''')

  -- Заменяем NOT LIKE на <>, если нет масок % и _
  SET @i  = 1
  SET @pos = 0
  WHILE @i <> 0 BEGIN
    SET @i = CHARINDEX('NOT LIKE ''',@str,@pos)
    IF @i <> 0 BEGIN
      SET @pos = CHARINDEX('''',@str,@i+10)
      SET @tmp = SUBSTRING(@str,@i,@pos-@i+1)
      IF CHARINDEX('%',@tmp) = 0 AND CHARINDEX('_',@tmp) = 0 BEGIN
        SET @str = STUFF(@str,@i,@pos-@i+1,STUFF(@tmp,1,9,'<>'))
      END
    END

  END

  -- Заменяем LIKE на =, если нет масок % и _
  SET @i  = 1
  SET @pos = 0
  WHILE @i <> 0 BEGIN
    SET @i = CHARINDEX('LIKE ''',@str,@pos)
      IF @i <> 0 BEGIN
        SET @pos = CHARINDEX('''', @str, @i+6)
        SET @tmp = SUBSTRING(@str, @i, @pos-@i+1)
        IF CHARINDEX('%',@tmp) = 0 AND CHARINDEX('_',@tmp) = 0 BEGIN
          SET @str = STUFF(@str, @i, @pos-@i+1, STUFF(@tmp,1,5,'='))
        END
      END
    END

  -- Заменяем .. на BEETWEEN AND, если нет LIKE
  SET @i  = 1
  SET @pos = 0
  WHILE @i <> 0 BEGIN
    SET @i = CHARINDEX(@var+' =''',@str,@pos)
    IF @i <> 0 BEGIN
      SET @pos = CHARINDEX('''',@str,@i+LEN(@var)+3)
      SET @tmp = SUBSTRING(@str,@i,@pos-@i+1)
      SET @pos2 = CHARINDEX('..',@tmp)
      IF CHARINDEX('%',@tmp) = 0 AND CHARINDEX('_',@tmp) = 0 AND @pos2 <> 0 BEGIN
        SET @tmp = @var + ' BETWEEN ' + SUBSTRING(@tmp,LEN(@var)+3, @pos2 - LEN(@var)-3)
        + ''' AND ''' + SUBSTRING(@tmp,@pos2+2,LEN(@tmp))
        SET @str = STUFF(@str, @i, @pos-@i+1, @tmp)
      END
    END
  END

  SET @str = REPLACE(@str, '#VAR#', @variable)

  RETURN(@str)

END

Автор:

В области Navision - с 2003 года. Профессиональные интересы: NAV, MS SQL, .NET, BPMN, IT-менеджмент. Предметная область: логистика, финансы, склады, 3PL.

Количество статей, опубликованных автором: 86.

Добавить комментарий