代码之家  ›  专栏  ›  技术社区  ›  john.1020

带冗余键的TSQL参考表

  •  0
  • john.1020  · 技术社区  · 7 年前

    我目前正在SQL Server 2016上开发一个存储过程。在我的数据库中,我有一个表结构,需要添加另一个表,该表引用与现有表相同的表。

    因此,我对同一个表有2次1:1的关系。

    出现的问题是,我在同一个目标表中引用了两次来自两个不同原始表的相同键。

    目标表:

    FK_Tables | Text
    ----------------
      1       | Table One Text Id: 1
      1       | Table Two Text Id: 1 // The error: Same FK_Tables 2 times
    

    表一:

    ID | OtherField
    ---------
     1 | 42 
    

    表二:

    ID | CoolField
    ---------
     1 | 22 
    

    表1和表2当前引用的是表引用表。

    你知道我怎么解决这个问题吗,用同一个ID解决两次?

    谢谢

    1 回复  |  直到 7 年前
        1
  •  0
  •   Everton Barciela    7 年前

    您需要为正在引用的每个表添加一列,否则,如果它们都插入到同一字段中,您将不知道ID来自何处。类似这样:

    /*
    CREATE TEST TABLES
    */
    DROP TABLE IF EXISTS tbOne;
    
    CREATE TABLE tbOne ( ID     INT     IDENTITY(1,1) NOT NULL      PRIMARY KEY
                       , TXT    VARCHAR(10) 
                       );
    
    DROP TABLE IF EXISTS tbTwo;
    
    CREATE TABLE tbTwo ( ID     INT     IDENTITY(1,1) NOT NULL      PRIMARY KEY
                       , TXT    VARCHAR(10) 
                       );
    
    DROP TABLE IF EXISTS Target;
    
    CREATE TABLE Target ( ID     INT    IDENTITY(1,1) NOT NULL      PRIMARY KEY
                        , FKTB1  INT
                        , FKTB2  INT
                        , TXT   VARCHAR(100) 
                        );
    
    
    
    -- 1st FK tbOne
    ALTER TABLE Target ADD CONSTRAINT FK_One FOREIGN KEY (FKTB1) REFERENCES tbOne (ID);
    
    --2nd FK tbTwo
    ALTER TABLE Target ADD CONSTRAINT FK_Two FOREIGN KEY (FKTB2) REFERENCES tbTwo (ID);
    
    
    
    -- Populate test tables
    INSERT INTO tbOne (TXT)
    SELECT TOP 100 LEFT(text, 10)
    FROM SYS.messages
    
    INSERT INTO tbTwo (TXT)
    SELECT TOP 100 LEFT(text, 10)
    FROM SYS.messages
    
    
    
    INSERT INTO [Target] (FKTB1, FKTB2, TXT)
    SELECT 1, 1, 'Test - constraint'
    
    
    -- Check result set
    SELECT *
    FROM tbTwo
    
    SELECT *
    FROM tbOne
    
    
    SELECT *
    FROM [Target] T
        INNER JOIN tbOne TB1
            ON T.FKTB1 = TB1.ID
        INNER JOIN tbTwo TB2
            ON T.FKTB2 = TB2.ID