使用TVP时更新的SQL Server问题

时间:2012-03-02 06:40:34

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

我有以下sql

DECLARE @tmpSelectedData   TABLE  -- table variable
        (SlNo  INT IDENTITY(1,1) PRIMARY KEY
         ,dataID INT NULL
         ,ValID INT NULL
         ,DdrID INT NULL
         ,InrID INT NULL
         ,IprID INT NULL)

-- inserting into table variable
INSERT INTO @tmpSelectedData(dataID)  
    SELECT 
        SQ.dataID    
    FROM 
        @SelectedQuestions SQ 

    -- Update the table variable with some values

    tblData
       dataID,ValID,DdrID,InrID,IprID 
        1-    2-  3  - 4-   5
        2-    7-  4  - 5-       8
        3-    8-  2  - 4-       3
        4-    0-  1  - 2-       5

    @SelectedData  
        dataID
         2
         3
         4

    @tmpSelectedData    
        dataID,ValID,DdrID,InrID,IprID 
            2-    
            3-    
        4-    

UPDATE @tmpSelectedData   
SET IprID = D.dataID,
    DdrID = D.DdrID,
    InrID = D.InrID 
FROM tblData D 
INNER JOIN @SelectedData SD ON SD.dataID = D.dataID  

使用此查询,@tmpSelectedData的所有行都将使用与tblData的第一行对应的值进行更新

@tmpSelectedData中的预期结果:

   dataID,ValID,DdrID,InrID,IprID 
        2-    7-  4  - 5-       8
        3-    8-  2  - 4-       3
        4-    0-  1  - 2-       5

@tmpSelectedData中的实际结果:

   dataID,ValID,DdrID,InrID,IprID 
        2-    7-  4  - 5-       8
        3-    7-  4  - 5-       8
        4-    7-  4  - 5-       8

它只会使用第一个值

进行更新
UPDATE @tmpSelectedData   
SET dataID = D.dataID,
    DdrID = D.DdrID,
    InrID = D.InrID 
FROM tblData D 
INNER JOIN @tmpSelectedData SD ON SD.IprID = D.IprID  

当我从@tmpSelectedData(第二个查询)将其更改为@SelectedData时,它将正常工作并更新为预​​期结果。

两个查询之间有什么区别?

2 个答案:

答案 0 :(得分:3)

这是UPDATE ... FROM语法的问题之一 - 如果它实际上尝试多次更新相同的行,最终结果将是 one < / em>这些更新,但哪一个是不确定的 - 并且在发生这种情况时不会给出错误或警告消息

您在第一个UPDATE查询中的内容是FROM子句,它根本不引用要更新的表 - 它实际上是一个不相关的查询,因此整个结果集由FROM子句适用于目标表中的所有行。一行(在这种情况下,“第一”,虽然定义不明确)是“赢得”更新的行(同样应该注意的是,不能保证同一行将“赢”每一行正在更新的表中的行。)

在第二个查询中,因为FROM clause中引用了要更新的表

  

指定使用表,视图或派生表源来提供更新操作的条件。有关详细信息,请参阅FROM (Transact-SQL)

     

如果要更新的对象与FROM子句中的对象相同,并且FROM子句中只有一个对象的引用,则可以指定或不指定对象别名。

答案 1 :(得分:0)

UPDATE @tmpSelectedData   
   SET dataID = D.dataID,
       DdrID = D.DdrID,
       InrID = D.InrID
  FROM tblData D 
 INNER JOIN @tmpSelectedData SD ON SD.IprID = D.IprID 
 WHERE SD.IprID In (SELECT IprID FROM @SelectedData)

尝试这种方式..在你的查询中,@ tmpSelectedData和@SelectedData之间的关系缺失。