2016-06-15 3 views
0

Я использую SQL Server 2014, и мне нужно найти все хранимые процедуры, которые используют функцию Left(Column, 5)SQL Server: найти все хранимые процедуры, содержащие Left (колонка, 5)

Например, он должен найти

left(jobno, 5) 

но не

left(jobno, 50) 

он должен найти

left(ZIP, 5) 

Первоначально я думал, что я мог бы использовать

Like '%Left(%,5)%' 

но не возвращает записи

Благодарности

знак

+0

Как насчет 'LEFT (xxx, 5)' с пробелом?Также это будет соответствовать «LEFT (x, 100), SOMEFUNC (5)» – DavidG

ответ

2

Это немного дорогостоящий подход, но служит цели. Он будет работать, когда функция Length to LEFT задана как Number, но не выполняется, когда Length задается с использованием переменных или некоторых других выражений. Надеюсь это поможет.

DECLARE @Search VARCHAR(10) = '5' 

;WITH CTE AS 
(
    SELECT 1 AS Lvl, o.name, o.type, o.Object_ID 
     ,NULLIF(CHARINDEX('left(',definition),0) AS LeftPos 
     ,CHARINDEX(')', definition, (NULLIF(CHARINDEX('left(',definition),0))) AS LastIndex 
     ,LTRIM(RTRIM(SUBSTRING(definition, CHARINDEX(',', definition, (NULLIF(CHARINDEX('left(',definition),0))) + 1, CHARINDEX(')', definition, (NULLIF(CHARINDEX('left(',definition),0))) - CHARINDEX(',', definition, (NULLIF(CHARINDEX('left(',definition),0))) -1))) AS LeftLen 
    FROM sys.all_sql_modules m 
    INNER JOIN sys.objects o on o.Object_ID = m.Object_ID 
    WHERE CHARINDEX(')', definition, (NULLIF(CHARINDEX('left(',definition),0))) - CHARINDEX(',', definition, (NULLIF(CHARINDEX('left(',definition),0))) -1 > 0 

    UNION ALL -- get all occurunces or Left 
    SELECT 2 AS Lvl, o.name, o.type, o.Object_ID 
     ,NULLIF(CHARINDEX('left(',definition,LastIndex),0) AS LeftPos 
     ,CHARINDEX(')', definition, (NULLIF(CHARINDEX('left(',definition,LastIndex),0))) AS LastIndex 
     ,LTRIM(RTRIM(SUBSTRING(definition, CHARINDEX(',', definition, (NULLIF(CHARINDEX('left(',definition,LastIndex),0))) + 1, CHARINDEX(')', definition, (NULLIF(CHARINDEX('left(',definition,LastIndex),0))) - CHARINDEX(',', definition, (NULLIF(CHARINDEX('left(',definition,LastIndex),0))) -1))) AS LeftLen 
    FROM sys.all_sql_modules m 
    INNER JOIN sys.objects o ON o.Object_ID = m.Object_ID 
    INNER JOIN CTE c ON c.Object_ID = m.Object_ID 
     AND c.LastIndex IS NOT NULL AND ISNULL(c.LeftLen,@Search) <> @Search    
    WHERE CHARINDEX(')', definition, (NULLIF(CHARINDEX('left(',definition,LastIndex),0))) - CHARINDEX(',', definition, (NULLIF(CHARINDEX('left(',definition,LastIndex),0))) -1 > 0 
) 
SELECT * FROM CTE 
WHERE LeftLen = @Search 
OPTION (MAXRECURSION 10000); 
1

SQL, к сожалению, не может иметь дикие карты в середине строки. Попробуйте

(column name) like '%left(%' and (column name) like '%,5)%' 

Это должно дать вам желаемый результат

+0

Это также будет соответствовать «LEFT (x, 100), SOMEFUNC (5)», и действительно наоборот «SOMEFUNC (5), LEFT (x, 100) ' – DavidG

1

Это одна из причин, почему мы реализовали регулярное выражение с использованием SQL CLR. Тем не менее, вы можете сделать еще пару вещей, чтобы решить вашу проблему.

Вы могли бы сделать что-то вроде этого ...

select * 
from sys.objects 
where object_definition(object_id) like '%left(%,5)%'; 

Или что-то подобное, что кажется немного чище, однако, иногда я использую выше метод, потому что мне нужна некоторые другие вещи, которые охватывают от SYS .объекты ...

select * 
from sys.sql_modules 
where definition like '%left(%,5)%'; 

Другой альтернативой является составление списка возможных имен столбцов. Если у вас нет проблем с перекрестными базами данных, вы можете захотеть использовать sys.columns, sys.all_columns или даже sys.parameters в качестве списка выбора. Чтобы сделать это, вы могли бы сделать что-то вроде этого ...

select * 
from sys.sql_modules m 
cross join (
    select distinct name 
    from sys.all_columns) c 
where definition like '%left(' + c.name + ',5)%'; 

Еще одна вещь, чтобы рассмотреть пробелы, которые, опять-таки, это еще одна причина для реализации регулярных выражений с использованием SQL CLR. Например, в приведенном выше случае кто-то может помещать пробел между «,» после имени столбца и числом «5». Но, с учетом сказанного, вышеупомянутые запросы должны стать очень близкими.

Надеюсь, это поможет.

1

Вы могли бы использовать что-то вроде

LIKE '%LEFT([a-z],5)%' 
Смежные вопросы