Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 带有偏移行的递归CTE,用于来自信息架构的元数据_Sql_Sql Server_Tsql_Recursion_Information Schema - Fatal编程技术网

Sql 带有偏移行的递归CTE,用于来自信息架构的元数据

Sql 带有偏移行的递归CTE,用于来自信息架构的元数据,sql,sql-server,tsql,recursion,information-schema,Sql,Sql Server,Tsql,Recursion,Information Schema,我建立了一个多语种的数据库(实际上比这更复杂,但我保持简单)。可翻译数据放在名为Fact的表中。数据从名为FactLink的表链接到(只有一列名为FactLinkID。一个表中的多列正在引用该数据。但有时,当数据构成自己的集合时,可以间接引用FactLink表。例如 CREATE TABLE FactLink ( FactLinkID INT NOT NULL IDENTITY(1,1) Primary KEY ) CREATE TABLE [Language] ( LanguageID IN

我建立了一个多语种的数据库(实际上比这更复杂,但我保持简单)。可翻译数据放在名为
Fact
的表中。数据从名为
FactLink
的表链接到(只有一列名为
FactLinkID
。一个表中的多列正在引用该数据。但有时,当数据构成自己的集合时,可以间接引用
FactLink
表。例如

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
表的所有列。获取直接链接很容易。我想我需要通过
递归CTE
获取间接链接。但我不确定如何实现。我对
递归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

以下是我已经测试过的两个场景:

不使用cte:

  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
      TABLE_SCHEMA
    , TABLE_NAME
    , CONSTRAINT_NAME
    , COLUMN_NAME
    , UNIQUE_CONSTRAINT_NAME from

 (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) as result
WHERE UNIQUE_CONSTRAINT_NAME =@FactLinkPKConstraint
  --AND t.TABLE_NAME NOT IN (SELECT c.TABLE_NAME FROM CTE c)
  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'

 ;with cte as
 (
    select @FactLinkPKConstraint  as col1
 ),
 FactLinkPKConstraint as 
 (
    select * from cte
 ),result 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
 )
 select * from result where UNIQUE_CONSTRAINT_NAME = (select col1 from FactLinkPKConstraint) 

  --AND t.TABLE_NAME NOT IN (SELECT c.TABLE_NAME FROM CTE c)
使用cte:

  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
      TABLE_SCHEMA
    , TABLE_NAME
    , CONSTRAINT_NAME
    , COLUMN_NAME
    , UNIQUE_CONSTRAINT_NAME from

 (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) as result
WHERE UNIQUE_CONSTRAINT_NAME =@FactLinkPKConstraint
  --AND t.TABLE_NAME NOT IN (SELECT c.TABLE_NAME FROM CTE c)
  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'

 ;with cte as
 (
    select @FactLinkPKConstraint  as col1
 ),
 FactLinkPKConstraint as 
 (
    select * from cte
 ),result 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
 )
 select * from result where UNIQUE_CONSTRAINT_NAME = (select col1 from FactLinkPKConstraint) 

  --AND t.TABLE_NAME NOT IN (SELECT c.TABLE_NAME FROM CTE c)

感谢您花时间解决此问题。但是您的解决方案将获取对
@FactLinkPKConstraint
的所有引用。也就是说,如果是另一个表,比如说
所有2
引用
@FactLinkPKConstraint
,那么它也将获取这些引用。我需要它们只获取引用
所有
中的列LinkPKConstraint
或其子表中的一个子表引用它。