0

再会

我有一个为特定前端应用程序设计的遗留数据库。我正在使用这些数据进行多个额外的应用程序开发案例,但是,遗留数据库已被证明不足以用于未来。不幸的是,由于我仍然需要运行前端应用程序,因此必须保留旧数据库。

我已经创建了一个将使用的类似结构的新数据库,每次通过前端应用程序将车辆(我们将使用的示例)添加到遗留数据库时,我都设置了一个触发器以将指定的数据推送到插入新数据库(这一切都很好)。

现在解决我的问题。每辆车都分配有一个位置键,该键描述了它在位置的层次树结构上属于哪个位置。我需要从任何树级别获取这个位置,并使用位置表在遗留数据库中找到它下方和上方的所有节点,然后将节点的所有位置键添加到新数据库中的车辆表中,这将由 7 个级别(列)组成。我只需要获取位置0,1,2,3,4,5,6,7.

例如,我将有七列,其中任何一个都可能是车辆注册位置。

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

据我了解,您需要查看旧数据库车辆表、逻辑级别表和位置表(所有位置都与父键一起列出)才能帮助我。

我将附上这些表格和我拥有的简单触发器,我无法解释我有多少帮助,无论是逻辑语句还是可能起作用的编码触发器(奖金)。提前非常感谢。我只是在与将所有 LocKeys 导出到变量 @level1Key 等作斗争。

位置表

逻辑级别表

车辆表

代码:

         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)

真的很感激一些帮助

4

1 回答 1

0

问题 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可以包含许多行。这只是得到第一个。如果有任何插入或更新许多行的操作,您的触发器将无法正常工作。您需要循环(或连接)插入并处理其中的每一行。

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)
于 2020-04-21T13:19:36.643 回答