首先使用快速varchar(max)字符串“splitter”。以下是Jeff Moden的delimitedSplit8K的黑客版本。
IF OBJECT_ID('dbo.DelimitedSplit2B','IF') IS NOT NULL DROP FUNCTION dbo.DelimitedSplit2B;
GO
CREATE FUNCTION dbo.DelimitedSplit2B
(
@pString varchar(max),
@pDelimiter char(1)
)
RETURNS TABLE WITH SCHEMABINDING AS RETURN
WITH L1(N) AS
(
SELECT N
FROM (VALUES
(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),
(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),
(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),
(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),
(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),
(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),
(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),
(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),
(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),
(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),
(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(N)
), --216 values
cteTally(N) AS
(
SELECT 0 UNION ALL
SELECT TOP (DATALENGTH(ISNULL(@pString,1))) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM L1 a CROSS JOIN L1 b CROSS JOIN L1 c
--2,176,782,336 rows: enough to handle 2,147,483,647 characters (the varchar(max) limit)
),
cteStart(N1) AS
(
SELECT t.N+1
FROM cteTally t
WHERE (SUBSTRING(@pString,t.N,1) = @pDelimiter OR t.N = 0)
)
SELECT
ItemNumber = ROW_NUMBER() OVER(ORDER BY s.N1),
Item = SUBSTRING(@pString,s.N1,ISNULL(NULLIF((LEAD(s.N1,1,1)
OVER (ORDER BY s.N1) - 1),0)-s.N1,DATALENGTH(ISNULL(@pString,1))))
FROM cteStart s;
下一步的功能来搜索您的DDL
create function dbo.SearchObjectDDLFor (@searchstring varchar(100), @maxLen int)
returns table as return
select objectName, lineNumber, lineText
from
(
select
objectName = ss.[name]+'.'+so.[name],
lineNumber = itemnumber,
lineText = substring(t.item, 1, isnull(nullif(charindex('--', t.item),0)-1, 8000)),
isLongComment =
sum
(-- this will assign a 1 for everything
case when t.item like '/*%' then 1
when t.item like '*/%'then -1
else 0 end
) over (partition by so.[name] order by itemnumber)
from sys.objects so
join sys.sql_modules ssmsp on so.[object_id] = ssmsp.[object_id]
join sys.schemas ss on so.schema_id = ss.schema_id
cross apply dbo.delimitedSplit2B(definition, char(10))
cross apply (values (rtrim(ltrim(replace(item,char(13),''))))) t(item)
where so.type in ('v', 'p')
and len(definition) < isnull(@maxLen,100000) -- character limit is @maxLen (100K default)
) splitLines
where isLongComment = 0 and lineText not like '--%' and lineText <> '*/'
and lineText like '%'[email protected]+'%';
此功能:
- 接受输入要搜索的字符串(@searchstring)
- 将您的对象成行
- 仅返回第e部分行不是注释
- 将步骤3中创建的行过滤为包含@searchstring的行,并返回ObjectName(。),行号和文本。
注意事项:
我只是把这个一起快速所以请原谅任何错误
一个T-SQL分路器接受[N] VARCHAR(最大值)将是缓慢的。 CLR分离器可能会更快,但我们并不是在谈论数百万行。也就是说,你可以通过使用@maxLen过滤行数来加速它。 @maxlen说:“忽略和更多@maxLen行数的对象。”当它为空时,它将搜索长达100K行的对象(但可以调整)。
这个函数地址评论场景中的意见看有没有“ - ”字符串中的任何地方:其中嵌套上线“/ ”和“ \之间的意见和方案 需要几个方案更多的编码来抑制意见包括:
select col1, /* skipping col2 for now */ col3, col4
和
个
/*********
comments here
*********/
例子:
select * from dbo.SearchObjectDDLFor('nocount', NULL);
select * from dbo.SearchObjectDDLFor('nocount', 2000);
结果看起来类似:
的可能重复[我怎样才能找到一个特定的字符串代码,而不是在评论( https://stackoverflow.com/questions/11928306/how-can-i-find-code-with-a-specific-string-but-not-in-comments) –