0

BackDrop:プロセスで多くのアカウントが失われた理由を調査しています。データがある限り戻ってきました。現在、何らかの理由で見落とされたアカウントのかなり大きなリストがあります。さて、あまり詳細に立ち入らないこのプロセスは非常に複雑であり、なぜこれらのアカウントとこれらのアカウントだけが見落とされたのかを知る必要があります。他のデータベースと同様に、常に実行される多くの自動化された手順があるため、この時点では、これらのアカウントが失われる原因となったのは一体何であるかはわかりません。これを解決するための私の唯一の賭けは、これらのアカウント間の類似点を見つけることです。明らかに、私たちはより一般的な場所を調べてみましたが、それ以来何も見つかりませんでした。

問題:SQLを使用して、データベース内のすべてのテーブル名と列名を返したいのですが、これらのアカウントのリストは、テーブルの1つまたは複数の列で同じ値を持っています。テーブル名や列などを検索するためのクエリを作成しましたが、すべてをまとめて1つのクエリを作成し、必要なすべての結果を得る方法がわかりません。カーソルを使用する必要があり、多くの内部結合が必要になることは確かですが、これをどのように行うべきかわかりません。
繰り返しますが、アカウント番号123456と654321があり、データベースに3,000のテーブルがあり、AccountNumber、AccountNum、またはAccountのいずれかの名前のアカウント番号への列参照があることがわかっているとします。AccountNumber、AccountNum、またはAccountの値が123456または654321の列を持つすべてのテーブルを検索して見つけたいと思います。次に、これらのテーブルを使用して、テーブルごとに行を取得します。 AccountNumber、AccountNum、またはAccountの値が123456と654321のいずれかである場合、これらの各行について、各行の各列をチェックして、アカウント番号123456の行の列がアカウント番号654321の行、その場合は、列名とテーブル名を返します。このようにして、これらのアカウントに共通するものを確認できます。

高度な部分:

貧しい人々が上記を実行できる場合は、テーブル名とそれがいつ更新されたかを返すクエリも作成したいと思います。各テーブルの各列をチェックして更新された値を取得します。列のタイプが「timestamp」またはデフォルト値の「GetDate()」の場合、その列は更新されたものとして使用されます。最終結果セットでは、更新されて注文するアカウント番号に対してすべての変更が行われたことを示しています。

4

2 に答える 2

0

ある時点で、Guidに対してこれを実行する必要がありました。これは、GUIDを使用するためのスクリプトです。1秒で、ニーズに合わせて変更する作業を行います。

DECLARE @table VARCHAR(100)
DECLARE @column VARCHAR(100)
DECLARE @value INT

SET @value = '06B8BD6C-A8EC-4EB3-9562-6666EE86952D'

DECLARE table_cursor CURSOR
FOR select tbl.Name, cols.name as TableName  FROM sys.columns cols  JOIN 
    sys.tables tbl on cols.object_id = tbl.object_id
    where system_type_id = 36

OPEN table_cursor 
FETCH NEXT FROM table_cursor 
INTO @table, @column;

WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @SQL NVARCHAR(1000)

SET @SQL = 'SELECT ''' + @Table + '''  AS TBL,''' + 
@column + ''' AS COL FROM [' + @table + '] 
WITH(NOLOCK) WHERE ' + @column + ' = ''' + CAST(@value AS VARCHAR(50)) + ''''

    print @sql
EXEC sp_executesql @Sql

FETCH NEXT FROM table_cursor 
INTO @table, @column;

END

CLOSE table_cursor
DEALLOCATE table_cursor

フィールド名を検索するために処理するように更新されました:

DECLARE @table VARCHAR(100)
DECLARE @column VARCHAR(100)
DECLARE @value UNIQUEIDENTIFIER

SET @value = --ENTER YOUR ACCOUNT NUMBER HERE

DECLARE table_cursor CURSOR

select tbl.Name, cols.name as TableName  FROM sys.columns cols  JOIN 
    sys.tables tbl on cols.object_id = tbl.object_id
    where cols.Name = 'AccountNumber' 
    OR cols.Name = 'AccountNum' OR cols.Name = 'Account'

OPEN table_cursor 
FETCH NEXT FROM table_cursor 
INTO @table, @column;

WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @SQL NVARCHAR(1000)

SET @SQL = 'SELECT ''' + @Table + '''  AS TBL,''' + @column + 
    ''' AS COL FROM [' + @table + '] WITH(NOLOCK) 
WHERE ' + @column + ' = ''' + CAST(@value AS VARCHAR(50)) + ''''
    print @sql
    EXEC sp_executesql @Sql

FETCH NEXT FROM table_cursor 
INTO @table, @column;

END

CLOSE table_cursor
DEALLOCATE table_cursor
于 2012-05-11T14:14:07.503 に答える
0

最初のアプローチは素朴です(私はT-SQLに慣れていないので、PL / SQLをもっとやりました)、さらに先に進むのに役立つかもしれません.SQL SERVER 2008でテストされています.2005年に動作することを願っています...)

したがって、2 つのプロシージャを作成し、一方が他方を呼び出します。

提供されたコードは、2 つの異なる ID について、関連するすべてのフィールド (Account、AccountNum、AccountNumber) について、一度にのみチェックできます。

アイデア (AccountNumber 列のチェック)

指定された 3 つの名前のいずれかを持つ列を持つテーブル (データベース テーブルをリストするテーブル INFORMATION_SCHEMA.columns 内) を見つけます。

見つかったすべてのテーブルに対して: 動的クエリを作成します:

select count(*) from <THE_TABLE> where <Account_column_name> IN (123456 654321);

2 つの結果が得られた場合 (ID が両方ともテーブルに存在することを意味します)、次のパラメーターを使用して 2 番目のプロシージャを起動します: @TableName = <THE_TABLE>@FieldName = <Account_column_name>@FirstId = 123456@SecondId = 654321

<THE_TABLE>(再び INFORMATION_SCHEMA.columns で)の列名を見つけます。見つかったすべての列について: 動的クエリを作成します

select count(*) from <THE_TABLE> as T1
inner join <THE_TABLE> as T2 on T1.<COLUMN_NAME> = T2.<COLUMN_NAME>
where T1.<Account_column_name>= 123456
and T2.<Account_column_name>= 654321

の場合count(*) = 1、指定された ID に対して同じテーブルの同じ列に同じ値が存在することを意味します。

その場合、印刷<THE_TABLE>して<THE_COLUMN>

検索を開始するには、SQL Management Studio で、make するだけです。

EXEC GetSimilarValuesForFieldAndValue  123456, 654321

「メッセージ」部分には、「結果」のリストが必要です。

CREATE procedure [dbo].[GetSimilarValuesForFieldAndValue](@FirstId int, @SecondId int)
AS


DECLARE @sql nvarchar(MAX);
DECLARE @params NVARCHAR(MAX);
DECLARE @Count int;
DECLARE @Name NVARCHAR(MAX);
DECLARE @FieldName NVARCHAR(MAX);

DECLARE db_cursor CURSOR for
select TABLE_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.columns
where COLUMN_NAME IN('Account', 'AccountNumber', 'AccountNum');



OPEN db_cursor
FETCH next from db_cursor into @Name, @FieldName
while @@FETCH_STATUS = 0
 begin
     select @sql = 
     N' SELECT @Count=Count(*) FROM ' + @Name +
     N' WHERE ' +@FieldName+' IN (@FirstId,@SecondId)'
     SELECT @params = N'@FieldName NVARCHAR(MAX), @FirstId int, @SecondId int, @Count int out'
     EXEC sp_executesql @sql, @params, @FieldName, @FirstId, @SecondId, @Count OUT
     if (@Count = 2)
     begin
      exec dbo.CompareFields @Name, @FieldName, @FirstId, @SecondId
     end
     FETCH NEXT FROM db_cursor INTO @Name, @FieldName    
 end
 close db_cursor
 DEALLOCATE db_cursor
GO

二つ目:

CREATE procedure [dbo].[CompareFields](@TableName NVARCHAR(MAX), @FieldName NVARCHAR(MAX), @FirstId int, @SecondId int)  
as


DECLARE @ColumnName NVARCHAR(MAX)
DECLARE @Sql NVARCHAR(MAX)
DECLARE @Params NVARCHAR(MAX)
DECLARE @Count int


DECLARE cfCursor CURSOR FOR
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = ''+@TableName+' '
AND COLUMN_NAME <> ' '+@FieldName+''




OPEN cfCursor
  FETCH next from cfCursor into @ColumnName
  while @@FETCH_STATUS = 0

    begin
    select @Sql = 
    N' SELECT @Count = count(*) from ' +@TableName + ' T1 '+
    N' INNER JOIN ' + @TableName + ' T2 ON T1.' +@ColumnName + ' = T2.' + @ColumnName +
    N' WHERE T1.' +@FieldName + ' = '+ CAST(@FirstId as varchar) +
    N' AND T2.' + @FieldName + ' = '+CAST(@SecondId as varchar)
    SELECT @Params = 
    N'@TableName VARCHAR(MAX), @ColumnName VARCHAR(MAX), '+
    N'@FieldName VARCHAR(MAX), @FirstId int, @SecondId int, @Count int out'
    exec sp_executesql  @sql, @Params, @TableName, @ColumnName, @FieldName, @FirstId, @SecondId, @Count OUT
    if @Count = 1
    begin
    --print tableName and column Name if value is identic
     print 'Table : ' + @TableName + ' : same value for ' + @ColumnName
    end
    FETCH NEXT FROM cfCursor INTO @ColumnName    
    end
 close cfCursor

 DEALLOCATE cfCursor
GO
于 2012-05-11T10:34:29.887 に答える