SQL 服务器触发器(我需要从任何给定节点遍历分层树结构)
SQL Server trigger (I need to move through a hierarchical tree structure from any given node)
美好的一天
我有一个专为特定前端应用程序设计的遗留数据库。我正在使用这些数据进行多个额外的应用程序开发案例,但是,遗留数据库已被证明不足以用于未来。不幸的是,由于我仍然需要前端应用程序 运行,遗留数据库必须保留在原地。
我创建了一个类似结构的新数据库,每次通过前端应用程序将车辆(我们将使用的示例)添加到遗留数据库时,我都设置了一个触发器来推送将指定的数据插入到新数据库中(一切正常)。
现在开始解决我的问题。每辆车都分配有一个位置键,它描述了它在位置的层次树结构中属于哪个位置。我需要从任何树级别获取这个位置,并使用位置 table 在遗留数据库中找到它下方和上方的所有节点,然后将节点的所有位置键添加到车辆 table 在新数据库中,它将包含 7 个级别(列)。我只需要获取 Location 0,1,2,3,4,5,6,7.
例如,我将有七列,其中任何一列都可能是车辆的注册位置。
(Level0Key, Level1Key, Level2key,...,...,..., Level6Key, Level7Key)
据我了解,您需要查看遗留数据库车辆 table、逻辑级别 table 和位置 table(所有位置都列出了父键)为了帮助我。
我将附上这些 table 和我拥有的简单触发器,我无法解释我是多么感激任何帮助,无论是逻辑语句还是可能起作用的编码触发器(奖励)。非常感谢。
我只是在努力将所有 LocKeys 导出到变量@level1Key 等。
Locations Table
Logical levels table
Vehicles table
代码:
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
if i use two select statments (see below) i get an error on the second
这不起作用,因为您的 CTE 在第一个语句后消失了。所以需要将数据保存成作品table.
示例:
-- 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
可以包含很多行。这只是第一个。如果有任何插入或更新许多行的操作,您的触发器将无法正常工作。您需要循环(或连接)插入并处理其中的每一行。
DDL 和插入示例
下面是 table 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)
美好的一天
我有一个专为特定前端应用程序设计的遗留数据库。我正在使用这些数据进行多个额外的应用程序开发案例,但是,遗留数据库已被证明不足以用于未来。不幸的是,由于我仍然需要前端应用程序 运行,遗留数据库必须保留在原地。
我创建了一个类似结构的新数据库,每次通过前端应用程序将车辆(我们将使用的示例)添加到遗留数据库时,我都设置了一个触发器来推送将指定的数据插入到新数据库中(一切正常)。
现在开始解决我的问题。每辆车都分配有一个位置键,它描述了它在位置的层次树结构中属于哪个位置。我需要从任何树级别获取这个位置,并使用位置 table 在遗留数据库中找到它下方和上方的所有节点,然后将节点的所有位置键添加到车辆 table 在新数据库中,它将包含 7 个级别(列)。我只需要获取 Location 0,1,2,3,4,5,6,7.
例如,我将有七列,其中任何一列都可能是车辆的注册位置。
(Level0Key, Level1Key, Level2key,...,...,..., Level6Key, Level7Key)
据我了解,您需要查看遗留数据库车辆 table、逻辑级别 table 和位置 table(所有位置都列出了父键)为了帮助我。
我将附上这些 table 和我拥有的简单触发器,我无法解释我是多么感激任何帮助,无论是逻辑语句还是可能起作用的编码触发器(奖励)。非常感谢。 我只是在努力将所有 LocKeys 导出到变量@level1Key 等。
Locations Table
Logical levels table
Vehicles table
代码:
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
if i use two select statments (see below) i get an error on the second
这不起作用,因为您的 CTE 在第一个语句后消失了。所以需要将数据保存成作品table.
示例:
-- 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
可以包含很多行。这只是第一个。如果有任何插入或更新许多行的操作,您的触发器将无法正常工作。您需要循环(或连接)插入并处理其中的每一行。
DDL 和插入示例
下面是 table 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)