gpt4 book ai didi

sql - T-SQL - 将数据插入父表和子表

转载 作者:行者123 更新时间:2023-12-02 18:28:38 25 4
gpt4 key购买 nike

代码:

CREATE TYPE dbo.tEmployeeData AS TABLE 
(
FirstName NVARCHAR(50),
LastName NVARCHAR(50),
DepartmentType NVARCHAR(10),
DepartmentBuilding NVARCHAR(50),
DepartmentEmployeeLevel NVARCHAR(10),
DepartmentTypeAMetadata NVARCHAR(100),
DepartmentTypeBMetadata NVARCHAR(100)
)
GO

CREATE PROC dbo.EmployeeImport
(@tEmployeeData tEmployeeData READONLY)
AS
BEGIN
DECLARE @MainEmployee TABLE
(EmployeeID INT IDENTITY(1,1),
FirstName NVARCHAR(50),
LastName NVARCHAR(50))

DECLARE @ParentEmployeeDepartment TABLE
(EmployeeID INT,
ParentEmployeeDepartmentID INT IDENTITY(1,1),
DepartmentType NVARCHAR(10))

DECLARE @ChildEmployeeDepartmentTypeA TABLE
(ParentEmployeeDepartmentID INT,
DepartmentBuilding NVARCHAR(50),
DepartmentEmployeeLevel NVARCHAR(10),
DepartmentTypeAMetadata NVARCHAR(100))

DECLARE @ChildEmployeeDepartmentTypeB TABLE
(ParentEmployeeDepartmentID INT,
DepartmentBuilding NVARCHAR(50),
DepartmentEmployeeLevel NVARCHAR(10),
DepartmentTypeBMetadata NVARCHAR(100))

-- INSERT CODE GOES HERE
SELECT * FROM @MainEmployee
SELECT * FROM @ParentEmployeeDepartment
SELECT * FROM @ChildEmployeeDepartmentTypeA
SELECT * FROM @ChildEmployeeDepartmentTypeB
END
GO

DECLARE @tEmployeeData tEmployeeData

INSERT INTO @tEmployeeData (FirstName, LastName, DepartmentType,
DepartmentBuilding, DepartmentEmployeeLevel,
DepartmentTypeAMetadata, DepartmentTypeBMetadata)
SELECT
N'Tom_FN', N'Tom_LN', N'A',
N'101', N'IV', N'Tech/IT', NULL
UNION
SELECT
N'Mike_FN', N'Mike_LN', N'B',
N'OpenH', N'XII', NULL, N'Med'
UNION
SELECT
N'Joe_FN', N'Joe_LN', N'A',
N'101', N'IV', N'Tech/IT', NULL
UNION
SELECT
N'Dave_FN', N'Dave_LN', N'B',
N'OpenC', N'XII', NULL, N'Lab'

EXEC EmployeeImport @tEmployeeData
GO

DROP PROC dbo.EmployeeImport
DROP TYPE dbo.tEmployeeData

注释:

  • 表变量被实时环境中的真实表替换。

  • EmployeeIDParentEmployeeDepartmentID 列的值并不总是相互匹配。实时环境在 udt (tEmployeeData) 中的记录数量多于 4

目标:

  • udt (tEmployeeData) 将传递到过程中

  • 该过程应首先将数据插入到 @MainEmployee 表中(并获取 EmployeeID)

  • 接下来,该过程应将数据插入到 @ParentEmployeeDepartment 表中(并获取 ParentEmployeeDepartmentID) - 注意 EmployeeID 是来自之前的输出。

  • 然后,该过程应根据 ​​DepartmentType 拆分子级数据(“A”= 插入@ChildEmployeeDepartmentTypeA,“B”= 插入@ChildEmployeeDepartmentTypeB)。

  • 将数据插入到 @ChildEmployeeDepartmentTypeA@ChildEmployeeDepartmentTypeB 时,应使用来自 @ParentEmployeeDepartment
  • ParentEmployeeDepartmentID >

  • 程序应该运行得很快(需要避免逐行操作)

输出:

@MainEmployee:

EmployeeID  FirstName   LastName
---------------------------------
1 Tom_FN Tom_LN
2 Mike_FN Mike_LN
3 Joe_FN Joe_LN
4 Dave_FN Dave_LN

@ParentEmployeeDepartment:

EmployeeID  ParentEmployeeDepartmentID  DepartmentType
-------------------------------------------------------
1 1 A
2 2 B
3 3 A
4 4 B

@ChildEmployeeDepartmentTypeA:

ParentEmployeeDepartmentID  DepartmentBuilding  DepartmentEmployeeLevel DepartmentTypeAMetadata
---------------------------------------------------------------------------------------------------------
1 101 IV Tech/IT
3 101 IV Tech/IT

@ChildEmployeeDepartmentTypeB:

ParentEmployeeDepartmentID  DepartmentBuilding  DepartmentEmployeeLevel DepartmentTypeAMetadata
----------------------------------------------------------------------------------------------------------
2 OpenH XII Med
4 OpenC XII Lab

我知道我可以在插入后使用OUTPUT子句并获取EmployeeIDParentEmployeeDepartmentID,但我不知道如何插入右子记录到右表中,并右映射到父表。任何帮助将不胜感激。

最佳答案

这是我的解决方案(基于我在评论中链接到的相同 answer):

首先,您必须向 UDT 添加另一列,以保存员工的临时 ID:

CREATE TYPE dbo.tEmployeeData AS TABLE 
(
FirstName NVARCHAR(50),
LastName NVARCHAR(50),
DepartmentType NVARCHAR(10),
DepartmentBuilding NVARCHAR(50),
DepartmentEmployeeLevel NVARCHAR(10),
DepartmentTypeAMetadata NVARCHAR(100),
DepartmentTypeBMetadata NVARCHAR(100),
EmployeeId int
)
GO

用新的employeeId 列填充它:

DECLARE @tEmployeeData tEmployeeData

INSERT INTO @tEmployeeData (FirstName, LastName, DepartmentType,
DepartmentBuilding, DepartmentEmployeeLevel,
DepartmentTypeAMetadata, DepartmentTypeBMetadata, EmployeeId)
SELECT
N'Tom_FN', N'Tom_LN', N'A',
N'101', N'IV', N'Tech/IT', NULL, 5
UNION
SELECT
N'Mike_FN', N'Mike_LN', N'B',
N'OpenH', N'XII', NULL, N'Med', 6
UNION
SELECT
N'Joe_FN', N'Joe_LN', N'A',
N'101', N'IV', N'Tech/IT', NULL, 7
UNION
SELECT
N'Dave_FN', N'Dave_LN', N'B',
N'OpenC', N'XII', NULL, N'Lab', 8

此处插入部分

然后,您使用表变量将插入的值从员工表映射到发送到过程的数据中的临时员工 ID:

DECLARE @EmployeeidMap TABLE
(
temp_id int,
id int
)

现在,诀窍是用 MERGE 填充员工表。语句而不是 INSERT...SELECT因为您必须在输出子句中使用插入数据和源数据中的值:

MERGE INTO @MainEmployee USING @tEmployeeData AS sourceData ON 1 = 0 -- Always not matched
WHEN NOT MATCHED THEN
INSERT (FirstName, LastName)
VALUES (sourceData.FirstName, sourceData.LastName)
OUTPUT sourceData.EmployeeId, inserted.EmployeeID
INTO @EmployeeidMap (temp_id, id); -- populate the map table

从这一点开始就很简单了,您需要连接发送到 @EmployeeidMap 的数据以获取实际的 employeeId:

INSERT INTO @ParentEmployeeDepartment (EmployeeID, DepartmentType)
SELECT Id, DepartmentType
FROM @tEmployeeData
INNER JOIN @EmployeeidMap ON EmployeeID = temp_id

现在您可以使用 @ParentEmployeeDepartment 中的数据将 ParentEmployeeDepartmentID 中的实际值映射到您发送的数据:

到目前为止正在测试插入

SELECT FirstName,
LastName,
SentData.DepartmentType As [Dept. Type],
DepartmentBuilding As Building,
DepartmentEmployeeLevel As [Emp. Level],
DepartmentTypeAMetadata As [A Meta],
DepartmentTypeBMetadata As [B Meta],
SentData.EmployeeId As TempId, EmpMap.id As [Emp. Id], DeptMap.ParentEmployeeDepartmentID As [Dept. Id]
FROM @tEmployeeData SentData
INNER JOIN @EmployeeidMap EmpMap ON SentData.EmployeeId = temp_id
INNER JOIN @ParentEmployeeDepartment DeptMap ON EmpMap.id = DeptMap.EmployeeID

结果:

FirstName   LastName    Dept. Type  Building    Emp. Level  A Meta      B Meta  TempId      Emp. Id     Dept. Id
--------- -------- ---------- -------- ---------- ------ ------ ------ ----------- -----------
Dave_FN Dave_LN B OpenC XII NULL Lab 8 1 1
Joe_FN Joe_LN A 101 IV Tech/IT NULL 7 2 2
Mike_FN Mike_LN B OpenH XII NULL Med 6 3 3
Tom_FN Tom_LN A 101 IV Tech/IT NULL 5 4 4

我确信从现在起您可以轻松地自己找出最后 2 个插入内容。

关于sql - T-SQL - 将数据插入父表和子表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38213008/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com