SQL Триггер сервера (мне нужно перемещаться по иерархической древовидной структуре с любого данного узла) - PullRequest
0 голосов
/ 15 апреля 2020

Добрый день

У меня есть устаревшая база данных, которая была разработана для определенного c приложения переднего плана. Я делаю несколько случаев дополнительной разработки приложений с использованием этих данных, однако устаревшая база данных оказалась неадекватной для работы в будущем. К сожалению, устаревшая база данных должна оставаться на месте из-за того, что мне все еще нужно запустить приложение переднего плана.

Я создал новую базу данных аналогичной структуры, которая будет использоваться каждый раз, когда транспортное средство (пример, который мы будем использовать) добавляется в устаревшую базу данных через приложение переднего плана, для которого я настроил триггер pu sh указанные данные в новой базе данных при вставке (это все работает отлично).

Теперь перейдем к моей проблеме. Каждому транспортному средству присваивается ключ местоположения, который описывает, к какому местоположению он принадлежит, в иерархической древовидной структуре местоположений. Мне нужно взять это местоположение, которое может быть с любого уровня дерева, и найти все узлы ниже и выше его в устаревшей базе данных, используя таблицу местоположений, а затем добавить все ключи местоположения узлов в таблицу транспортных средств в новой базе данных, которая будет состоит из 7 уровней (столбцов). Мне нужно только получить Местоположение 0,1,2,3,4,5,6,7.

Например, у меня будет семь столбцов, каждый из которых может быть зарегистрированным местоположением транспортных средств.

(Level0Key, Level1Key, Level2key,...,...,..., Level6Key, Level7Key)

Как я понимаю, вам нужно увидеть чтобы помочь мне, мне нужна таблица устаревших баз данных, таблица логического уровня и таблица местоположений (где перечислены все местоположения с указанными там родительскими ключами).

Я приложу эти таблицы и простой триггер, который у меня есть, я не могу объяснить, насколько id ценит любую помощь, будь то оператор logi c или кодированный триггер, который может работать (Бонус). Огромное спасибо заранее. Я просто борюсь с экспортом всех LocKeys в переменные @ level1Key et c ..

Таблица расположений

Таблица логических уровней

Таблица транспортных средств

Код:

         SET ANSI_NULLS ON
    SET QUOTED_IDENTIFIER ON
    GO

    CREATE TRIGGER dbo.transferVehicle
    ON dbo.Vehicles
    AFTER INSERT 
    AS
    BEGIN
        SET NOCOUNT ON;

        DECLARE @Level0Key INT, @Level1Key INT, @Level2Key INT, @Level3Key INT, @Level4Key INT, @Level5Key INT,@Level6Key INT,@Level7Key INT, @LocKey INT;

        SELECT @LocKey = [LocKey] FROM Inserted ;

            with tbParent as
    (
        select * from Canepro.dbo.locations where LocKey= @LocKey
        union all
        select locations.* from Canepro.dbo.locations  join tbParent  on locations.LocKey = tbParent.ParentKey
    ),

        tbsons as
    (
        select * from Canepro.dbo.locations where LocKey= @LocKey
        union all
        select locations.* from Canepro.dbo.locations  join tbsons  on locations.ParentKey= tbsons.LocKey
    ),
        tball as
    (
        select * from  tbParent as p
        union 
        select * from tbsons as s

    ),
    final as
    (
    select number = ROW_NUMBER() OVER (ORDER BY t.LocKey), t.LocKey,t.LocName ,  t.ParentKey 
    from tball as t 
    )

    --I now need to export all rows (LocKeys) from final into the variables
    -- if i use two select statments (see below) i get an error on the second
select @LocKey1 = LocKey from final where number = 1
select @LocKey2 = Lockey from final where number = 2 


        INSERT INTO [NewDatabase].dbo.Vehicles (VehCode, VehicleNumber, RegistrationNumber, Description, FuelKey, CatKey, Active, ExpectedConsumption, IsPetrol, LicenseExpiryDate, FuelTankCapacity, OdometerReading, Level0LocKey, Level1LocKey, Level2LocKey,Level3LocKey, Level4LocKey, Level5LocKey, Level6LocKey, Level7Key)

            SELECT 
                VehCode, VehicleNumber, RegistrationNumber, Description, FuelType, CatKey, Active, ExpectedConsumption, IsPetrol, LicenseExpiryDate, FuelTankCapacity, OdometerReading, LocKey, @Level0Key, @Level1Key, @Level2Key, @Level3Key, @Level4Key, @Level5Key, @Level6Key, @Level7Key -- then all the other nodes that relate to the lockey, above and below is level from level0 (The top of the tree) to level 6 of the tree
            FROM   
                inserted;
    END
    GO

Ожидаемый ввод от вставки:

Vkey : 185 
Lockey : 60000690
VehCode : 52
VehicleNumber : 80/11A52
RegistrationNumber :NUF 37746
Description : Ford 6610 4x4 (52)
FuelType : 174
CatKey : 7
Active : 1
Expected consumption : Null
IsPetrol : 0
LicenseExpiryDate : 2011-04-30 00:00:00
FuelTankCapacity : 150
OdomenterReading : Hours 

Ожидаемый вывод в новую базу данных:

Vkey : 185 
Lockey : 60000690
VehCode : 52
VehicleNumber : 80/11A52
RegistrationNumber :NUF 37746
Description : Ford 6610 4x4 (52)
FuelType : 174
CatKey : 7
Active : 1
Expected consumption : Null
IsPetrol : 0
LicenseExpiryDate : 2011-04-30 00:00:00
FuelTankCapacity : 150
OdomenterReading : Hours 
Level0Key : 60000291 (Top Tree node)
Level1Key : 60002764 (Second Level of tree)
Level2Key : 60000841 (third level of tree)
Level3Key : 60000177 (Fourth level of tree)
Level4Key : 60000179 (Fifth level of tree)
Level5Key : 60000181 (sixth level of tree)
Level6Key : 60000205 (seventh level of tree)
Level7Key : 60000690 (Eighth level of tree)  
( We can see this one is the same as the Lockey)

Был бы очень признателен за помощь

1 Ответ

0 голосов
/ 21 апреля 2020

Задача 1

Если я использую два выбранных отчета (см. Ниже), я получаю сообщение об ошибке на втором

Это не работать, потому что ваш CTE исчезает после первого утверждения. Таким образом, вам нужно сохранить данные в рабочую таблицу.

Пример:

-- Set up a table variable to save results into
DECLARE @WorkTable TABLE (LevelNumber INT,LocKey INT,ParentKey INT)

DECLARE @LocKey INT = 11;

        with tbParent as
(
    select * from [Location] where LocKey= @LocKey
    union all
    select [Location].* from [Location]  join tbParent  on [Location].LocKey = tbParent.ParentKey
),

    tbsons as
(
    select * from [Location] where LocKey= @LocKey
    union all
    select [Location].* from [Location]  join tbsons  on [Location].ParentKey= tbsons.LocKey
),
    tball as
(
    select * from  tbParent as p
    union 
    select * from tbsons as s

),
final as
(
select LevelNumber = ROW_NUMBER() OVER (ORDER BY t.LocKey), t.LocKey,  t.ParentKey 
from tball as t 
)

-- Save the results into the table variable
INSERT INTO @WorkTable (LevelNumber,LocKey,ParentKey)
SELECT LevelNumber,LocKey,ParentKey from final

-- now we can do what we like with the table variables
select @LocKey1 = LocKey from final where number = 1
select @LocKey2 = Lockey from final where number = 2 

Но опять же я должен предостеречь вас от принудительного использования дерева ссылок на фиксированные уровни, если вы не уверены в данных всегда получается таким образом.

Задача 2

SELECT @LocKey = [LocKey] FROM Inserted;

INSERTED может содержать много строк. Это просто получает первый. Если есть какая-либо операция, которая вставляет или обновляет много строк, ваш триггер не будет работать должным образом. Вам нужно вставить l oop (или объединить) и работать с каждой строкой в ​​нем.

Пример DDL и вставок

Ниже приведен пример таблицы DDL и пример данных. Это позволяет нам настраивать ваши данные и работать с ними локально.

CREATE TABLE [LOCATION] (LocKey INT , ParentKey INT , TreeLevel INT)

INSERT INTO [LOCATION]
SELECT LocKey,ParentKey,TreeLevel
FROM 
(
VALUES 
(1,60000291,1),
(2,50000199,6),
(6,60000706,8),
(7,60000707,8),
(8,6,9),
(9,6,9),
(10,6,9),
(11,6,9),
(12,6,9),
(13,6,9),
(14,6,9),
(15,6,9),
(16,6,9),
(17,6,9)
) As T(LocKey,ParentKey,TreeLevel)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...