【问题标题】:Update a value from one table to another using a Proc使用 Proc 将值从一个表更新到另一个表
【发布时间】:2013-08-22 14:21:33
【问题描述】:

我有两个结构相同的表。一张是临时表,一张是主表。表名分别是 PurchaseOrders_TEMP 和 PurchaseOrders。每天我都用新数据刷新临时表并运行一个 PROC 来用更改和/或添加来更新主表。我意识到如果 PO 和/或 PO 上的项目被完全删除,我会遇到问题。我的 proc 没有更新不在 Temp 表中的行。这是 PurchaseOrders 的表定义。我需要一个新的 PROC 或对此 PROC 的更新,当 TEMP 表中不存在时,它将 PBSTAT 更改为 PBPO/PBITEM 的“X”。

[dbo].[PurchaseOrders](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [PBPO] [int] NOT NULL,
    [PBSEQ] [int] NOT NULL,
    [PBITEM] [varchar](28) NOT NULL,
    [PBDEL] [varchar](1) NULL,
    [PBVEND] [varchar](9) NULL,
    [PBTYPE] [varchar](1) NULL,
    [PBLOC] [varchar](4) NULL,
    [PBDSC1] [varchar](51) NULL,
    [PBDSC2] [varchar](45) NULL,
    [PBPDTE] [datetime] NULL,
    [PBDUE] [datetime] NULL,
    [XDPRVDT] [datetime] NULL,
    [XDCURDT] [datetime] NULL,
    [PBRDTE] [datetime] NULL,
    [PBOQTY] [int] NULL,
    [PBTQTY] [int] NULL,
    [PBRQTY] [int] NULL,
    [PBDQTY] [int] NULL,
    [PBLQTY] [int] NULL,
    [PBBQTY] [int] NULL,
    [PBCOST] [float] NULL,
    [EXTCOST] [float] NULL,
    [PBCCTD] [datetime] NULL,
    [PBCCTT] [int] NULL,
    [PBCCTU] [varchar](15) NULL,
    [PBLCGD] [datetime] NULL,
    [PBLCGT] [int] NULL,
    [PBUSER] [varchar](12) NULL,
    [PASTAT] [varchar](1) NULL,
    [PABUYR] [varchar](3) NULL,
    [PAPAD3] [varchar](45) NULL,
    [PAPPHN] [varchar](30) NULL,
    [PACONF] [varchar](39) NULL,
    [Comment] [varchar](max) NULL

这是我为更新数据而运行的当前 Proc。

ALTER PROCEDURE [dbo].[UpdateExistingPurchaseOrders] 
AS
BEGIN
SET NOCOUNT ON;

UPDATE 
    p
SET
    p.PBDEL = pt.PBDEL,
    p.PBVEND = pt.PBVEND,
    p.PBTYPE = pt.PBTYPE,
    p.PBLOC = pt.PBLOC,
    p.PBDSC1 = pt.PBDSC1,
    p.PBDSC2 = pt.PBDSC2,
    p.PBPDTE = pt.PBPDTE,
    p.PBDUE = pt.PBDUE,
    p.PBRDTE = pt.PBRDTE,
    p.PBOQTY = pt.PBOQTY,
    p.PBTQTY = pt.PBTQTY,
    p.PBRQTY = pt.PBRQTY,
    p.PBDQTY = pt.PBDQTY,
    p.PBLQTY = pt.PBLQTY,
    p.PBBQTY = pt.PBBQTY,
    p.PBCOST = pt.PBCOST,
    p.EXTCOST = pt.EXTCOST,
    p.PBCCTD = pt.PBCCTD,
    p.PBCCTT = pt.PBCCTT,
    p.PBCCTU = pt.PBCCTU,
    p.PBLCGD = pt.PBLCGD,
    p.PBLCGT = pt.PBLCGT,
    p.PBUSER = pt.PBUSER,
    p.PASTAT = pt.PASTAT,
    p.PABUYR = pt.PABUYR,
    p.PAPAD3 = pt.PAPAD3,
    p.PAPPHN = pt.PAPPHN,
    p.PACONF = pt.PACONF
FROM
    dbo.PurchaseOrders_TEMP pt
    LEFT OUTER JOIN dbo.PurchaseOrders p
        ON p.PBPO = pt.PBPO
        AND p.PBSEQ = pt.PBSEQ
WHERE
    p.PBPO IS NOT NULL
    AND p.PBSEQ IS NOT NULL

END

【问题讨论】:

    标签: tsql sql-server-2012-express


    【解决方案1】:

    您可以使用MERGE 语句从源查询中的数据修改目标表中的数据。文档中的前两个示例显示了如何根据是否找到源行来插入/更新或更新/删除。

    在你的情况下,你必须写这样的东西:

    MERGE dbo.PurchaseOrders AS target
    USING (SELECT ...  FROM PurchaseOrders_TEMP) AS source (...)
    ON (ON target.PBPO = source.PBPO
        AND target.PBSEQ = source.PBSEQ)
    WHEN NOT MATCHED BY SOURCE
        THEN DELETE
    WHEN NOT MATCHED BY TARGET
        THEN INSERT (....)
             VALUES (....)
    WHEN MATCHED 
        THEN UPDATE 
        SET ...
    

    【讨论】:

    • 我不想删除 PurchaseOrders 表中的任何历史记录。当新数据中不存在 PBPO 和/或 PBSEQ/PBITEM 时,我只想将字段 PASTAT 的值更改为“X”。
    • 然后写一个UPDATE语句而不是DELETE
    • 其他人有办法做到这一点吗?
    • 你试过了吗?你有问题吗?你还在寻找什么其他方式?什么不起作用?
    【解决方案2】:

    这是我想出的答案...

    UPDATE 
       p
    SET
       p.PASTAT = 'X'
    FROM
       dbo.PurchaseOrders_TEMP pt        
       LEFT JOIN dbo.PurchaseOrders p ON 
           p.PBPO = pt.PBPO
           AND p.PBSEQ = pt.PBSEQ
    WHERE
       pt.PBPO IS NULL
       AND pt.PBSEQ IS NULL
       AND p.PASTAT <> 'X'
    END
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-13
      • 2023-03-22
      • 1970-01-01
      • 2011-11-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-01
      • 2012-08-02
      相关资源
      最近更新 更多