代码:
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
注意:
在实时环境中,表变量被实际表替换。
EmployeeID
和ParentEmployeeDepartmentID
列'价值观并不总是相互匹配。实时环境在udt(tEmployeeData
)中的记录多于4
目标:
udt(tEmployeeData
)将被传递到程序中
该程序应首先将数据插入@MainEmployee
表(并获取EmployeeID
s)
接下来,该过程应将数据插入@ParentEmployeeDepartment
表(并获取ParentEmployeeDepartmentID
) - 注意EmployeeID
来自上一个输出。
然后,程序应该根据DepartmentType
(" A" =插入@ChildEmployeeDepartmentTypeA和" B" =插入到子级别数据) @ChildEmployeeDepartmentTypeB)。
ParentEmployeeDepartmentID
或@ParentEmployeeDepartment
时,应使用来自@ChildEmployeeDepartmentTypeA
的 @ChildEmployeeDepartmentTypeB
程序应该快速运行(需要逐行操作)
输出:
@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
子句并获取EmployeeID
和ParentEmployeeDepartmentID
,但我不确定如何将正确的子记录插入到右表中正确映射到父表。任何帮助将不胜感激。
答案 0 :(得分:8)
以下是我的解决方案(基于我在评论中链接的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
然后,使用表变量将employee表中的插入值映射到发送到过程的数据中的临时员工ID:
DECLARE @EmployeeidMap TABLE
(
temp_id int,
id int
)
现在,诀窍是用MERGE
语句而不是INSERT...SELECT
填充employee表,因为你必须在输出子句中使用插入数据和源数据中的值:
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个插页。