Sql 如何搜索主键ID';这些主键ID';s在列中具有相似的值
背景:我们正在研究为什么在一个过程中遗漏了许多账户。我们已经回到了我们所掌握的数据。我们现在有一个相当大的账户清单,无论出于何种原因,这些账户都被遗漏了。现在这个过程没有太多细节,非常复杂,我们需要知道为什么遗漏了这些账户,只有这些账户。就像任何数据库一样,我们有很多自动的过程一直在运行,所以现在真的不知道到底发生了什么导致这些帐户丢失。我认为解决这个问题的唯一办法是找出这些账户之间的相似之处。显然,我们已经尝试寻找更常见的地方,但后来什么也没有发现 问题:我想使用SQL返回数据库中的所有表名和列名,其中这些帐户列表在表的一列或多列中具有相同的值。我已经创建了一个查询来查找表名、列等,但不知道如何将它们组合在一起创建一个查询,以获得我想要的所有结果。我确信需要使用光标和大量内部连接,但我不确定该如何操作。Sql 如何搜索主键ID';这些主键ID';s在列中具有相似的值,sql,database,reporting,analytics,Sql,Database,Reporting,Analytics,背景:我们正在研究为什么在一个过程中遗漏了许多账户。我们已经回到了我们所掌握的数据。我们现在有一个相当大的账户清单,无论出于何种原因,这些账户都被遗漏了。现在这个过程没有太多细节,非常复杂,我们需要知道为什么遗漏了这些账户,只有这些账户。就像任何数据库一样,我们有很多自动的过程一直在运行,所以现在真的不知道到底发生了什么导致这些帐户丢失。我认为解决这个问题的唯一办法是找出这些账户之间的相似之处。显然,我们已经尝试寻找更常见的地方,但后来什么也没有发现 问题:我想使用SQL返回数据库中的所有表名和
再一次: 假设我有账号123456和654321,我知道我们的数据库有3000个表,其中一列引用账号,名称为AccountNumber、AccountNum或account。我想搜索并查找所有表,这些表的列名称为AccountNumber、AccountNum或Account的值为123456或654321。然后对于这些表,对于每个表,我想获取列所在的行,无论名称是AccountNumber,AccountNum,或者Account的值为123456和654321,然后对于这些行中的每一行,我想检查每一行的每一列,看看账号123456行上的列是否与账号654321行上的列相等,如果是,那么我想让它返回列名和表名。通过这种方式,我可以看到这些账户的共同点 高级部分: 如果某个可怜的灵魂能够做到以上几点,那么我还想创建一个将返回的查询 表名及其更新时间。我将通过检查每个表中的每一列来获得更新的值,如果该列的类型为“timestamp”或默认值为“GetDate()”,则该列将被用作更新。在最终的结果集中,显示了它将订购的帐户编号的所有更改都已更新。第一种方法,rustic(我不太习惯T-SQL,我做了更多的PL/SQL),但这可能会帮助您更进一步,并在SQL SERVER 2008中进行测试。希望它能在2005年起作用……) 因此,我们创建了两个过程,一个调用另一个 提供的代码只能检查一次 -对于2个不同的ID -对于所有相关字段(Account、AccountNum、AccountNumber) 想法(检查AccountNumber列) 查找表(在表信息_SCHEMA.columns中,其中列出了您的数据库表),这些表的列具有提供的3个名称之一 对于找到的每个表: 创建动态查询:
select count(*) from <THE_TABLE> where <Account_column_name> IN (123456 654321);
如果count(*)=1
,则表示给定ID的同一表格的同一列中存在相同的值
在这种情况下,我们打印
和
要在sql management studio中启动搜索,只需
EXEC GetSimilarValuesForFieldAndValue 123456, 654321
在“消息”部分,您应该有一个“结果”列表
第二条:
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
CREATE procedure[dbo].[CompareFields](@TableName-NVARCHAR(MAX)、@FieldName-NVARCHAR(MAX)、@FirstId-int、@SecondId-int)
作为
声明@ColumnName NVARCHAR(最大值)
声明@Sql NVARCHAR(最大值)
声明@Params NVARCHAR(最大值)
声明@countint
为其声明cfCursor游标
从INFORMATION\u SCHEMA.COLUMNS中选择COLUMN\u NAME
其中TABLE_NAME='+@TableName+''
和列名称“”+@FieldName+“”
开放式cfCursor
从cfCursor获取下一个到@ColumnName
而@@FETCH\u STATUS=0
开始
选择@Sql=
N'从'+@TableName+'T1'中选择@Count=Count(*)+
N'内部联接'+@TableName+'T2在T1上'+@ColumnName+'=T2'+@ColumnName'+
N'其中T1.'+@FieldName+'='+CAST(@FirstId作为varchar)+
N'和T2.'+@FieldName+'='+CAST(@SecondId作为varchar)
选择@Params=
N'@TableName VARCHAR(最大值),@ColumnName VARCHAR(最大值),'+
N'@FieldName VARCHAR(MAX),@FirstId int,@SecondId int,@Count int out'
exec sp_executesql@sql、@Params、@TableName、@ColumnName、@FieldName、@FirstId、@SecondId、@Count OUT
如果@Count=1
开始
--如果值相同,则打印表名和列名
打印“Table:”++@TableName+”:与“++@ColumnName”的值相同
结束
从cfCursor获取下一个到@ColumnName
结束
闭式cfCursor
解除分配cfCursor
去
实际上,我曾一度不得不为guid做这件事。下面是使用guid的脚本。一秒钟后,我将修改它以满足您的需要:
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
如果这不够清楚,请随时询问更多细节。我会在早上7点左右再次查看这篇文章,看看是否有勇敢的灵魂尝试过这一壮举。sgbd会很好,因为这样的查询可以在系统表中进行;)知道你有一个GetDate可能还不够,这是什么数据库和版本?我会首先做什么(如果我在你那里,但我不是;):在你的数据库中创建这两个过程,并用很少的样本值测试它。这将帮助你了解你是否获得了太多的信息(我认为这会发生)。然后进行定制、重构、改进,等等。好吧,我想我已经找到了我认为应该采取的分析步骤。1.获取所有表的列表,这些表的列类型为int,其值等于账号an
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