【问题标题】:Update from Temp Table从临时表更新
【发布时间】:2013-02-27 17:50:40
【问题描述】:

查询:

SELECT ID, T.c.value('@Address', 'nvarchar(20)' ) as Address
INTO #TMP
FROM TABLE1
    CROSS APPLY XMLData.nodes('/Document') AS T(c)

UPDATE TABLE1
SET HomeAddress = (SELECT TOP 1 t.Address
                   FROM #TMP t
                   WHERE t.ID = ID)

主要是,我需要将数据 OUT 从 XML 字段复制到同一个表中的普通字段。

问题:

  1. 为什么所有记录都获得 Table1 上的 HomeAddress?
  2. Cursor 真的是更新 Table1 上的值的唯一方法吗?

【问题讨论】:

标签: sql sql-server tsql sql-update temp-tables


【解决方案1】:

在更新时,我需要按以下方式完全限定表格:                  

UPDATE TABLE1 SET TABLE1.HomeAddress = (SELECT TOP 1 t.Address  
               FROM #TMP t  
               WHERE t.ID = TABLE1.ID)  

【讨论】:

    【解决方案2】:
    UPDATE T2
    SET HomeAddress = t1.address
    FROM TABLE2 t2
    join TABLE1 t1 on T1.ID = t2.HomeAddressID
    and t2.HomeAddress <> t1.address
    

    使用连接。无需临时表或相关子查询。

    如果表 1 处于一对多关系中,则这些是处理该问题的一些可能性。如果您有一个值指示一个且只有一个记录(我们的系统中有一个字段选择最重要的地址,它通过触发器维护以保证唯一性),试试这个:

    UPDATE T2
    SET HomeAddress = t1.address
    FROM TABLE2 t2
    join TABLE1 t1 on t1.ID = t2.HomeAddressID
    WHERE t1.somefield = 'somevalue'
    and t2.HomeAddress <> t1.address
    

    如果您需要基于其他字段(例如最近日期)的唯一记录,请尝试以下变体:

    UPDATE T2
    SET HomeAddress = t1.address
    FROM TABLE2 t2
    join TABLE1 t1 on t1.ID = t2.HomeAddressID
    join (select id, max(somedatefield) from  table1 group by id) t3 on t3.id = t1.id
    Where  t2.HomeAddress <> t1.address
    

    【讨论】:

    • 如果 t1.id 与 t2.homeaddressid 具有一对多关系,您可能需要更具体地说明要使用的记录。
    • 实际值在 XML 字段中。我刚刚更新了原始问题。
    • @DanBracuk,很好。当然,当前版本没有指定在这种情况下使用哪个。不过,让我拼凑一些例子。
    【解决方案3】:
    SELECT P.TipoComprob,P.NoComprob,C.Importe as ImpIVA1,ROUND(100/P.ImpGravado*C.Importe,1)
     as PorcIVA1 
           INTO #Temporal
           FROM ComprobProv AS P
           LEFT JOIN PasesCompras AS C ON C.TipoComprob=P.TipoAsiento AND 
    C.NoComprob=P.NoComprob
    WHERE P.PorcIVA1 =0 and P.CatIVA = 'Ri' AND P.ImpGravado>0 AND C.CodCuenta=110303010 AND ROUND(100/P.ImpGravado*C.Importe,1) IN (21.00,10.50,27.00);
    go
    
    select * from #Temporal;
    go
    
    UPDATE 
       t1 
    SET 
       t1.ImpIVA1 =  t2.ImpIVA1, t1.PorcIVA1 = t2.PorcIVA1
    FROM
       dbo.ComprobProv t1
       INNER JOIN #Temporal t2
       ON t1.TipoComprob = t2.TipoComprob AND t1.NoComprob = t2.NoComprob;
    go
    

    -- 请注意,“GO”对于保留 SQL Server 2017 中的上下文很重要,否则您会发现 “未知字段名称”错误。

    【讨论】:

      猜你喜欢
      • 2017-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多