Фильтруй!
Эта статья — продолжение темы, начатой в «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
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.