我有一个查询
select
definition
from
sys.objects so
join
sys.sql_modules ssmsp on so.[object_id] = ssmsp.[object_id]
where
so.type in ('v', 'p')
where
definition like '%exec%'
在填充记录时,也会从评论中填充。如何避免过滤评论?
有没有解决方案?
由于
答案 0 :(得分:0)
我认为在单个查询中几乎不可能实现这一目标。
请记住[定义]没有格式,没有换行符等。代码是一行(复制一行并将其粘贴到编辑器中)。
如果评论以--
开头,那么它会在哪里结束?你无从知晓。
使用/*
会更容易一些,因为您可以找到相应的*/
,但搜索字符串的多次出现仍然会增加复杂性。
使用PATINDEX
并指定一个区分大小写的排序规则(如果您有一个不区分大小写的数据库),您可能会有更多的运气,例如,您知道只希望出现EXEC
而不是"执行"例如WHERE patindex('%EXEC%',defintion COLLATE SQL_Latin1_General_CP1_CS_AS) > 0
答案 1 :(得分:0)
首先是快速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 '%'+@searchstring+'%';
此功能:
<强>注意事项:强>
我只是快速地把它扔到一起,原谅任何错误
接受[n] varchar(max)的t-sql拆分器会很慢。 CLR分离器可能会更快但我们不会谈论数百万行。也就是说,您可以通过使用@maxLen过滤行数来加快速度。 @maxlen说&#34;忽略和具有更多@maxLen行数的对象。&#34;当为null时,它将搜索长达100K行的对象(但这可以调整)。
此功能可以解决评论所看到的评论情况&#34; - &#34;字符串中的任何位置:以及评论嵌套在&#34; / &#34;之间的情况。和&#34; \在不同的行上。 一些需要更多编码来抑制评论的场景包括:
select col1, /* skipping col2 for now */ col3, col4
和
/*********
comments here
*********/
<强>示例:强>
select * from dbo.SearchObjectDDLFor('nocount', NULL);
select * from dbo.SearchObjectDDLFor('nocount', 2000);
结果将类似于: