Sql server 查找在一个过程中外键中使用的任何特定值
下午好 我正在使用SQLServer2008/TSQL。可能需要注意的是,我没有对任何数据库的写访问权限(我是只读用户)。我没有对数据库的写入权限,但如果绝对需要,可以插入临时表 首先,我想让大家知道我没有接受过SQL方面的正规教育。希望这是有道理的-我可能在一些词汇等方面不准确 我正在尝试的范围: 1.从表中选择列(主键)中的特定recordID(值) 2.查找在所有从属项/外键中使用该特定编号/记录ID的位置 3.返回tablename和columnname,并计算找到该值的次数 所以,作为一个例子。。。 您有一个表,其中包含与recordID关联的人员的信息,例如: 带有记录ID、名称等的dbo.MemberInfo 成员的ID号(MemberInfo.RecordID)用于其他 表,例如:dbo.Awards作为[荣誉ID] (dbo.Awards.HonoreeID=MemberInfo.RecordID)dbo.Address为[MemberID] (dbo.Address.MemberID=MemberInfo.RecordID)dbo.Contact as[PersonID] (dbo.Contact.PersonID=MemberInfo.RecordID)…可能还有一些 百人 我基本上想浏览所有的表,看看某个特定的值/记录被使用了多少次。现在,为了增加一些复杂性,它需要是通用的,因为我可能正在查找依赖项的列可能每天都在变化。(例如,我明天可能要寻找EventID的家属) 我目前的程序是: -使用select查找所需人员的ID -查看所有链接到dbo.Members的RecordID(主键)的外键 -将外键的表名和列转储到Excel中 -使用WHERE=@变量查找并替换一组SELECT计数 -将其放入SQL,定义my变量并将其设置为初始ID号 一定有更好的办法。我尝试了以下多种方法,但都出现了很多错误,没有成功:Sql server 查找在一个过程中外键中使用的任何特定值,sql-server,sql-server-2008,tsql,Sql Server,Sql Server 2008,Tsql,下午好 我正在使用SQLServer2008/TSQL。可能需要注意的是,我没有对任何数据库的写访问权限(我是只读用户)。我没有对数据库的写入权限,但如果绝对需要,可以插入临时表 首先,我想让大家知道我没有接受过SQL方面的正规教育。希望这是有道理的-我可能在一些词汇等方面不准确 我正在尝试的范围: 1.从表中选择列(主键)中的特定recordID(值) 2.查找在所有从属项/外键中使用该特定编号/记录ID的位置 3.返回tablename和columnname,并计算找到该值的次数 所以,作为
--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
我的思路是:
1.查询表/列中使用的外键,从相关表返回表名和列名
2.将这些结果输入到可以构建新查询的内容中,以便在适用的情况下返回每个表/列中的值计数
3.还返回tablename,以便在我需要查看构成计数的详细信息时,可以轻松地将其输入到另一个select语句中
所以我的结果可能是这样的:
Tablename、Columnname、列中的值计数
理想情况下,如果计数小于1,则不会返回任何值、表名等
我的过程可能在一开始就有极大的缺陷,但提供的任何东西都能帮助我学习。谢谢 下面的脚本不使用存储过程,但使用临时表。据我所知,这是没有办法的。它对我来说运行得非常快,尽管我使用的是一个相对较小的测试数据库 这是我第一次尝试使用动态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;
下面的脚本不使用存储过程,但使用临时表。据我所知,这是没有办法的。它对我来说运行得非常快,尽管我使用的是一个相对较小的测试数据库 这是我第一次尝试使用动态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;
看起来和这个项目很相似:查看器选择所有数据,你只需要计数。我最初的建议是暂时不要考虑让它通用化。设置一个变量并使用它成功地测试它。例如,如果我在AdventureWorks中使用462624691,我将获得Address/StateProvinceID和SalesTaxRate/StateProvinceID。因此,我必须问自己,这是否就是我正在寻找的数据。然后调整它直到我得到我想要的。这将有助于查看当前查询和过程的示例。看起来与此项目类似:查看器选择所有数据,您只需要计数。我最初的建议是暂时不要考虑将其设置为通用。设置一个变量并使用它成功地测试它。例如,如果我在AdventureWorks中使用462624691,我将获得Address/StateProvinceID和SalesTaxRate/StateProvinceID。因此,我必须问自己,这是否就是我正在寻找的数据。然后调整它直到我得到我想要的。查看当前查询和流程的示例会有所帮助。