2017-10-12 10 views
0

私はレコードを移入しながら、ストアドプロシージャやビューを検索するが、無視して、コメントを

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%' 

としてクエリを持っても、コメントから移入されます。コメントから除外されないようにするにはどうすればよいですか?

解決策はありますか?

ありがとうございました

+1

可能な重複[Iはなく、コメント欄に、特定の文字列でコードを見つけることができる方法]( https://stackoverflow.com/questions/11928306/how-can-i-find-code-with-a-specific-string-but-not-in-comments) –

答えて

0

これは、単一のクエリで達成することはほぼ不可能に近いと思います。

[定義]には書式設定や改行などがないことに注意してください。コードは1行でコピーして、エディタに貼り付けます。

コメントが--で始まる場合は、どこで終了しますか?あなたは知る方法がありません。

対応する*/が見つかる可能性があるため、/*ではやや簡単ですが、検索文字列が複数回出現するという複雑な問題が残ります。

(あなたは大文字小文字を区別しないデータベースを持っている場合)あなたはPATINDEXを使用して、照合の大文字と小文字を区別したバージョンを指定して、もう少し運を持っている可能性があり、たとえば、あなたが唯一のEXECとないの出現は、例えば「実行」したい知っていますWHERE patindex('%EXEC%',defintion COLLATE SQL_Latin1_General_CP1_CS_AS) > 0

+0

結果をテキストではなくテキストにすると書式設定はpです[syscommentsからの改行をSQL​​ Serverに含めるにはどうすればいいですか?](https://stackoverflow.com/questions/1975468/how-do-i-include-the-newlines-from-syscomments-in- SQLサーバー)。 – Brett

0

最初は高速のvarchar(最大)文字列「スプリッタ」です。以下は、Jeff ModenのdelimitedSplit8Kのハッキングされたバージョンです。

  1. スプリットあなたのオブジェクトを(@searchstring)を検索するために入力文字列を受け入れます。関数の

    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]+'%'; 
    

    この関数を検索します行に入れる

  2. eコメントの一部ではない行の部分
  3. は、step3で作成された行を@searchstringを含むものにフィルタリングし、ObjectName(。)、行番号およびテキストを返します。

警告:

  1. 私はちょうど速いので、[N]はvarchar(max)を受け付けるT-SQLスプリッタが遅くなるエラー

  2. を許すと共に、これを投げました。 CLRスプリッタはおそらく高速ですが、私たちは何百万行も話していません。つまり、@maxLenで行数をフィルタリングすることで速度を上げることができます。 @maxlenは "無視し、@maxLen行数以上のオブジェクトを持つ"と言います。 nullの場合、オブジェクトは最大100K行まで検索されますが、これは調整できます。「 - 」

  3. この関数のアドレスは、コメントが持って見てシナリオコメント文字列の任意の場所:。コメントは別々の行に「/ 」と " \の間にネストされたとのシナリオを必要と いくつかのシナリオをコメントを抑制するために多くのコーディングが含まれます。

select col1, /* skipping col2 for now */ col3, col4 

/********* 
comments here 
*********/ 

例:

select * from dbo.SearchObjectDDLFor('nocount', NULL); 
select * from dbo.SearchObjectDDLFor('nocount', 2000); 
ようになります

結果:

enter image description here

関連する問題