SQL更新1个表中的多行

时间:2018-02-07 10:10:19

标签: sql sql-server subquery

我有一个问题。我顺便使用MS SQL Server Management Studio。

我有一个包含大量翻译的词典表。我需要将完整的描述从languageID复制到另一种languageID。

以下示例。

LanguageID | Description
    2      | Some text
    2      | More text
    2      | Some more text
   10      | *needs to be replaced
   10      | *needs to be replaced
   10      | *needs to be replaced

结果必须如下:

LanguageID | Description
    2      | Some text
    2      | More text
    2      | Some more text
   10      | Some text
   10      | More text
   10      | Some more text

LanguageID 2和10的描述必须完全相同。

我当前的查询遇到错误:

update tblDictionary
set Description = (Select Description from tblDictionary where 
tblDictionary.LanguageID = 2)
where LanguageID = 10
  

Msg 512,Level 16,State 1,Line 1 Subquery返回的值超过1   值。当子查询遵循=,!=,<,< =,

时,不允许这样做      
    

,> =或当子查询用作表达式时。声明已经终止。

  

3 个答案:

答案 0 :(得分:4)

如果LanguageID 10的所有翻译必须与languageID 2完全相同,则更容易删除ID 10的所有翻译,然后再将其插入。
像这样的东西

delete from tblDictionary where LanguageID = 10;

insert into tblDictionary (LanguageID, Description)
select 10, d.Description
from   tblDictionary d
where  d.LanguageID = 2

此方法还有一个优势,即如果LanguageID = 10的记录较少,那么LanguageID = 2的记录将在同一过程中得到纠正。

如果tblDictionary中有更多列,则需要修改插入语句

答案 1 :(得分:1)

DECLARE @temp varchar(50)
DECLARE language_cursor CURSOR FOR  
SELECT Description FROM tblDictionary  
WHERE LanguageID = 2  
ORDER BY Description;  

OPEN language_cursor;  

-- Perform the first fetch.  
FETCH NEXT FROM language_cursor
into @temp;  

-- Check @@FETCH_STATUS to see if there are any more rows to fetch.  
WHILE @@FETCH_STATUS = 0  
BEGIN  
   update TOP (1) tblDictionary
   set Description = @temp
   where Description = ''
   and LanguageID = 10;  
   FETCH NEXT FROM language_cursor
   into @temp;
END  

CLOSE language_cursor;  
DEALLOCATE language_cursor;  

首先将所有languageID 10设置为空,然后将所有描述从languageID 2循环到一个接一个地更新为languageID 10,直到填写languageID10的所有空描述为止。

答案 2 :(得分:0)

现在,如果你真的想要更新,那么这样的东西应该可行,即使我认为表的结构需要改进。

WITH l2 AS 
(SELECT *,  
 ROW_NUMBER() OVER(PARTITION BY LanguageId ORDER BY Description ASC) AS No FROM tblDictionary WHERE LanguageId=2),
l10 AS 
(SELECT *,  
 ROW_NUMBER() OVER(PARTITION BY LanguageId ORDER BY Description ASC) AS No FROM tblDictionary WHERE LanguageId=10)

UPDATE l10 SET Description = l2.Description 
FROM l10
INNER JOIN l2 ON l10.No = l2.No