有没有办法获取表格所依赖的所有表格?必须有SQL Server Management Studio允许你通过选择Find Dependencies然后选择'Objectname'[tablename]依赖于'在SQL Server中查找特定表所依赖的表格
我知道sp_depends
,但是这会让我回到依赖于表的对象而不是桌子依赖于什么。
由于提前,
乔恩
有没有办法获取表格所依赖的所有表格?必须有SQL Server Management Studio允许你通过选择Find Dependencies然后选择'Objectname'[tablename]依赖于'在SQL Server中查找特定表所依赖的表格
我知道sp_depends
,但是这会让我回到依赖于表的对象而不是桌子依赖于什么。
由于提前,
乔恩
根据与GBN和讨论你只关心表取决于(而不是任何取决于表)中的对象的假设,我想出了这个人为的例子:
USE [master];
GO
IF DB_ID('foo') IS NOT NULL
DROP DATABASE foo;
GO
CREATE DATABASE foo;
GO
USE foo;
GO
CREATE TYPE dbo.Email FROM VARCHAR(320) NOT NULL;
GO
CREATE SCHEMA foo AUTHORIZATION dbo;
GO
CREATE TYPE foo.Email FROM VARCHAR(320) NULL;
GO
CREATE FUNCTION dbo.IsGreaterThanZero1(@i INT)
RETURNS BIT
AS
BEGIN
RETURN (SELECT CASE WHEN @i>0 THEN 1 ELSE 0 END);
END
GO
CREATE FUNCTION dbo.IsGreaterThanZero2(@i INT)
RETURNS BIT
AS
BEGIN
RETURN (SELECT CASE WHEN @i>0 THEN 1 ELSE 0 END);
END
GO
CREATE TABLE dbo.bar
(
id INT PRIMARY KEY
);
GO
CREATE FUNCTION dbo.maxbar()
RETURNS INT
AS
BEGIN
RETURN (SELECT MAX(id) FROM dbo.bar);
END
GO
CREATE TABLE dbo.foo
(
id INT FOREIGN KEY REFERENCES dbo.bar(id),
-- dependency on foreign key to another table
Email1 dbo.Email,
-- dependency on alias type
Email2 foo.Email,
-- dependency on alias type in different schema
IsMoreThanZero1 AS CONVERT(BIT, dbo.IsGreaterThanZero1(id)),
-- computed column dependency
IsMoreThanZero1A AS dbo.IsGreaterThanZero1(id),
-- computed column dependency
IsMoreThanZero2 BIT CHECK (dbo.IsGreaterThanZero2(IsMoreThanZero2)=1),
-- check constraint dependency
IsMoreThanZero2A BIT CHECK (CONVERT(BIT,
dbo.IsGreaterThanZero2(IsMoreThanZero2A))=1),
CHECK(IsMoreThanZero2A LIKE '[,%]'),
-- check constraint dependency
maxbar INT NOT NULL DEFAULT (dbo.maxbar())
-- default constraint dependency
);
GO
CREATE TRIGGER dbo.after_insert_foo ON dbo.foo
FOR INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @x INT;
SELECT TOP (1) @x = id FROM dbo.bar;
END
GO
好了,现在该数据库是座充满的东西要找到,以下脚本将标识所有对象引用ces以上:
DECLARE @tablename SYSNAME = N'dbo.foo';
DECLARE @object_id INT = OBJECT_ID(@tablename);
-- functions mentioned in check/default constraints
-- and computed columns in @tablename
WITH x AS
(
SELECT [type], [obj], [count] = COUNT(*)
FROM
(
SELECT [type], obj = OBJECT_ID(
SUBSTRING(d, CHARINDEX('],', d) + 2,
CHARINDEX('(', SUBSTRING(d,
CHARINDEX('],', d) + 2, LEN(d)))-1))
FROM
(
SELECT [type] = 'default', [object_id], d = [definition]
FROM sys.default_constraints
WHERE parent_object_id = @object_id
AND CHARINDEX('].[', [definition]) > 0
UNION
SELECT 'check', [object_id], [definition]
FROM sys.check_constraints
WHERE parent_object_id = @object_id
AND CHARINDEX('].[', [definition]) > 0
UNION
SELECT 'computed', NULL, [definition]
FROM sys.computed_columns
WHERE [object_id] = @object_id
AND CHARINDEX('].[', [definition]) > 0
) AS x
) AS y GROUP BY [type], [obj]
UNION ALL
-- triggers defined on @tablename
SELECT 'trigger', obj = [object_id], 1
FROM sys.triggers
WHERE parent_id = @object_id
UNION ALL
-- objects referenced by triggers on @tablename
SELECT 'trigger references', [obj] = d.[referenced_major_id], COUNT(*)
FROM sys.sql_dependencies AS d
INNER JOIN sys.triggers AS tr
ON d.[object_id] = tr.[object_id]
AND tr.parent_id = @object_id
GROUP BY d.referenced_major_id
UNION ALL
-- foreign keys referenced by @tablename
SELECT 'foreign key', [obj] = referenced_object_id, COUNT(*)
FROM sys.foreign_keys
WHERE parent_object_id = @object_id
GROUP BY referenced_object_id
)
SELECT
[obj] = QUOTENAME(OBJECT_SCHEMA_NAME(obj)) + '.'
+ QUOTENAME(OBJECT_NAME(obj)),
[type],
[count]
FROM x
UNION ALL
SELECT
[obj],
[type],
[count] = COUNT(*)
FROM
(
SELECT
[obj] = QUOTENAME(SCHEMA_NAME(t.[schema_id]))
+ '.' + QUOTENAME(t.name),
[type] = 'alias type'
FROM
sys.types AS t
INNER JOIN sys.columns AS c
ON t.user_type_id = c.user_type_id
WHERE t.is_user_defined = 1
AND c.[object_id] = @object_id
) AS x GROUP BY [obj], [type];
这里有更多的注意事项比我不在乎。一个是,在sys.default_constraints,sys.check_constraints和sys.computed_columns中的定义分析假定你没有看起来像对象名称(特别是我解析为)的常量[显示函数名称,因为你可以' t将模式和方括号添加为您),不包含特殊字符(如“[”,“。”或“]”)的函数名称,或者传递给包含'['的UDF或']',因为我使用这些来确定它实际上是一个函数(并且我还假定没有嵌套函数)。它还假定所有的引用都包含在同一个数据库中。还有一点是我只深入一层 - 如果你在dbo.foo上有一个触发器,它会调用一个函数,该函数又引用另一个表,而这个表不会被包含在内。免费的帮助只会愿意走到兔子洞的尽头。 :-)
我仍然不信任任何依赖性视图100%,所以如果你的系统是不稳定的,我会说你最安全的赌注是遵循gbn的建议,并使用sys.sql_modules.definition来追求暴力破解由于模式更改,这部分容易失效。只有很多方法可以使这些东西自动化出错,我不知道你是否会有100%的防弹解决方案 - 尽管有很多工作可以让你变得非常接近。
但回到原来的问题 - 也许你可以明确定义你正在寻找哪些类型的依赖关系。
表通常不依赖于表除了
间接依赖,像什么看法JOIN的2桌都将是从一些聪明的查询上sys.sql_modules
即使是最后一个,视图依赖于表格,而不是相反。也有可能属于该要求的别名类型。 –
@Aaron Bertrand:是的,但如果OP意味着“相关”而不是“依赖”,那么它仍然是sys.sql_modules上的一个聪明的查询。无论如何这都是一个混乱的要求。 – gbn
查看 - >表关系实际上应该很简单(sys.sql_dependencies)。 –
您是否尝试过sp_MSdependencies?这是无证的,所以你不能完全依靠它,但它似乎很灵活,很好地完成它的工作......
通过打开SQL事件探查器并捕获Management Studio运行的查询,您可能确实很狡猾 - 在Profiler中,一定要禁用删除Management Studio查询的列过滤器。 –