使用链接表的SQL插入/删除行查询

时间:2019-04-15 02:19:59

标签: sql sql-server

我有4个sql表,这些表具有基于同一城市的链接行。每个表格行都有一个代码,该代码将组合在一起以根据每个表格行的代码值以及匹配的城市创建1个主代码。例如,如果Table_1.code = 2,Table_2.code = 3c,Table_3.code = 1a和Table_4.code = 2(2)与休斯顿市匹配,则最终结果代码的组合值为2-3c-1a -2(2)。我有一个查询,该查询使用内部联接可以很好地根据匹配的城市创建组合代码。我的问题是,有时我不会为城市创建子表2(第3章),3(部分)或4(部分)代码行,因为它可能会在以后出现。如何做插入的最佳方法是,我可以在其中添加与父表_1行的城市匹配的表2(章),3(部分)或4(部分)代码行,并将更新其他表上的所有FK引用,以便表格行按城市链接在一起以进行另一个查询,以便以后在需要时获取组合的代码。我不是SQL编程专家,但想知道是否有人可以指导我如何完成此工作。希望我已经正确设置了表,以便每一行都将具有与城市代码匹配的列表中上一个/下一个表的FK引用,因此可以在table_1(title)父表之间的任何位置插入或删除行。特定城市的table_4(section)。有人可以使用下表通过插入和删除查询来帮助我解决上述情况。

Table1-Title (Parent table)
 table1_ID_PK int,
 code varchar(100),
 city varchar(100)

Table2-Chapter (Child table)
 table2_ID_PK int,
 table1_ID_FK int,
 table3_ID_FK int,
 code varchar(100),
 city varchar(100)

Table3-Part (Child table)
 table3_ID_PK int,
 table1_ID_FK int,
 table2_ID_FK int,
 table4_ID_FK int,
 code varchar(100),
 city varchar(100)

Table4-Section (Child table)
 table4_ID_PK int,
 table1_ID_FK int,
 table2_ID_FK int,
 table3_ID_FK int,
 code varchar(100),
 city varchar(100)

1 个答案:

答案 0 :(得分:1)

我建议使用VIEW,因此只要视图中所有部分都可用,就可以将它们插入到任何需要的位置。该视图将始终自动更新。因此,您可以使用当前查询,并对其进行调整以在视图中使用它,然后查询该视图,如果它具有所需的完整代码,则可以将该行插入到目标表中。

示例:

CREATE VIEW CityMasterCode AS (
    SELECT 
        t1.City 
    ,   CASE WHEN t1.code IS NULL OR t1.code = '' THEN NULL ELSE t1.code +  '-' END 
    +   CASE WHEN t2.code IS NULL OR t2.code = '' THEN NULL ELSE t2.code +  '-' END 
    +   CASE WHEN t3.code IS NULL OR t3.code = '' THEN NULL ELSE t3.code +  '-' END 
    +   CASE WHEN t4.code IS NULL OR t4.code = '' THEN NULL ELSE t4.code END AS MasterCode
    FROM 
        table1 t1
    LEFT JOIN table2 t2 ON t2.table1_ID_FK = t1.table1_ID_PK
    LEFT JOIN table3 t3 ON t3.table1_ID_FK = t1.table1_ID_PK
    LEFT JOIN table4 t4 ON t4.table1_ID_FK = t1.table1_ID_PK
)


INSERT INTO TargetTable (city, code)
SELECT 
    m.City 
,   m.MasterCode
FROM table1 t1 
JOIN CityMasterCode m ON m.City = t1.City AND t1.code = m.MasterCode

更新 在评论中回答您的问题。如果要使用UPDATE CASCADE,则需要将FK操作设置为UPDATE CASCADE。这意味着,每当PK更新时,其所有FK也会同时更新。因此,在您的情况下,您需要将每个表的代码都设置为PK,这也意味着您的代码列将始终是唯一的。针对您的方案的这种方法不是一个好主意。

但是,由于我已经知道了您要尝试的想法(有点),所以我建议您改变思维方式。您可以只使用一个包含标题,章,部分和节代码的表,而不必走这条路。并根据需要进行更新。这对您来说会容易得多。

应该是这样的:

MasterCityCode (Child Table)
ID_PK int,
table1_ID_FK int,
city varchar(100), 
TitleCode varchar(100),
ChapterCode varchar(100),
PartCode varchar(100),
SectionCode varchar(100)

父表将保存城市和主代码,只要MasterCityCode表中的所有4个部分都完成了,该代码就会更新(触发器对于该部分很有用)。

快速示例:

首先创建所需的表:

CREATE TABLE CityCode (
    ID INT IDENTITY(1,1) NOT NULL,
    City VARCHAR(100) NOT NULL, 
    Code VARCHAR(100) NULL,
    PRIMARY KEY (ID, City)  
)

CREATE TABLE CityCode_Master (
    ID INT IDENTITY(1,1) NOT NULL,
    CityCode_ID_FK INT NOT NULL,
    CityCode_City_FK  VARCHAR(100) NOT NULL, 
    TitleCode VARCHAR(100) NULL,
    ChapterCode VARCHAR(100) NULL,
    PartCode VARCHAR(100) NULL,
    SectionCode VARCHAR(100) NULL, 
    PRIMARY KEY (ID),
    FOREIGN KEY (CityCode_ID_FK, CityCode_City_FK) REFERENCES CityCode(ID, City)
    ON UPDATE CASCADE 
    ON DELETE CASCADE
)   

现在,我们将在CityCode上设置两个触发器,其中一个将在CityCode_Master表中插入所有新城市。另一个将在CityCode_Master上,它将处理CityCode.code更新。因此,如果所有代码部分都不为null,则它将使用新的主代码更新CityCode.code。

CREATE TRIGGER InsertNewRowInCityCode_Master
   ON  CityCode
   AFTER INSERT
AS 
BEGIN
    SET NOCOUNT ON;

    INSERT INTO CityCode_Master (CityCode_ID_FK, CityCode_City_FK)  
    SELECT ID, City
    FROM 
        inserted
END

GO
CREATE TRIGGER UpdateCityCode
   ON  CityCode_Master
   FOR UPDATE
AS 
BEGIN
    SET NOCOUNT ON;

    IF EXISTS (
        SELECT * 
        FROM inserted 
        WHERE 
            TitleCode IS NOT NULL 
        AND ChapterCode IS NOT NULL 
        AND PartCode IS NOT NULL 
        AND SectionCode IS NOT NULL     
    )
    BEGIN 

        UPDATE city
        SET Code = TitleCode + '-' + ChapterCode + '-' + PartCode + '-' +  SectionCode
        FROM CityCode city 
        JOIN inserted ins ON ins.CityCode_ID_FK = city.ID AND ins.CityCode_City_FK = city.City 
    END 

END

现在,让我们尝试一下。

我们将在CityCode表中插入一个新城市。

INSERT INTO CityCode (City)
VALUES ('Houston')

如果查询CityCode表,则会发现休斯顿的代码为NULL,这是我们在第一阶段中需要的;如果查询CityCode_Master表,则会找到休斯顿的新行,以及所有其他行代码列为空。

现在,让我们更新CityCode_Master代码。

单个代码:

-- Update a single column at time. 
UPDATE CityCode_Master
SET TitleCode = '2'
WHERE 
    CityCode_ID_FK = 1 
AND CityCode_City_FK = 'Houston'

如果重新检查该表,则会发现只有TitleCode列已更新,其余代码仍为空,如果重新检查CityCode表,您仍将看到休斯顿的代码仍为空。

现在让我们更新其中的其余部分,以查看第二个触发器的影响:

UPDATE CityCode_Master
SET 
    ChapterCode = '3c'
,   PartCode    = '1a'
,   SectionCode = '2(2)'
WHERE 
    CityCode_ID_FK = 1 
AND CityCode_City_FK = 'Houston'

您将看到CityCode_Master中的所有代码现在都不为空。如果您返回CityCode表并重新检查,则会发现休斯顿的代码列现在已使用主代码2-3c-1a-2(2)

更新

我希望这会对您有所帮助