Как лучше всего копировать иерархию объектов на SQL сервере - PullRequest
2 голосов
/ 24 июня 2011

Предположим, у нас есть иерархия, состоящая из нескольких объектов, например:

enter image description here

И я хочу скопировать это дерево (и, возможно, каким-то образом изменить эти объекты).

Простой способ сделать это - просто перебирать объекты и создавать их один за другим.Но производительность здесь очень плохая.Кроме того, я не люблю циклы; -)

Итак, вопрос - возможно ли это сделать с помощью логики на основе множеств?

1 Ответ

3 голосов
/ 27 июня 2011

Используя технику, описанную в этого вопроса , вы можете сделать что-то вроде этого:

DECLARE @CartId int, @NewCartId int;
DECLARE @CartItems TABLE (OldId int, NewId int);

SET @CartId = ...;

INSERT INTO Shopping_Cart (
  Session_Id_Str,
  Name,
  Program_User_Id,
  Shopping_Cart_Status_Code,
  Placed_Order_Id)
SELECT
  Shopping_Cart_Id,
  Session_Id_Str,
  Name,
  Program_User_Id,
  Shopping_Cart_Status_Code,
  Placed_Order_Id
FROM Shopping_Cart
WHERE Shopping_Cart_Id = @CartId;
SET @NewCartId = SCOPE_IDENTITY();

WITH src AS (
  SELECT
    Shopping_Cart_Item_Id,
    @NewCartId AS Shopping_Cart_Id,
    Base_Product_Id,
    Product_Category_Id,
    Shop_Id,
    Currency_Code
  FROM Shopping_Cart_Item
  WHERE Shopping_Cart_Id = @CartId
)
MERGE Shopping_Cart_Item AS tgt
USING src
ON 0 = 1
WHEN NOT MATCHED THEN
  INSERT (
    Shopping_Cart_Id,
    Base_Product_Id,
    Product_Category_Id,
    Shop_Id,
    Currency_Code)
  VALUES (
    src.Shopping_Cart_Id,
    src.Base_Product_Id,
    src.Product_Category_Id,
    src.Shop_Id,
    src.Currency_Code)
OUTPUT
  src.Shopping_Cart_Item_Id,
  inserted.Shopping_Cart_Item_Id
INTO @CartItems (OldId, NewId);

WITH src AS (
  SELECT
    s.Shopping_Cart_Item_Detail_Id,
    map.NewId AS Shopping_Cart_Item_Id,
    s.Display_Order_Number,
    s.Product_Id,
    s.Product_Variant_Id
  FROM Shopping_Cart_Item_Detail s
    INNER JOIN @CartItems map ON s.Shopping_Cart_Item_Id = map.OldId
)
MERGE Shopping_Cart_Item_Detail AS tgt
USING src
ON 0 = 1
WHEN NOT MATCHED THEN
  INSERT (
    Shopping_Cart_Item_Id,
    Display_Order_Number,
    Product_Id,
    Product_Variant_Id)
  VALUES (
    src.Shopping_Cart_Item_Id,
    src.Display_Order_Number,
    src.Product_Id,
    src.Product_Variant_Id);

Предполагается, что вы хотите копировать только одно «дерево» за раз.

Все это, вероятно, должно быть сделано за одну транзакцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...