如何在 Sql Server 中使用 INFORMATION_SCHEMA 或 sys 视图识别一对一(一对?)关系
问题域 http://www.freeimagehosting.net/uploads/6e7aa06096.png
所以问题来了..使用TSQL和INFORMATION_SCHEMA或sys视图,如何识别1:0-1关系,例如FK_BaseTable_InheritedTable?
在一个具体的示例中,想象一个简单的 DTO - FK_JoinTable_ParentTable 将呈现为 ParentTable 对象上的 JoinTable 集合,而 FK_BaseTable_InheritedTable 将呈现为 BaseTable 对象上的 InheritedTable 对象(例如,继承是一个糟糕的选择,我知道,但不会回去)。
我能想到的最好的方法是一对多,与 FK_JoinTable_ParentTable 相同。我尝试了很多方法,包括(尝试)比较密钥,但效果不佳。
这是脚本。问题是,使用 INFO_SCHEMA 或 sys views ,将 FK_JoinTable_ParentTable 和 FK_JoinTable_Child 标识为一对多,将 FK_BaseTable_InheritedTable 标识为一对一/无。
试金石是能够区分 FK_BaseTable_InheritedTable 和 FK_JoinTable_ParentTable
CREATE TABLE [dbo].[Child](
[ChildId] [int] NOT NULL,
CONSTRAINT [PK_Child] PRIMARY KEY CLUSTERED
(
[ChildId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[ParentTable](
[ParentId] [int] NOT NULL,
CONSTRAINT [PK_ParentTable] PRIMARY KEY CLUSTERED
(
[ParentId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[JoinTable](
[PId] [int] NOT NULL,
[CId] [int] NOT NULL,
CONSTRAINT [PK_JoinTable] PRIMARY KEY CLUSTERED
(
[PId] ASC,
[CId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[InheritedTable](
[InheritedId] [int] NOT NULL,
CONSTRAINT [PK_InheritedTable] PRIMARY KEY CLUSTERED
(
[InheritedId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[BaseTable](
[BaseId] [int] NOT NULL,
CONSTRAINT [PK_BaseTable] PRIMARY KEY CLUSTERED
(
[BaseId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
ALTER TABLE [dbo].[JoinTable] WITH CHECK ADD CONSTRAINT [FK_JoinTable_Child] FOREIGN KEY([CId])
REFERENCES [dbo].[Child] ([ChildId])
ALTER TABLE [dbo].[JoinTable] CHECK CONSTRAINT [FK_JoinTable_Child]
ALTER TABLE [dbo].[JoinTable] WITH CHECK ADD CONSTRAINT [FK_JoinTable_ParentTable] FOREIGN KEY([PId])
REFERENCES [dbo].[ParentTable] ([ParentId])
ALTER TABLE [dbo].[JoinTable] CHECK CONSTRAINT [FK_JoinTable_ParentTable]
ALTER TABLE [dbo].[BaseTable] WITH CHECK ADD CONSTRAINT [FK_BaseTable_InheritedTable] FOREIGN KEY([BaseId])
REFERENCES [dbo].[InheritedTable] ([InheritedId])
ALTER TABLE [dbo].[BaseTable] CHECK CONSTRAINT [FK_BaseTable_InheritedTable]
The Problem Domain http://www.freeimagehosting.net/uploads/6e7aa06096.png
So here is the problem.. Using TSQL and INFORMATION_SCHEMA or sys views, how can I identify a 1:0-1 relationship, such as FK_BaseTable_InheritedTable?
In a concrete example, imagine a simple DTO - FK_JoinTable_ParentTable would be rendered as a collection of JoinTable on the ParentTable object, whereas FK_BaseTable_InheritedTable would either be rendered as an InheritedTable object on the BaseTable object (inheritance was a bad choice for example, I know, but not going back).
The best I can come up with is one-to-many, same as FK_JoinTable_ParentTable. I have tried a lot of approaches, including (trying to) comparing keys and am coming up short.
Here is the script. Problem is to, USING INFO_SCHEMA or sys views , identify FK_JoinTable_ParentTable and FK_JoinTable_Child as one-to-many and FK_BaseTable_InheritedTable as one-to-one/none.
The litmus is being able to differentiate FK_BaseTable_InheritedTable from FK_JoinTable_ParentTable
CREATE TABLE [dbo].[Child](
[ChildId] [int] NOT NULL,
CONSTRAINT [PK_Child] PRIMARY KEY CLUSTERED
(
[ChildId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[ParentTable](
[ParentId] [int] NOT NULL,
CONSTRAINT [PK_ParentTable] PRIMARY KEY CLUSTERED
(
[ParentId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[JoinTable](
[PId] [int] NOT NULL,
[CId] [int] NOT NULL,
CONSTRAINT [PK_JoinTable] PRIMARY KEY CLUSTERED
(
[PId] ASC,
[CId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[InheritedTable](
[InheritedId] [int] NOT NULL,
CONSTRAINT [PK_InheritedTable] PRIMARY KEY CLUSTERED
(
[InheritedId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[BaseTable](
[BaseId] [int] NOT NULL,
CONSTRAINT [PK_BaseTable] PRIMARY KEY CLUSTERED
(
[BaseId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
ALTER TABLE [dbo].[JoinTable] WITH CHECK ADD CONSTRAINT [FK_JoinTable_Child] FOREIGN KEY([CId])
REFERENCES [dbo].[Child] ([ChildId])
ALTER TABLE [dbo].[JoinTable] CHECK CONSTRAINT [FK_JoinTable_Child]
ALTER TABLE [dbo].[JoinTable] WITH CHECK ADD CONSTRAINT [FK_JoinTable_ParentTable] FOREIGN KEY([PId])
REFERENCES [dbo].[ParentTable] ([ParentId])
ALTER TABLE [dbo].[JoinTable] CHECK CONSTRAINT [FK_JoinTable_ParentTable]
ALTER TABLE [dbo].[BaseTable] WITH CHECK ADD CONSTRAINT [FK_BaseTable_InheritedTable] FOREIGN KEY([BaseId])
REFERENCES [dbo].[InheritedTable] ([InheritedId])
ALTER TABLE [dbo].[BaseTable] CHECK CONSTRAINT [FK_BaseTable_InheritedTable]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
编辑:修复了外键查询中的小拼写错误,该错误不会影响答案,但会返回错误的唯一表
我得出但从未能够正确执行的原始结论是:
这是我的执行问题。
我制定了一个可以产生正确结果的解决方案,但由于我不是 SQL 专家,我担心它相当混乱。也许我会把它作为另一个问题提出来供审查。
无论如何 - 这个脚本将识别所有 1:?数据库中的关系。
要查看更精细的测试数据库的结果,请参阅 TSQL:识别1:?关系
EDIT: fixed small typo in the foreign key query that does not affect the answer but returns the wrong unique table
The original conclusion I came to but was never able to properly execute is:
It was an execution issue on my part.
I worked out a solution that produces correct results but in that I am no SQL guru I fear it is rather kludgy. Perhaps I will put it up as another question for review.
Anyway - this script will identify all the 1:? relationships in the db.
For a look at the results on a more elaborate test db see TSQL: Identify a 1:? relationship