2016-04-19 8 views
1

午後。どこでも探して、特定の値が1回のパスで外部キーで使用されました

私はSQL Server 2008/TSQLを使用しています。おそらく私はすべてのデータベース(私は読んでいるのみのユーザー)に書き込みアクセス権を持っていないことに注意することが重要です。私はdbへの書き込みアクセスを持っていないが、絶対に必要な場合は一時テーブルを挿入することができます。

私は正式な教育を受けていないことを皆に教えてもらいたいと言っています。うまくいけば、これは理にかなって - 私はなど、いくつかの語彙私がやろうとしています何の

範囲で不正確になることがあります。 1.テーブルから列内の特定のレコードID(値)(主キー)を選択し 2その特定の数/レコードIDは、すべての扶養に使用される。あなたは ... 3.戻りに/その値は一例として、だから、

を発見された回数のカウントがテーブル名とColumnNameには外部キーを探しますレコードIDに結び付けられた人に関する情報を持つテーブルがあります。 dbo.MemberInfo(レコードID、名前など)

部材(MemberInfo.RecordID)のID番号が他の テーブルで使用されている、と言う:dbo.AwardsのようHonoreeID] (dbo.Awards.HonoreeID = MemberInfo.RecordID)dbo.Address [としてMEMBERID ]百 (dbo.Address.MemberID = MemberInfo.RecordID)dbo.Contactとして潜在[PERSONID] (dbo.Contact.PersonID = MemberInfo.RecordID)...といくつかの他

I基本的にはすべてのテーブルを実行し、特定の値/レコードが何回使用されているかを確認したい。さて、これにいくつかの複雑さを加えるためには、私が扶養者を探している列が日々変わるかもしれないので、それは一般的である必要があります。 (例:私は明日イベントIDの扶養家族を探していてもよい。)

私の現在のプロセスは次のとおりです。選択 - 使用 レコードIDにリンクされているすべての外部キーで、私は -lookを必要とする人のIDを見つけるために、(プライマリキー)をdbo.Members - 外部キーのテーブル名と列をExcelにダンプします - WHERE = @変数を持つSELECT COUNTSの束を作成するために、検索と置換を行います。 - SQLに挿入し、変数を定義します初期ID番号と同じに設定してください

良い方法があるはずです。テーブル名と列を返す、テーブル/列で使用 1.クエリの外部キー:思考の私の行が/あるた

--DECLARE @Selected CHAR 
SELECT T.Name, C.Name 
--SET @Selected=(SELECT T.Name FROM sys.tables T) 
--CASE WHEN (T.NAME IS NOT NULL) THEN 1 
--ELSE '0' END AS 'MyTrial' 
FROM 
--sys.tables t 
sys.foreign_key_columns AS fk 
INNER JOIN sys.tables AS t ON fk.parent_object_id = t.object_id 
INNER JOIN sys.columns AS c ON fk.parent_object_id = c.object_id AND fk.parent_column_id = c.column_id 
WHERE Referenced_Object_ID=--Insert object ID here 

:私はエラーなし成功の多くと、次の多くのバリエーションを試みてきました名前を従属テーブルから取得する 2.これらの結果を、新しいクエリを作成して、該当する各テーブル/列の値のカウントを返すようにします。 3.テーブル名も同様に戻します。カウントを構成する詳細を調べる必要がある場合は、別のselectステートメントを入力してください。 テーブル名、COLUMNNAME、

理想的には列の値のカウント、値なし、テーブル名など:

だから私の結果は次のようになります。カウントが1未満の場合は返されます。

私のプロセスはゲートから非常に欠陥があるかもしれませんが、提供されたものは私が学ぶのに役立ちます。ありがとう!

+0

[sp_CascadingDataViewer](http://cascadingdataviewer.codeplex.com/)ビューアはすべてのデータを選択するだけでカウントが必要です。 – lad2025

+0

私の最初の勧告はしばらくの間、それを一般的にすることについて考えないようにすることです。変数を設定し、それを使用して正常にテストします。たとえば、AdventureWorksで462624691を使用すると、Address/StateProvinceIDとSalesTaxRate/StateProvinceIDが取得されます。だから私はそれが私が探しているデータかどうか自分自身に尋ねなければならない。それから、私が欲しいものを得るまでそれを微調整してください。それは、現在のクエリとプロセスの例を見るのに役立ちます。 – DaveX

答えて

0

以下のスクリプトはストアドプロシージャを使用しませんが、一時テーブルを使用しています。私が想像できる限り、その周りには方法はありません。私は比較的小さなテストデータベースで作業していましたが、それは私のために非常に迅速に実行されます。

これは動的SQLへの私の最初のベンチャーであり、SQLインジェクション攻撃などに対するこのコードの安全性について証言することはできません。私も独学です。

Declare @Primary_Table varchar(100) = ''; 
Declare @Column_Name varchar(100) = ''; 
Declare @Specific_Value int = ; 

IF(OBJECT_ID('tempdb..#Selected_Tables') is not null) 
Begin 
    Drop Table #Selected_Tables; 
End 

Select Distinct T.Name as Table_Name 
    , C.Name as Column_Name 
    , CAST(null as bigint) as Referenced_Records 

Into #Selected_Tables 

FROM sys.foreign_key_columns AS fk 
    INNER JOIN sys.tables AS t 
     ON fk.parent_object_id = t.object_id 
    INNER JOIN sys.columns AS c 
     ON fk.parent_object_id = c.object_id 
      AND fk.parent_column_id = c.column_id 
    Inner Join sys.tables AS t2 
     ON fk.referenced_object_id = t2.object_id 
    Inner Join sys.columns AS c2 
     on fk.referenced_column_id = c2.column_id 

Where t2.name = @Primary_Table 
    and c2.Name = @Column_Name; 

Declare @sqlCommand nvarchar(max); 
Declare @Unprocessed_Records int = (Select Count(1) 
            From #Selected_Tables 
            Where Referenced_Records is null); 
Declare @Processing_Table varchar(1000) = (Select Top 1 Table_Name 
              From #Selected_Tables 
              Where Referenced_Records is null); 
Declare @Processing_Column varchar(1000) = (Select Top 1 Column_Name 
              From #Selected_Tables 
              Where Referenced_Records is null 
               and Table_Name = @Processing_Table); 

While @Unprocessed_Records > 0 
Begin 
    Set @sqlCommand = 'Update #Selected_Tables ' 
         + 'Set Referenced_Records = (Select Count(1) ' 
         + 'From ' + @Processing_Table + ' ' 
         + 'Where ' + @Processing_Column + ' = ' + CAST(@Specific_Value as nvarchar(1000)) + ') ' 
         + 'Where Table_Name = ''' + @Processing_Table + ''' ' 
         + 'and Column_Name = ''' + @Processing_Column + ''';' 

    Exec (@sqlCommand); 

    Set @Unprocessed_Records = (Select Count(1) 
            From #Selected_Tables 
            Where Referenced_Records is null); 
    Set @Processing_Table = (Select Top 1 Table_Name 
              From #Selected_Tables 
              Where Referenced_Records is null); 
    Set @Processing_Column = (Select Top 1 Column_Name 
              From #Selected_Tables 
              Where Referenced_Records is null 
               and Table_Name = @Processing_Table); 
End; 

Select * From #Selected_Tables; 
関連する問題