插入子表并在父表上更新FK

时间:2019-05-30 12:52:08

标签: sql sql-server tsql

我有一个具有以下结构和数据的父表:

---------------------------------------------
|  Id | TranslationId |                Name |
---------------------------------------------
|   1 |          NULL |          Image1.jpg |
|   2 |          NULL |          Image7.jpg |
|   3 |          NULL |    Picture_Test.png |
---------------------------------------------

还有保存已翻译图像的空子表:

-------------------------------------------------------------------------
|  Id |                  De |                  Fr |                  En |
-------------------------------------------------------------------------
|     |                     |                     |                     |
-------------------------------------------------------------------------

现在,我正在寻找一个查询语句或至少几个无需进一步编程即可运行的查询。用脚本或编程来完成这项工作很容易,但是我经常遇到需要这种插入/更新的情况。而且每次开发小型控制台应用程序都不可行。

最后,两个表应如下所示:

---------------------------------------------
|  Id | TranslationId |                Name |
---------------------------------------------
|   1 |            28 |                NULL |
|   2 |            29 |                NULL |
|   3 |            30 |                NULL |
---------------------------------------------
-------------------------------------------------------------------------
|  Id |                  De |                  Fr |                  En |
-------------------------------------------------------------------------
|  28 |          Image1.jpg |                NULL |               NULL  |
|  29 |          Image7.jpg |                NULL |               NULL  |
|  30 |    Picture_Test.png |                NULL |               NULL  |
-------------------------------------------------------------------------

谢谢您的建议。

3 个答案:

答案 0 :(得分:1)

您可以执行以下操作:

INSERT INTO Child
(
   Id
   ,De
   ,Fr
   ,En
)
OUTPUT Inserted.Id INTO #Temp
SELECT Id
       ,De
       ,Fr
       ,En
FROM @Values --If you are using a table type to insert into the Child table as a set based approach

;WITH CTE
AS
(
  SELECT ROW_NUMBER() OVER(ORDER BY Id) AS Rnk
  ,Id
  FROM #Temp

)
,CTE1 AS
(
  SELECT ROW_NUMBER() OVER(ORDER BY Id) AS Rnk
  ,*
  FROM Parent
)

UPDATE cte1
SET TranslationId = cte.Id
FROM CTE1 cte1
JOIN CTE cte ON cte.Rnk = cte1.Rnk

答案 1 :(得分:1)

演示,假设名称在第一张表中是唯一的

create table tab1 (
  id int identity
 ,TranslationId int null
 ,Name nvarchar(max) null
 );
 insert tab1 (Name)
     values 
     ('Image1.jpg')
    ,('Image7.jpg')
    ,('Picture_Test.png')
    ,(null)

create table tab2 (
  id int identity (100,1)
 ,De nvarchar(max) null
 ,Fr nvarchar(max) null
 ,En nvarchar(max) null
 );

-- Update them 

declare @map table(
  name nvarchar(max) 
 ,ref int
  );

insert tab2 (de)
output inserted.De, inserted.id
into @map(Name, ref)
select Name
from tab1 src
where Name is not null and not exists (select 1 from tab2 t2 where t2.De = src.Name);

update t1 set TranslationId = ref, Name = null
from tab1 t1
join @map m on t1.Name = m.Name;

select * from tab1;
select * from tab2;

答案 2 :(得分:0)

与此同时,我想出了怎么做。应用到数据库后,查询看起来像这样:

DECLARE @Temp TABLE (ImageId INT, Id INT)

MERGE INTO Translation USING 
  (
  SELECT Image.Name AS Name, Image.Id AS ImageId
  FROM Candidate
  INNER JOIN Candidacy ON Candidate.Id = Candidacy.CandidateId
  INNER JOIN Election ON Candidacy.ElectionId = Election.Id
  INNER JOIN SmartVoteCandidate ON Candidate.Id = SmartVoteCandidate.CandidateId
  INNER JOIN Image ON SmartVoteCandidate.SpiderImageId = Image.Id
  WHERE Election.Id = 1575) AS temp ON 1 = 0
WHEN NOT MATCHED THEN
  INSERT (De)
  VALUES (temp.Name)
  OUTPUT temp.ImageId, INSERTED.Id
  INTO @Temp (ImageId, Id);

UPDATE Image
SET Image.TranslationId = t.Id, Name = NULL
FROM @Temp t
WHERE Image.Id = t.ImageId

该解决方案的灵感源于