如何在T-SQL中插入主详细记录?

时间:2014-11-07 13:05:51

标签: sql-server sql-server-2008 tsql

我需要复制一些主要细节记录,包括:

INSERT INTO Order
(
    SupplierId
   ,DateOrdered
)
SELECT 
   SupplierID
  ,DateOrdered
FROM Order
WHERE SupplierId = 10

DECLARE @OrderId int;

Select @OrderId = Scope_Identity;

INSERT INTO OrderItem
(
   Quantity
  ,ProductCode
  ,Price
  ,FkOrderId
)
SELECT 
  Quantity
 ,ProductCode
 ,Price 
 ,FkOrderId
FROM OrderItem 
WHERE FkOrderId = @OrderId

这不起作用。原因是供应商有多个订单= 10.那么,在供应商= 10,添加订单,然后在进入下一个订单记录之前添加相关子订单项的最佳方式是什么? 10。我想我正在讨论批处理,可能是游标,但我是T-SQL / Store程序的新手。

我很感激上述建议。

感谢。

修改

我希望通过一些样本数据澄清更多信息。

Original Order Table

Id       SupplierId         DateOrdered
 1          10                01/01/2000
 2          10                01/01/2000

Original OrderItem Table

Id       Quantity      ProductCode     Price      FkOrderId
 1          20             X1           100           1
 2          10             Y1            50           1
 3          30             X1           100           2
 4          20             Y1            50           2

Final Order Table

Id       SupplierId         DateOrdered
 1          10                01/01/2000
 2          10                01/01/2000
 3          10                01/01/2000    (Clone of 1)
 4          10                01/01/2000    (Clone of 2)

Final OrderItem Table

Id       Quantity      ProductCode     Price      FkOrderId
 1          20             X1           100           1
 2          10             Y1            50           1
 3          30             X1           100           2
 4          20             Y1            50           2
 5          20             X1           100           3 (Clone of 1, linked to clone Order=3)
 6          10             Y1            50           3 (Clone of 2, linked to clone Order=3)
 7          30             X1           100           4 (Clone of 3, linked to clone Order=4)
 8          20             Y1            50           5 (Clone of 4, linked to clone Order=4)

所以我需要一些帮助,代码可以通过克隆Order和OrderItem来实现" final"表记录。

似乎我需要做类似的事情:

For each matching record in "Order"

  Clone Order Record
  Clone OrderItem Record where FkOrderId = OldOrderId

Next

6 个答案:

答案 0 :(得分:8)

这回答了你的问题(也没有游标)

SQL Fiddle

MS SQL Server 2008架构设置

CREATE TABLE [Order]
(
    Id Int Primary Key Identity,
    SupplierId Int,
    DateOrdered Date
)

SET IDENTITY_INSERT [Order] ON

INSERT INTO [Order] (Id, SupplierId, DateOrdered)
VALUES
    (1, 10, '01/01/2000'),
    (2, 10, '01/01/2000')

SET IDENTITY_INSERT [Order] OFF


CREATE TABLE [OrderItem]
(
    ID INT Primary Key Identity,
    Quantity Int,
    ProductCode CHAR(2),
    Price Int,
    FKOrderId Int
)
SET IDENTITY_INSERT [OrderItem] ON

INSERT INTO [OrderItem] (Id, Quantity, ProductCode, Price, FKOrderId)
VALUES 
    (1, 20, 'X1', 100, 1),
    (2, 10, 'Y1', 50, 1),
    (3, 30, 'X1', 100, 2),
    (4, 20, 'Y1', 50, 2)

SET IDENTITY_INSERT [OrderItem] OFF

查询1

DECLARE @NewEntries TABLE (ID Int, OldId Int);


MERGE INTO [Order]
USING [Order] AS cf
ON 1 = 0 -- Ensure never match - therefore an Insert
WHEN NOT MATCHED AND cf.SupplierId = 10 THEN
  INSERT(SupplierId, DateOrdered) Values(cf.SupplierId, cf.DateOrdered)
Output inserted.Id, cf.Id INTO 
  @NewEntries(Id, OldId);

INSERT INTO [OrderItem]
(
   Quantity
  ,ProductCode
  ,Price
  ,FkOrderId
)
SELECT 
  Quantity
 ,ProductCode
 ,Price 
 ,NE.ID
FROM [OrderItem] OI
INNER JOIN @NewEntries NE
    ON OI.FKOrderId = NE.OldId ;


SELECT *
FROM [OrderItem];

<强> Results

| ID | QUANTITY | PRODUCTCODE | PRICE | FKORDERID |
|----|----------|-------------|-------|-----------|
|  1 |       20 |          X1 |   100 |         1 |
|  2 |       10 |          Y1 |    50 |         1 |
|  3 |       30 |          X1 |   100 |         2 |
|  4 |       20 |          Y1 |    50 |         2 |
|  5 |       20 |          X1 |   100 |         3 |
|  6 |       10 |          Y1 |    50 |         3 |
|  7 |       30 |          X1 |   100 |         4 |
|  8 |       20 |          Y1 |    50 |         4 |

答案 1 :(得分:3)

在Order表中添加一个名为OriginalOrderId的附加列。让它可以为空,FK回到OrderId,并在其上放一个索引。使用“INSERT INTO [Order] ... SELECT ... OUTPUT INSERTED。* INTO #ClonedOrders From ...”。在#ClonedOrders.OriginalOrderId上添加索引。然后你可以“INSERT INTO OrderItem ... SELECT co.OrderId,... FROM #ClonedOrders co INNER JOIN OrderItem oi ON oi.OrderId = co.OriginalOrderId”。这将为您提供您正在寻找的功能,以及基于集合的语句的性能优势。它还将为您提供订单原始来源的证据以及可用于区分克隆订单和非克隆订单的字段。

答案 2 :(得分:1)

在这种情况下你必须使用输出子句..让我给你一个示例脚本,它将帮助你与你的需求相关

Declare @Order AS Table(id  int identity(1,1),SupplierID INT)

DECLARE @outputOrder AS TABLE 
(Orderid INT)

INSERT INTO @Order (SupplierID)
    Output inserted.id into @outputOrder
    Values (102),(202),(303)    


select * from @outputOrder

您的案例的下一步将使用来自outputorder表&amp;的新生成的orderid。 join从输入表中获取orderitems

答案 3 :(得分:1)

这将处理你的第一张桌子。

PS:在这种状态下提供您的问题,他们的答案会更快。

IF OBJECT_ID('Orders') IS NOT NULL DROP TABLE Orders
IF OBJECT_ID('OrderItem') IS NOT NULL DROP TABLE OrderItem
IF OBJECT_ID('tempdb..#FinalOrders') IS NOT NULL DROP TABLE #FinalOrders


CREATE TABLE Orders (OrdersID INT, SupplierID INT, DateOrdered DATETIME)

CREATE TABLE OrderItem (OrderItemID INT, Quantity INT, FkOrderId INT)

INSERT INTO Orders VALUES (1,20,'01/01/2000'),(2,20,'01/01/2000')

INSERT INTO OrderItem VALUES
(1,20,1),
(2,10,1),
(3,30,2),
(4,20,2)

SELECT 
    a.OrderItemID,
    b.SupplierID,
    b.DateOrdered
INTO #FinalOrders
FROM OrderItem as a
INNER JOIN Orders as b
ON a.FkOrderId = b.OrdersID

SELECT * FROM #FinalOrders

答案 4 :(得分:1)

这可以通过游标实现。但请注意,游标将带来显着的性能缺陷。

DECLARE @SupplierID AS INT
DECLARE @OrderId AS INT
DECLARE @DateOrdered AS DATE
DECLARE @OrderIdNew AS INT

Declare @Order AS Table(OrderId INT,SupplierID INT,DateOrdered Date)

INSERT INTO @Order
SELECT 
   ID
  ,SupplierID
  ,DateOrdered
FROM [Order]
WHERE SupplierId = 10

DECLARE CUR CURSOR FAST_FORWARD FOR
SELECT 
   OrderId
  ,SupplierID
  ,DateOrdered
FROM @Order

OPEN CUR
FETCH NEXT FROM CUR INTO @OrderId, @SupplierID, @DateOrdered
WHILE @@FETCH_STATUS = 0
BEGIN
    INSERT INTO [Order]
    (
    SupplierId
   ,DateOrdered
    )
    VALUES
    (@SupplierID,@DateOrdered)

    Select  @OrderIdNew=@@IDENTITY

    INSERT INTO [OrderItem]
           ([Quantity]
           ,[ProductCode]
           ,[Price]
           ,[FkOrderId])
     SELECT [Quantity]
           ,[ProductCode]
           ,[Price]
           ,@OrderIdNew
     FROM [OrderItem]
     WHERE [FkOrderId]=@OrderId
    FETCH NEXT FROM CUR INTO @OrderId, @SupplierID, @DateOrdered
END

CLOSE CUR;
DEALLOCATE CUR;

答案 5 :(得分:1)

您可以尝试在Order和OrderItems之间进行内部联接,其中内部联接的子句是SupplierId = 10, 或者只是修改你的位置以获得相同的结果。 尝试按照以下方式做一些事情:

INSERT INTO OrderItem
(
   Quantity
  ,ProductCode
  ,Price
  ,FkOrderId
)
SELECT 
  Quantity
 ,ProductCode
 ,Price 
 ,FkOrderId
FROM OrderItem 
where FkOrderId in (Select Id FROM Order WHERE SupplierId = 10)
相关问题