Sql 使用合并插入多个表?
我试图在父/子关系中插入一些行。如何在SQL中实现这一点 这将是我用来查找要插入的信息的基本查询:Sql 使用合并插入多个表?,sql,sql-server,merge,sql-server-2008-r2,Sql,Sql Server,Merge,Sql Server 2008 R2,我试图在父/子关系中插入一些行。如何在SQL中实现这一点 这将是我用来查找要插入的信息的基本查询: SELECT * FROM parentTable p INNER JOIN childTable c ON p.ID = c.ParentTableID WHERE p.PlanID = 123456 需要做的是首先插入ParentTable行,它实际上只是匹配行的一个副本,但具有新的PlanID和创建日期。然后,我从插入的行中获取ParentTable ID,并将其用于同一进程,但用
SELECT * FROM parentTable p
INNER JOIN childTable c
ON p.ID = c.ParentTableID
WHERE p.PlanID = 123456
需要做的是首先插入ParentTable行,它实际上只是匹配行的一个副本,但具有新的PlanID和创建日期。然后,我从插入的行中获取ParentTable ID,并将其用于同一进程,但用于子表
所以我需要在.Net中至少循环所有parentTable匹配,并为每个匹配创建一个childTable行
我试图使用MERGE和OUTPUT子句,但似乎我可能使用了一个方形的peg作为圆孔。使用某种光标会更好吗
这就是我根据下面的答案得出的结论。不幸的是,它没有抓住SCOPE_的身份…有什么诀窍吗?因为它返回NULL,所以我在插入中得到FK错误
USE MemberCenteredPlan
DECLARE @NewPlanID BIGINT;--49727690
DECLARE @OldPlanID BIGINT;--49725211
DECLARE @NewSWReAssID BIGINT;
SET @NewPlanID = 49727690
SET @OldPlanID = 49725211
BEGIN
INSERT INTO tblSocialWorkerReAssessment
SELECT
@NewPlanID
,[Discussed]
,Discussion
,NULL
,NULL
,NULL
,CreatedBy
,GETDATE()
,NULL
,NULL
FROM tblSocialWorkerReAssessment
WHERE PlanID = @OldPlanID
SELECT @NewSWReAssID = SCOPE_IDENTITY();
INSERT INTO tblPlanDomain
SELECT
@NewPlanID
,[DomainTypeID]
,[MemberOutcomes]
,[MemberPreferences]
,[DomainDate]
,[Steps]
,[ClinicalFunctionalConcerns]
,[ReportWageES]
,[ReportWageSSA]
,@NewSWReAssID
,[CreatedBy]
,GETDATE()
,NULL
,NULL
,NEWID()
FROM tblPlanDomain
WHERE planID = @OldPlanID
END
您不需要合并,也不需要游标。而INSERT或MERGE一次只能影响一个表,因此您仍然需要执行多个语句。如果您一次只处理一个计划,您可以这样做:
DECLARE @NewPlanID INT;
INSERT dbo.ParentTable(cols...)
SELECT cols...
FROM dbo.ParentTable WHERE PlanID = 123456;
SELECT @NewPlanID = SCOPE_IDENTITY();
INSERT dbo.ChildTable(ParentTableID, cols...)
SELECT @NewPlanID, cols...
FROM dbo.ChildTable WHERE PlanID = 123456;
如果您需要引用多个新计划,它会变得更加复杂,在这种情况下,您现在需要使用MERGE,INSERT的composable DML有点轻描淡写——您不能在OUTPUT子句中引用源表
然而,你应该对此非常谨慎。。。我用MERGE-in链接到几个问题和未解决的bug。我还提供了您不需要合并,也绝对不需要游标。而INSERT或MERGE一次只能影响一个表,因此您仍然需要执行多个语句。如果您一次只处理一个计划,您可以这样做:
DECLARE @NewPlanID INT;
INSERT dbo.ParentTable(cols...)
SELECT cols...
FROM dbo.ParentTable WHERE PlanID = 123456;
SELECT @NewPlanID = SCOPE_IDENTITY();
INSERT dbo.ChildTable(ParentTableID, cols...)
SELECT @NewPlanID, cols...
FROM dbo.ChildTable WHERE PlanID = 123456;
如果您需要引用多个新计划,它会变得更加复杂,在这种情况下,您现在需要使用MERGE,INSERT的composable DML有点轻描淡写——您不能在OUTPUT子句中引用源表
然而,你应该对此非常谨慎。。。我用MERGE-in链接到几个问题和未解决的bug。我也我想这就是你想要的
Use Northwind
GO
SET NOCOUNT ON
IF OBJECT_ID('tempdb..#OrderAuditHolder') IS NOT NULL
begin
drop table #OrderAuditHolder
end
CREATE TABLE #OrderAuditHolder
(
[OriginalOrderID] [int] NOT NULL,
[NewOrderID] [int] NOT NULL,
[CustomerID] [nchar](5) NULL,
[EmployeeID] [int] NULL,
[OrderDate] [datetime] NULL,
[RequiredDate] [datetime] NULL,
[ShippedDate] [datetime] NULL,
[ShipVia] [int] NULL,
[Freight] [money] NULL,
[ShipName] [nvarchar](40) NULL,
[ShipAddress] [nvarchar](60) NULL,
[ShipCity] [nvarchar](15) NULL,
[ShipRegion] [nvarchar](15) NULL,
[ShipPostalCode] [nvarchar](10) NULL,
[ShipCountry] [nvarchar](15) NULL,
)
declare @ExampleOrderID int
select @ExampleOrderID = (select top 1 OrderID from dbo.Orders ords where exists (select null from dbo.[Order Details] innerOD where innerOD.OrderID = ords.OrderID ) )
print '/@ExampleOrderID/'
print @ExampleOrderID
print ''
insert into dbo.Orders (CustomerID,EmployeeID,OrderDate,RequiredDate,ShippedDate,ShipVia,Freight,ShipName,ShipAddress,ShipCity,ShipRegion,ShipPostalCode,ShipCountry)
output @ExampleOrderID , inserted.OrderID,inserted.CustomerID,inserted.EmployeeID,inserted.OrderDate,inserted.RequiredDate,inserted.ShippedDate,inserted.ShipVia,inserted.Freight,inserted.ShipName,inserted.ShipAddress,inserted.ShipCity,inserted.ShipRegion,inserted.ShipPostalCode,inserted.ShipCountry
into #OrderAuditHolder
Select
CustomerID,EmployeeID,OrderDate,RequiredDate,ShippedDate,ShipVia,Freight,ShipName,ShipAddress,ShipCity,ShipRegion,ShipPostalCode,ShipCountry
from dbo.Orders where OrderID = @ExampleOrderID
print '/#OrderAuditHolder/'
Select * from #OrderAuditHolder
print ''
Insert into dbo.[Order Details] ( OrderID , ProductID , UnitPrice , Quantity , Discount )
Select
holder.NewOrderID , od.ProductID , od.UnitPrice , od.Quantity , od.Discount
from #OrderAuditHolder holder
join dbo.[Order Details] od on holder.OriginalOrderID = od.OrderID
/* Note, the "join" is on the OriginalOrderID, but the inserted value is the NewOrderID */
/* below is not needed, but shows results */
declare @MaxOrderID int
select @MaxOrderID = (select MAX(OrderID) from dbo.Orders ords where exists (select null from dbo.[Order Details] innerOD where innerOD.OrderID = ords.OrderID ) )
select * from dbo.[Order Details] where OrderID = @MaxOrderID order by OrderID desc
/**/
IF OBJECT_ID('tempdb..#OrderAuditHolder') IS NOT NULL
begin
drop table #OrderAuditHolder
end
SET NOCOUNT OFF
我想这就是你想要的
Use Northwind
GO
SET NOCOUNT ON
IF OBJECT_ID('tempdb..#OrderAuditHolder') IS NOT NULL
begin
drop table #OrderAuditHolder
end
CREATE TABLE #OrderAuditHolder
(
[OriginalOrderID] [int] NOT NULL,
[NewOrderID] [int] NOT NULL,
[CustomerID] [nchar](5) NULL,
[EmployeeID] [int] NULL,
[OrderDate] [datetime] NULL,
[RequiredDate] [datetime] NULL,
[ShippedDate] [datetime] NULL,
[ShipVia] [int] NULL,
[Freight] [money] NULL,
[ShipName] [nvarchar](40) NULL,
[ShipAddress] [nvarchar](60) NULL,
[ShipCity] [nvarchar](15) NULL,
[ShipRegion] [nvarchar](15) NULL,
[ShipPostalCode] [nvarchar](10) NULL,
[ShipCountry] [nvarchar](15) NULL,
)
declare @ExampleOrderID int
select @ExampleOrderID = (select top 1 OrderID from dbo.Orders ords where exists (select null from dbo.[Order Details] innerOD where innerOD.OrderID = ords.OrderID ) )
print '/@ExampleOrderID/'
print @ExampleOrderID
print ''
insert into dbo.Orders (CustomerID,EmployeeID,OrderDate,RequiredDate,ShippedDate,ShipVia,Freight,ShipName,ShipAddress,ShipCity,ShipRegion,ShipPostalCode,ShipCountry)
output @ExampleOrderID , inserted.OrderID,inserted.CustomerID,inserted.EmployeeID,inserted.OrderDate,inserted.RequiredDate,inserted.ShippedDate,inserted.ShipVia,inserted.Freight,inserted.ShipName,inserted.ShipAddress,inserted.ShipCity,inserted.ShipRegion,inserted.ShipPostalCode,inserted.ShipCountry
into #OrderAuditHolder
Select
CustomerID,EmployeeID,OrderDate,RequiredDate,ShippedDate,ShipVia,Freight,ShipName,ShipAddress,ShipCity,ShipRegion,ShipPostalCode,ShipCountry
from dbo.Orders where OrderID = @ExampleOrderID
print '/#OrderAuditHolder/'
Select * from #OrderAuditHolder
print ''
Insert into dbo.[Order Details] ( OrderID , ProductID , UnitPrice , Quantity , Discount )
Select
holder.NewOrderID , od.ProductID , od.UnitPrice , od.Quantity , od.Discount
from #OrderAuditHolder holder
join dbo.[Order Details] od on holder.OriginalOrderID = od.OrderID
/* Note, the "join" is on the OriginalOrderID, but the inserted value is the NewOrderID */
/* below is not needed, but shows results */
declare @MaxOrderID int
select @MaxOrderID = (select MAX(OrderID) from dbo.Orders ords where exists (select null from dbo.[Order Details] innerOD where innerOD.OrderID = ords.OrderID ) )
select * from dbo.[Order Details] where OrderID = @MaxOrderID order by OrderID desc
/**/
IF OBJECT_ID('tempdb..#OrderAuditHolder') IS NOT NULL
begin
drop table #OrderAuditHolder
end
SET NOCOUNT OFF
严格来说,您可以使用可更新的分区视图在一条语句中插入多个表。。。这里只是吹毛求疵。严格来说,您可以使用可更新的分区视图在一条语句中插入多个表。。。只是吹毛求疵。