将SQL Server更新集从(使用连接)转换为Oracle

时间:2018-04-20 19:48:01

标签: oracle

SQL Server表定义:

CREATE TABLE #tmp_pricing
(
    contract_nbr               integer        not null,
    pricing_order              integer        not null,
    priced_from_contract_flag  char(1) COLLATE DATABASE_DEFAULT not null,
    release_nbr                integer        null,
    quantity                   decimal(25, 6) not null,
    price                      decimal(25, 6) null,
    price_future               decimal(25, 6) null,
    price_basis                decimal(25, 6) null,
    sum_qty                    decimal(25, 6) null,
    row_nbr                    integer        null,
    new_quantity               decimal(25, 6) null
)

Oracle全局临时表定义

CREATE GLOBAL TEMPORARY TABLE gtt_cpr_tmp_pricing
(
contract_nbr                    number                      not null,
pricing_order                   number                      not null,
priced_from_contract_flag       char(1)                     not null,
release_nbr                     number                      not null,
quantity                        number(25,6)                not null,
price                           number(18,6)                null,
price_future                    number(18,6)                null,
price_basis                     number(18,6)                null,
sum_qty                         number(25,6)                null,
row_nbr                         number                      null,
new_quantity                    number(25,6)                null
)
ON COMMIT DELETE ROWS
tablespace temp
/

SQL Server SQL语句:

UPDATE #tmp_pricing
  SET row_nbr = Q.row_nbr
 FROM #tmp_pricing
      JOIN (SELECT contract_nbr,
                   pricing_order,
                   priced_from_contract_flag,
                   release_nbr,
                   ROW_NUMBER() OVER (PARTITION BY contract_nbr
                                          ORDER BY contract_nbr,
                                      priced_from_contract_flag,
                                      CASE WHEN pricing_order < 0
                                               THEN 1
                                               ELSE 0
                                      END,
                                      pricing_order
                                     )     AS row_nbr
              FROM #tmp_pricing
           ) Q
        ON #tmp_pricing.contract_nbr = Q.contract_nbr
       AND #tmp_pricing.pricing_order = Q.pricing_order
       AND #tmp_pricing.priced_from_contract_flag = Q.priced_from_contract_flag
       AND COALESCE(#tmp_pricing.release_nbr, 0) = COALESCE(Q.release_nbr, 0)

Oracle语句(使用Merge)

MERGE INTO gtt_cpr_tmp_pricing t
USING (SELECT contract_nbr,
             pricing_order,
             priced_from_contract_flag,
             release_nbr,
             ROW_NUMBER() OVER (PARTITION BY contract_nbr
                                    ORDER BY contract_nbr,
                                priced_from_contract_flag,
                                CASE WHEN pricing_order < 0
                                        THEN 1
                                        ELSE 0
                                END,
                                pricing_order
                               )           AS row_nbr
        FROM gtt_cpr_tmp_pricing 
     )
    Q
  ON (t.contract_nbr = Q.contract_nbr AND
      t.pricing_order = Q.pricing_order AND
      t.priced_from_contract_flag = Q.priced_from_contract_flag AND
      COALESCE(t.release_nbr, 0) = COALESCE(Q.release_nbr, 0)
     )
WHEN MATCHED
    THEN UPDATE SET row_nbr = Q.row_nbr;

这是我得到的错误:

ORA-30926: unable to get a stable set of rows in the source tables

我想将语句转换为update .. set ..where exists 结构,但我做错了;这是我的(第一次)尝试:

UPDATE gtt_cpr_tmp_pricing 
  SET row_nbr = (SELECT contract_nbr,
                        pricing_order,
                        priced_from_contract_flag,
                        release_nbr,
                        ROW_NUMBER() OVER (PARTITION BY contract_nbr
                                               ORDER BY contract_nbr,
                                           priced_from_contract_flag,
                                           CASE WHEN pricing_order < 0
                                                    THEN 1
                                                    ELSE 0
                                           END,
                                           pricing_order
                                          ) AS row_nbr
                   FROM gtt_cpr_tmp_pricing ctp 
                  WHERE gtt_cpr_tmp_pricing.contract_nbr = contract_nbr
                    AND gtt_cpr_tmp_pricing.pricing_order = pricing_order
                    AND gtt_cpr_tmp_pricing.priced_from_contract_flag = priced_from_contract_flag 
                    AND COALESCE(gtt_cpr_tmp_pricing.release_nbr, 0) = COALESCE(release_nbr, 0)
               ) 
  WHERE EXISTS (SELECT 1
                  FROM gtt_cpr_tmp_pricing
                  WHERE gtt_cpr_tmp_pricing.contract_nbr = contract_nbr
                    AND gtt_cpr_tmp_pricing.pricing_order = pricing_order
                    AND gtt_cpr_tmp_pricing.priced_from_contract_flag = priced_from_contract_flag 
                    AND COALESCE(gtt_cpr_tmp_pricing.release_nbr, 0) = COALESCE(release_nbr, 0)
               );

任何帮助将不胜感激。 默里

1 个答案:

答案 0 :(得分:0)

在Oracle中使用内联视图时,没有别名的列会引用内联视图中的表。您需要使用表别名来引用内联视图中update子句中的表。请注意price_outer别名及其使用位置。

UPDATE gtt_cpr_tmp_pricing price_outer
  SET row_nbr = (SELECT contract_nbr,
                    pricing_order,
                    priced_from_contract_flag,
                    release_nbr,
                    ROW_NUMBER() OVER (PARTITION BY contract_nbr
                                           ORDER BY contract_nbr,
                                       priced_from_contract_flag,
                                       CASE WHEN pricing_order < 0
                                                THEN 1
                                                ELSE 0
                                       END,
                                       pricing_order
                                      ) AS row_nbr
               FROM gtt_cpr_tmp_pricing ctp 
              WHERE price_outer.contract_nbr = contract_nbr
                AND price_outer.pricing_order = pricing_order
                AND price_outer.priced_from_contract_flag = priced_from_contract_flag 
                AND COALESCE(price_outer.release_nbr, 0) = COALESCE(release_nbr, 0)
           ) 
WHERE EXISTS (SELECT 1
              FROM gtt_cpr_tmp_pricing
              WHERE price_outer.contract_nbr = contract_nbr
                AND price_outer.pricing_order = pricing_order
                AND price_outer.priced_from_contract_flag = priced_from_contract_flag 
                AND COALESCE(price_outer.release_nbr, 0) = COALESCE(release_nbr, 0)
           );