SQL вставка / удаление строки запроса с использованием связанных таблиц - PullRequest
0 голосов
/ 15 апреля 2019

У меня есть 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 (Часть) или 4 (Раздел) для города, поскольку это может произойти позже. Как лучше всего выполнить вставку, где я могу добавить строку кода таблицы 2 (Глава), 3 (Часть) или 4 (Раздел), которая соответствует городу родительской строки table_1 и обновит все ссылки FK в других таблицах так, чтобы строки таблицы связаны по городам для другого запроса, чтобы при необходимости получить объединенный код позже. Я не эксперт в программировании на SQL, но мне было интересно, может ли кто-нибудь подсказать мне, как это можно сделать. Надеюсь, я правильно настроил таблицы, чтобы каждая строка имела FK-ссылку на предыдущую / следующую таблицу в списке, которая соответствует коду города, поэтому строки можно вставлять или удалять в любом месте между родительским элементом table_1 (title) для Таблица_4 (раздел) для конкретного города. Может ли кто-нибудь помочь мне с запросом на вставку и удаление, чтобы справиться с вышеуказанным условием, используя следующие таблицы:

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 Ответ

1 голос
/ 15 апреля 2019

Я могу предложить использовать 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 отвечая на ваш вопрос в комментариях. Если вы хотите использовать 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)

И родительская таблица будет содержать город и мастер-код, который будет обновляться всякий раз, когда будут завершены все 4 части в таблице MasterCityCode (триггеры полезны для этой части).

Быстрый пример:

Сначала создайте необходимые таблицы:

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)

Надеюсь, это поможет вам

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...