【发布时间】:2016-11-07 20:32:29
【问题描述】:
代码:
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列的值并不总是相互匹配。 Live 环境在 udt (tEmployeeData) 中的记录多于 4 条
目标:
udt (
tEmployeeData) 将被传递到过程中该过程应首先将数据插入
@MainEmployee表中(并获取EmployeeIDs)接下来,该过程应该将数据插入
@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 子句并获得EmployeeID 和ParentEmployeeDepartmentID,但我不确定如何将正确的子记录插入到正确映射到父表的正确表中。任何帮助将不胜感激。
【问题讨论】:
-
USE OUTPUT Inserted.EmployedId, Inserted.ParentEmployeeDepartmentType INTO TempTable (employeeid, ...) 然后为子项执行 2 条插入语句,其中部门 = A,然后为下一个部门 = b。
-
You might want to look at this answer。我的解决方案是为每个表使用不同的 UDT,但如果必须,可以将其转换为使用单个 UDT。
-
@Matt,例如,如何防止 ParentEmployeeDepartmentID 的 2 与 4 的子数据错误映射? ZoharPeled,我会研究那个解决方案。我认为,这种情况的问题是我们没有主/父表的唯一“id”字段。
-
进一步看,是的,您将需要一个临时密钥。这可以通过将您的 UDT 转储到临时表中并分配一个身份来完成,或者按照 Zohar 的建议扩展您的 udt 以保存一个身份。如果没有密钥,您将不得不依赖名字和姓氏组合是唯一的,这在一个小的设置中可能是正确的,但不会持续很长时间。虽然我并不总是 MERGE 的粉丝,但我确实喜欢 Zohar 使用它来维护键之间的关系。
-
@matt 谢谢,我对合并也有同样的感觉。但是,这是我所知道的从源表和插入的数据中获取输出的唯一方法。
标签: sql sql-server sql-server-2012