私は多言語データベースを設定しています(実際はそれより複雑ですが、単純なままです)。変換可能なデータはFact
というテーブルに格納されます。データはFactLink
というテーブルからリンクされています(FactLinkID
という単一の列のみがテーブル内の複数の列によって参照されていますが、FactLink
テーブルはデータが独自のセットを構成するときに間接的に参照されることがあります。 、メタデータのオフセット行を持つ再帰的CTE(Information_Schemaから)
CREATE TABLE FactLink
(FactLinkID INT NOT NULL IDENTITY(1,1) Primary KEY
)
CREATE TABLE [Language]
(LanguageID INT NOT NULL IDENTITY(1,1) Primary KEY
, Code varchar(50) not null
)
CREATE TABLE Fact
(FactLinkID INT NOT NULL
, LanguageID INT NOT NULL
, PRIMARY KEY CLUSTERED (FactLinkID ASC, LanguageID ASC)
, CONSTRAINT fk_Fact_FactLinkID FOREIGN KEY (FactLinkID) REFERENCES dbo.FactLink (FactLinkID)
, CONSTRAINT fk_Fact_LanuageID FOREIGN KEY (LanguageID) REFERENCES dbo.[Language] (LanguageID)
)
CREATE TABLE LimitedTranslateableItem
(LimitedTranslateableItemID INT NOT NULL PRIMARY KEY
, [Order] INT NOT NULL
, CONSTRAINT fk_LimitedTranslateableItem_Table1ID FOREIGN KEY (LimitedTranslateableItemID) REFERENCES dbo.FactLink (FactLinkID)
)
CREATE TABLE [All]
(AllID INT NOT NULL IDENTITY(1,1) PRIMARY KEY
, TranslateableItemID INT NOT NULL
, LimitedTranslateableItemID INT NOT NULL
, CONSTRAINT fk_All_TranslateableItemID FOREIGN KEY (TranslateableItemID) REFERENCES dbo.FactLink (FactLinkID)
, CONSTRAINT fk_All_LimitedTranslateableItemID FOREIGN KEY (LimitedTranslateableItemID) REFERENCES dbo.LimitedTranslateableItem (LimitedTranslateableItemID)
)
私が直接または間接的かどうかFactLink
テーブルを参照するすべての列を取得したいと思います。直接リンクを取得することは容易である。私は私がRecursive CTE
を通じて間接的にリンクを取得する必要があります理解。しかし、私はよ私はRecursive CTE
の新機能です。それは問題の一部ですが、FactLink
への参照はマッチング以外の行にあります制約。
-- Get constraint for FactLink table
DECLARE @FactLinkPKConstraint sysname
SELECT @FactLinkPKConstraint = t.CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS t
WHERE t.TABLE_NAME = 'FactLink'
AND t.CONSTRAINT_TYPE = 'PRIMARY KEY'
SELECT
t.TABLE_SCHEMA
, t.TABLE_NAME
, t.CONSTRAINT_NAME
, t.COLUMN_NAME
, rc.UNIQUE_CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE t
JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
ON rc.CONSTRAINT_NAME = t.CONSTRAINT_NAME
WHERE t.TABLE_NAME = 'All'
AND t.TABLE_SCHEMA = 'dbo'
AND rc.UNIQUE_CONSTRAINT_NAME = @FactLinkPKConstraint
は、ここで私がこれまで持っているものだ。もちろん
;WITH CTE AS (
SELECT
t.TABLE_SCHEMA
, t.TABLE_NAME
, t.CONSTRAINT_NAME
, t.COLUMN_NAME
, rc.UNIQUE_CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE t
JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
ON rc.CONSTRAINT_NAME = t.CONSTRAINT_NAME
WHERE t.TABLE_NAME = 'All'
AND t.TABLE_SCHEMA = 'dbo'
UNION ALL
SELECT
t.TABLE_SCHEMA
, t.TABLE_NAME
, t.CONSTRAINT_NAME
, t.COLUMN_NAME
, rc.UNIQUE_CONSTRAINT_CATALOG
FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE t
JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
ON rc.CONSTRAINT_NAME = t.CONSTRAINT_NAME
WHERE rc.UNIQUE_CONSTRAINT_NAME IN (
SELECT ct.UNIQUE_CONSTRAINT_NAME
FROM CTE ct
WHERE ct.UNIQUE_CONSTRAINT_NAME <> @FactLinkPKConstraint)
--AND t.TABLE_NAME NOT IN (SELECT c.TABLE_NAME FROM CTE c)
)
SELECT *
FROM CTE t
、Recursive CTE
はサブクエリで参照することはできませんので、それは動作しません。そして、私はテーブルの制約FactLink
とのマッチで私に行を取得しません。
多分私はこれで寝るとき、私はそれを考え出しました。しかし、いくつかの指針が役立ちます。
ありがとうございます!
UPDATE:
これは、私が思い付くことが最高です。それは私の基準に正確には合わないが、当初計画していた以上の欲求不満を見つけるので、実際には少し上手くいく。これにより、All
テーブルも参照するテーブルの列がFactLink
になります。
;WITH AFactLinkPKConstraint AS (
SELECT t.CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS t
WHERE t.TABLE_NAME = 'FactLink'
AND t.CONSTRAINT_TYPE = 'PRIMARY KEY'
), APrimary AS (
SELECT *
FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE t
WHERE t.CONSTRAINT_NAME IN (
SELECT DISTINCT rc.UNIQUE_CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE t
JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
ON rc.CONSTRAINT_NAME = t.CONSTRAINT_NAME
WHERE t.TABLE_NAME = 'All')
)
SELECT *
FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE t
JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
ON rc.CONSTRAINT_NAME = t.CONSTRAINT_NAME
AND rc.UNIQUE_CONSTRAINT_NAME = (SELECT pk.CONSTRAINT_NAME FROM AFactLinkPKConstraint pk)
JOIN APrimary p
ON p.TABLE_NAME = t.TABLE_NAME
AND p.TABLE_SCHEMA = t.TABLE_SCHEMA
おかげでこの問題に取り組む時間。しかし、あなたのソリューションは '@ FactLinkPKConstraint'への参照をすべて取得します。つまり、別のテーブルであれば、 'All2'が' @ FactLinkPKConstraint'を参照しているとしましょう。 '@ FactLinkPKConstraint'を参照する' All'からの列を取得するか、そのサブテーブルの1つがそれを参照する場合にのみ、それらを必要とします。 – Jon49