简体   繁体   English

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

[英]SQL insert/delete row query using linked tables

I have 4 sql tables that have linked rows based on a common city. 我有4个sql表,这些表已基于一个普通城市链接了行。 Each table row has a code that will be combined together to create 1 master code based on the code value of each table row with a matching city. 每个表格行都有一个代码,该代码将组合在一起以根据每个表格行的代码值以及匹配的城市创建1个主代码。 For example, if Table_1.code = 2, Table_2.code = 3c, Table_3.code = 1a, and Table_4.code = 2(2) matching the city of Houston then the combined end result code value would be 2-3c-1a-2(2). 例如,如果Table_1.code = 2,Table_2.code = 3c,Table_3.code = 1a和Table_4.code = 2(2)与休斯顿市匹配,则最终结果代码的组合值为2-3c-1a -2(2)。 I have a query that uses inner joins that works fine to create the combined code based on the matching city. 我有一个查询,该查询使用内部联接可以很好地根据匹配的城市创建组合代码。 My problem is, sometimes I will not have a child table 2(Chapter), 3(Part) or 4(Section) code row for a city since it might come later. 我的问题是,有时我不会为城市创建子表2(第3章),3(部分)或4(部分)代码行,因为它可能会在以后出现。 How's the best way to do an insert where I can add a table 2(Chapter), 3(Part) or 4(Section) code row that matches the city of the parent table_1 row and will update all FK references on other tables so that the table rows are linked together by city for a another query to get the combined code later if needed. 如何做插入的最佳方法是,我可以在其中添加与父表_1行的城市匹配的表2(章),3(部分)或4(部分)代码行,并将更新其他表上的所有FK引用,以便表格行按城市链接在一起以进行另一个查询,以便以后在需要时获取组合的代码。 I'm not an expert at SQL programming, but was wondering if someone could guide me in how this could be done. 我不是SQL编程专家,但想知道是否有人可以指导我如何完成此工作。 Hopefully, I've setup the tables correctly so that each row will have a FK reference to a prev/next table in the list that matches the city code, so rows can be inserted or deleted anywhere in between the table_1(title) parent to table_4(section) for a particular city. 希望我已经正确设置了表,以便每一行都将具有与城市代码匹配的列表中上一个/下一个表的FK引用,因此可以在table_1(title)父表之间的任何位置插入或删除行。特定城市的table_4(section)。 Can someone help me w/ an insert and delete query to handle this condition above using the following tables below. 有人可以使用下表帮助我进行插入和删除查询,以解决上述情况。

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)

what I can suggest is to use VIEW, so whenever all parts are available in the view, you can then insert them wherever you want. 我建议使用VIEW,因此只要视图中的所有部分都可用,就可以将它们插入到任何需要的位置。 The view will always updated automatically. 该视图将始终自动更新。 So, you can use your current query, and adjust it to use it in the view, and then query that view, if it has the full code you need, then you can insert that row to the target table. 因此,您可以使用当前查询,并对其进行调整以在视图中使用它,然后查询该视图,如果它具有所需的完整代码,则可以将该行插入到目标表中。

Example : 范例:

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 answering your question in the comments. 更新在评论中回答您的问题。 If you want to use UPDATE CASCADE, you need to set FK action to UPDATE CASCADE. 如果要使用UPDATE CASCADE,则需要将FK操作设置为UPDATE CASCADE。 This mean, whenever the PK updated, all its FK will be updated as well. 这意味着,每当PK更新时,其所有FK也会同时更新。 So, in your case, you'll need to make the Code for each table as PK, this will also means your code column will be always unique. 因此,在您的情况下,您需要将每个表的代码都设置为PK,这也意味着您的代码列将始终是唯一的。 This approach for your scenario will be not a good idea. 针对您的方案的这种方法不是一个好主意。

However, since I've got the idea you're trying to do (kinda), I would suggest to change the way of your thinking. 但是,由于我已经知道了您要尝试的想法(有点),所以我建议您改变思维方式。 Instead of going this road, you can use just one table that will contain Title, Chapter, Part, and Section codes. 您可以只使用一个包含标题,章,部分和节代码的表,而不必走这条路。 and update them as needed. 并根据需要进行更新。 which will be much easier for you. 这对您来说会容易得多。

it would be something like this : 就像这样:

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)

And the parent table will be holding the city and master code, which will be updated whenever all 4 parts in MasterCityCode table are completed (Triggers are useful for this part). 父表将保存城市和主代码,每当MasterCityCode表中的所有4个部分都完成时,该代码就会更新(触发器对于该部分很有用)。

Quick Example: 快速示例:

First creating the required tables : 首先创建所需的表:

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
)   

Now, we will set two triggers one on CityCode, which will insert all new cities in CityCode_Master table. 现在,我们将在CityCode上设置两个触发器,一个将在CityCode_Master表中插入所有新城市。 The other one will be on CityCode_Master, which will handle the CityCode.code update. 另一个将在CityCode_Master上,它将处理CityCode.code更新。 So, if all code parts are not null then it'll update the CityCode.code with the new master 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

now, let's try them out. 现在,让我们尝试一下。

we will insert a new city in CityCode table. 我们将在CityCode表中插入一个新城市。

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

if you query CityCode table, you'll find that code for Houston is NULL, which is what we need for the first stage, and if you query CityCode_Master table, you'll find a new row for Houston, and all other code columns are null. 如果查询CityCode表,则会发现Houston的代码为NULL,这是我们在第一阶段中需要的代码;如果查询CityCode_Master表,则会找到Houston的新行,所有其他代码列为空值。

Now, let's update the CityCode_Master codes. 现在,让我们更新CityCode_Master代码。

for a single code : 对于单个代码:

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

if you recheck the table, you'll find that only column TitleCode is updated, the rest of the codes still null, and if you recheck CityCode table, you'll still see that code for Houston is still null. 如果您重新检查该表,则会发现只有TitleCode列已更新,其余代码仍为空,并且如果您重新检查CityCode表,您仍会看到休斯顿的代码仍为空。

Now let's update the rest of them to see the affects of the second trigger : 现在,让我们更新它们的其余部分,以查看第二个触发器的影响:

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

you'll see that in CityCode_Master all the codes are not null now. 您会看到在CityCode_Master中,所有代码现在都不为空。 If you go back to CityCode table and recheck it, you'll find that code column for Houston is now updated with the master code 2-3c-1a-2(2) 如果您返回CityCode表并重新检查,您会发现Houston的代码列现在已更新为主代码2-3c-1a-2(2)

I hope this will help you 我希望这能帮到您

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM