久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

在 mssql 中復制多級相關表

Copying multi level related tables in mssql(在 mssql 中復制多級相關表)
本文介紹了在 mssql 中復制多級相關表的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

我有 4 個相關表,每個表與下一個表有 1:N 關系,例如

一個(OneID pk)兩個(TwoID pk,OneID fk)三(ThreeID pk,TwoID fk)四(FourID pk,ThreeID fk)

當用戶想要復制一"中的記錄以及表二、三和四中的所有相關記錄時,我需要實現功能.

從前端完成此操作,以便用戶可以在現有記錄的基礎上創建新記錄.做這個的最好方式是什么?我有新插入的OneID"和原始的OneID".

我想到的一種方法是為每個表創建一個復制"存儲過程,在每個表中都有一個游標,為每一行調用它的子表復制 SP.

我想到的唯一另一種方法是創建一個臨時表,其中記錄了每個表的原始 ID + 新 ID,但這看起來很混亂,而且可能會失控.

有什么建議嗎?

解決方案

如果您的 PK 是 IDENTITY 列,您可以使用 MERGE 中描述的技術a title="使用merge..output得到source.id 和 target.id 之間的映射">這個問題.

以下是整個過程的腳本編寫方式:

DECLARE @OldID int, @NewID int;SET @OldID = some_value;聲明 @TwoMapping 表 (OldID int, NewID int);聲明 @ThreeMapping 表 (OldID int, NewID int);插入一個選擇從一哪里 OneID = @OldID;SET @NewID = SCOPE_IDENTITY();/*那個很簡單:一行被復制,所以只需閱讀 SCOPE_IDENTITY()插入后.實際的映射技術從這一點開始.*/合并兩個 tgt使用 (選擇@NewID 作為 OneID,其他欄目從兩噸哪里 OneID = @OldID) 源文件開 0 = 1當不匹配時INSERT (columns) VALUES (src.columns)OUTPUT src.TwoID, INSERTED.TwoID INTO @TwoMapping (OldID, NewID);/*如您所見,MERGE 允許我們在OUTPUT 子句,除了偽表 INSERTED 和 DELETED,這是優于 INSERT 和方法核心的一大優勢.*/

<預><代碼>合并三個 tgt使用 (選擇map.NewID AS TwoID,t.其他欄目從三噸INNER JOIN @TwoMapping 映射上 t.TwoID = map.OldID) 源文件開 0 = 1當不匹配時INSERT (columns) VALUES (src.columns)OUTPUT src.ThreeID, INSERTED.ThreeID INTO @ThreeMapping (OldID, NewID);/*現在我們有了一個映射表,我們可以很容易地用新的 FK 代替舊的具有簡單連接的那些.在接下來的 MERGE 中再次重復相同的操作.*/合并四個 tgt使用 (選擇map.NewID AS ThreeID,t.從四噸INNER JOIN @ThreeMapping map ON t.ThreeID = map.OldID) 源文件開 0 = 1當不匹配時INSERT (columns) VALUES (src.columns);/*Four 表是依賴鏈中的最后一個,所以最后一個 MERGE沒有 OUTPUT 子句.但是如果有一張五人桌,我們會像上面那樣繼續.*/

或者,您可能不得不使用游標,這似乎是在 SQL Server 2005 及更早版本中執行此操作的唯一(合理)方法.

I have 4 related tables, each has a 1:N relationship with the next table, e.g.

One (OneID pk)
Two (TwoID pk, OneID fk)
Three (ThreeID pk, TwoID fk)
Four (FourID pk, ThreeID fk)

I need to implement functionality for when the user wants to copy a record in 'One' and all related records in tables Two, Three and Four.

From the front end this is done so that the user can base a new record on an existing one. What is the best way to do this? I have the newly inserted 'OneID' and the Original 'OneID'.

One way that I've thought of doing this is to have a 'Copy' stored procedure for each table, in each of them have a cursor that calls it's child tables Copy SP once for each row.

The only other way I've thought of doing it was to have a temp table that has a record of the original + new IDs for each table but this seemed messy and like it could get out of hand.

Any suggestions?

解決方案

If your PKs are IDENTITY columns, you could use a technique involving MERGE that is described in this question.

Here's how the entire process might be scripted:

DECLARE @OldID int, @NewID int;
SET @OldID = some_value;

DECLARE @TwoMapping TABLE (OldID int, NewID int);
DECLARE @ThreeMapping TABLE (OldID int, NewID int);

INSERT INTO One
SELECT columns
FROM One
WHERE OneID = @OldID;
SET @NewID = SCOPE_IDENTITY();
/*
That one was simple: one row is copied, so just reading SCOPE_IDENTITY()
after the INSERT. The actual mapping technique starts at this point.
*/

MERGE Two tgt
USING (
  SELECT
    @NewID AS OneID,
    other columns
  FROM Two t
  WHERE OneID = @OldID
) src
ON 0 = 1
WHEN NOT MATCHED THEN
  INSERT (columns) VALUES (src.columns)
OUTPUT src.TwoID, INSERTED.TwoID INTO @TwoMapping (OldID, NewID);
/*
As you can see, MERGE allows us to reference the source table in the
OUTPUT clause, in addition to the pseudo-tables INSERTED and DELETED,
and that is a great advantage over INSERT and the core of the method.
*/


MERGE Three tgt
USING (
  SELECT
    map.NewID AS TwoID,
    t.other columns
  FROM Three t
    INNER JOIN @TwoMapping map ON t.TwoID = map.OldID
) src
ON 0 = 1
WHEN NOT MATCHED THEN
  INSERT (columns) VALUES (src.columns)
OUTPUT src.ThreeID, INSERTED.ThreeID INTO @ThreeMapping (OldID, NewID);
/*
Now that we've got a mapping table, we can easily substitute new FKs for the old
ones with a simple join. The same is repeated once again in the following MERGE.
*/

MERGE Four tgt
USING (
  SELECT
    map.NewID AS ThreeID,
    t.columns
  FROM Four t
    INNER JOIN @ThreeMapping map ON t.ThreeID = map.OldID
) src
ON 0 = 1
WHEN NOT MATCHED THEN
  INSERT (columns) VALUES (src.columns);
/*
The Four table is the last one in the chain of dependencies, so the last MERGE
has no OUTPUT clause. But if there were a Five table, we would go on like above.
*/

Alternatively you'd probably have to use cursors, which seems to be the only (sane) way of doing this in SQL Server 2005 and earlier versions.

這篇關于在 mssql 中復制多級相關表的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

Converting Every Child Tags in to a Single Column with multiple Delimiters -SQL Server (3)(將每個子標記轉換為具有多個分隔符的單列-SQL Server (3))
How can I create a view from more than one table?(如何從多個表創建視圖?)
Create calculated value based on calculated value inside previous row(根據前一行內的計算值創建計算值)
How do I stack the first two columns of a table into a single column, but also pair third column with the first column only?(如何將表格的前兩列堆疊成一列,但也僅將第三列與第一列配對?) - IT屋-程序員軟件開發技
Recursive t-sql query(遞歸 t-sql 查詢)
Convert Month Name to Date / Month Number (Combinations of Questions amp; Answers)(將月份名稱轉換為日期/月份編號(問題和答案的組合))
主站蜘蛛池模板: 成人三级网址 | 亚洲国产高清高潮精品美女 | 看羞羞视频 | 国产精品色哟哟网站 | 亚洲视频二区 | 日韩波多野结衣 | 国产午夜精品理论片a大结局 | 天天视频成人 | 嫩草一区二区三区 | 看真人视频一级毛片 | 国产农村一级片 | 日韩精品久久久久久 | 国产成人精品亚洲日本在线观看 | 欧美v在线观看 | 亚洲国产69 | 日韩在线小视频 | 在线免费观看a级片 | 国产精品一区二区久久 | 在线观看亚 | 男女污污网站 | 欧美一区二区免费视频 | 99re视频精品 | 毛片区| 九九99久久| 国产日韩精品一区 | 国产激情视频网址 | 91免费在线看 | 羞视频在线观看 | 国产精品.xx视频.xxtv | 国产二区视频 | 久久久网 | 91精品久久久久久久久久入口 | 免费一级黄 | 国产精品成人国产乱一区 | 日韩精品专区在线影院重磅 | 亚洲va国产日韩欧美精品色婷婷 | 蜜桃视频在线观看免费视频网站www | 欧美在线视频网站 | 九九久久精品 | 国产成人99久久亚洲综合精品 | 成年人在线视频 |