2017-03-31 2 views
1

現在データ移行プロジェクトではデータの使用状況を分析する必要があります。つまり、どのテーブルと列が使用され、移行する必要があるかを把握する必要があります。データは時代遅れです。 ストアドプロシージャに基づいて多くのSSRSレポートを用意するだけでなく、何千ものTSQLスクリプトを使用してアドホック分析を行います。手でひとつずつ分析するのは事実上不可能です。TSQLスクリプトを解析してテーブルと列の使用を返します

私はこれらのスクリプトを解析し、スクリプトが使用しているデータを返す方法を探しました。私はスクリプトからテーブルを抽出するEditPadにマクロを書き込むことができましたが、私は同じことをカラムではしませんでした。ここでの主な問題は、エイリアス、CTE、およびスクリプト内の列名と他のコマンドとの区別です。

単純な正規表現ベースのマクロとは対照的に、SQL Serverではスクリプト - >実行計画で使用される列が明確に理解されている必要があります。 この機能を私たちの目的に使用できる方法はありますか?それとももっと良い:私たちが必要とすることができるサードパーティツールがありますか?これまでのところ、何も見つかりませんでした。

非常に多くのアドバイスをお願いします。

+0

手順は少なくともテーブルを取得するには悪くないが、列は別の話です。 sys.sysdependsを使用しても、オブジェクトが取得されます。これらのオブジェクトはテーブルでも構いませんが、関数、ビューなどであっても分析する必要があります。そして、アドホックなクエリになると、それを手動で解析することが正確に不足することはほとんど不可能になります。 –

+0

RedGate SQL Searchには、列名がストアドプロシージャで参照されている場所を見つけることができる影響分析機能があります。あなたのアドホックなクエリに役立つかどうかは分かりません。 http://www.red-gate.com/products/sql-development/sql-search/ – mallan1121

答えて

2

実行計画からテーブルと列を解析することは可能かもしれませんが、簡単に行うことはできません。 (私は誰かがそれを綴る場合にはこの投稿を見ています)。サードパーティのツールかもしれないが、これを行うにはかもしれない。私の経験から、私はこれが実現可能ではないかもしれないと思っています。あなたが必要とする限りではありません。

横方向のアプローチ:データにアクセスする可能性のあるすべての試みがヒットしたことを知るために、データベースに対して「すべてを実行」することができますか?ある場合:

  • データベースのコピーを作成します。
  • クエリが機能するために必要なだけのデータを含めます。使用されるログインが
  • 実行最初のクエリにアクセスできないよう
  • (だから、バックアップ/復元、または「スクリプト実行」データベースにSSMSを使用するか)
  • 設定のセキュリティ。これは失敗します。決定どのテーブルや列それがにアクセスする必要があります。テーブルのみと列へのアクセスを許可します。
  • を実行し、次のクエリ。繰り返します。
  • オッズは、あなたが
  • 保存クエリのバッチを実行し、ひとまとめにテーブル/列を追加することができます既知の/明白なテーブルを最初に有効にすることで時間がかかる
  • 関連するすべてのテーブルとカラムが有効になっているため、すべてのクエリを正常に実行できるようになると、最小限の設定になります。

事は...ということを書かれた、私は(それは完全にあなたが望む?トリガ?シノニムについてと、どのような仕事をしなければならない何かに依存?)ので、多くの潜在的な注意点、フリンジ例と落とし穴を見ている私がしなければならないことそれが努力する価値があるかどうか疑問に思う。データベースの半分を切り捨てると確信しているなら、それを試してみてください。しかし、10%の削減のためには、それは価値がありません。 (10%削減のために、ちょうど最も疑わしいテーブルの名前を変更しようとすると何が起こるかを参照してください。)

+0

ありがとう、私たちが自動化されたソリューションを開発できない場合、これは良い代替ソリューションです。 –

1

部分的な答え:

this articleに基づいて、それはPowerShellを使用することが可能です(またはコンパイル。Microsoftのツールで使用されているように、SQL文の構文解析ツリーを生成するためにMicrosoft.SqlServer.Management.SqlParserを使用します。

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Management.SqlParser") | Out-Null 
$ParseOptions = New-Object Microsoft.SqlServer.Management.SqlParser.Parser.ParseOptions 
$ParseOptions.BatchSeparator = 'GO' 
$ParseOptions.CompatibilityLevel = [Microsoft.SqlServer.Management.SqlParser.Common.DatabaseCompatibilityLevel]::Current 
$ParseOptions.IsQuotedIdentifierSet = $true 
$ParseOptions.TransactSqlVersion= [Microsoft.SqlServer.Management.SqlParser.Common.TransactSqlVersion]::Current 

set-psdebug -strict 

#$SQL=get-content $Args[0] |foreach-object{"$_`n"} 

$SQL = "SELECT c.COLUMN_NAME, 
     c.TABLE_NAME, 
     t.TABLE_SCHEMA, 
     t.TABLE_TYPE, 
     t.TABLE_NAME AS t2 
FROM INFORMATION_SCHEMA.TABLES AS t 
JOIN INFORMATION_SCHEMA.COLUMNS AS c 
ON c.TABLE_NAME = t.TABLE_NAME 
AND c.TABLE_SCHEMA = t.TABLE_SCHEMA 
AND c.TABLE_CATALOG = t.TABLE_CATALOG 
" 

$Script=[Microsoft.SqlServer.Management.SqlParser.Parser.Parser]::Parse($SQL, $ParseOptions) 

$flags = [System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::NonPublic 
$Script.GetType().GetProperty("Script", $flags).GetValue($Script).Xml 

ローカルバージョンのSSMS 2016とSQL Server 2014がインストールされていますが、これは他のものをインストールすることなく動作しました。

これは、まだツリーの解釈の点でかなりの仕事を残していますが、あなたはそれを利用できるかもしれません。

+0

大変ありがとう、これは有望そうです。確かにこれを試してみます。 –

0

私の同僚は、XMLクエリを使用して実行計画を解析するの巧妙な考えを持っていた:

実行計画は、XMLとして保存し、その後のレベルの深さ/数を減らすために、ウェブサイト上で濾過する必要があり、あってはならないより大きく128:

http://xmltoolbox.appspot.com/

1. Paste the XML 
2. Add Column Reference as a filter 
3. Format xml 
4. Save it again as flatfile 

濾過XML読み取りおよびSQLで処理することができる。

DECLARE @xml xml = (
       SELECT CAST(BulkColumn AS XML) FROM OPENROWSET(  
       BULK 'c:\temp\Herkunftsselect_filtered.xml',  
       SINGLE_BLOB) AS ExecPlan 
   ); 

WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS SP) 
SELECT DISTINCT 
       'Database' = n.xml.value('./@Database','nvarchar(100)'), 
       'Schema' =          n.xml.value('./@Schema','nvarchar(100)'), 
       'Tabelle' =         n.xml.value('./@Table','nvarchar(100)'), 
       'Alias' =           n.xml.value('./@Alias','nvarchar(100)'), 
       'Column' =          n.xml.value('./@Column','nvarchar(100)') 
FROM @xml.nodes('/Root/SP:ColumnReference') n(xml) 
WHERE n.xml.value('./@Column','nvarchar(100)') NOT LIKE 'Expr%' 
  AND n.xml.value('./@Column','nvarchar(100)') NOT LIKE 'Chk%' 
  AND n.xml.value('./@Column','nvarchar(100)') NOT LIKE 'Bitmap%' 
  AND n.xml.value('./@Column','nvarchar(100)') NOT LIKE 'IsBaseRow%' 
  AND n.xml.value('./@Column','nvarchar(100)') NOT LIKE 'Union%' 
  AND n.xml.value('./@Column','nvarchar(100)') NOT LIKE 'Segment%' 

ORDER BY 1,2,3,4,5 

ここで欠けている部分は、スクリプトファイルをループして実行計画を生成し、XMLをフィルタリングしてクエリを実行するプロセスを完全に自動化する方法だけです。私の同僚が考えた方法は、すべてのスクリプトファイルを1つの大きなファイル(ファイルをループして追加する)にマージして手動のプロセスを1回だけ実行する必要があるということです。

関連する問題