Oracle SQL中的动态FROM子句

时间:2015-02-11 16:01:11

标签: sql oracle dynamic

我有三个语句可以工作(见下文),但是我想将这三个语句组合成一个动态语句,其中tablea,tableb或tablec在FROM子句中使用,具体取决于col4_value的值。我无法解决如何做到这一点。

UPDATE table1 a 
SET a.price_fx = 
  (SELECT b.price 
   FROM tablea b, table2 c
   WHERE a.client = b.client 
   AND a.dim_value = b.project 
   AND a.price_fx != b.price
   AND b.client = c.client
   AND b.project = c.col1_value
   AND c.col4_value = '11'
   AND c.col5_value = 'KB01');

UPDATE table1 a 
SET a.price_fx = 
  (SELECT b.price 
   FROM tableb b, table2 c
   WHERE a.client = b.client 
     AND a.dim_value = b.project 
     AND a.price_fx != b.price
     AND b.client = c.client
     AND b.project = c.col1_value
     AND c.col4_value = '3'
     AND c.col5_value = 'KB01');

UPDATE table1 a 
SET a.price_fx = 
  (SELECT b.price 
   FROM tablec b, table2 c
   WHERE a.client = b.client 
     AND a.dim_value = b.project 
     AND a.price_fx != b.price
     AND b.client = c.client
     AND b.project = c.col1_value
     AND c.col4_value = '34'
     AND c.col5_value = 'KB01');

非常感谢任何帮助。

我正在使用Oracle Database 11g企业版11.2.0.4.0版

1 个答案:

答案 0 :(得分:1)

通常,我会尝试使用外连接来解决这个问题。以下内容可能会起作用(如果没有样本数据,很难验证)。

UPDATE table1 t1
SET    t1.price_fx =
          (SELECT CASE t2.col4_value
                     WHEN '11' THEN a.price
                     WHEN '3' THEN b.price
                     WHEN '34' THEN c.price
                  END
           FROM   table2 t2
                  LEFT JOIN tablea a
                     ON     t1.client = a.client
                        AND t1.dim_value = a.project
                        AND t1.price_fx != a.price
                        AND a.client = t2.client
                        AND a.project = t2.col1_value
                  LEFT JOIN tableb b
                     ON     t1.client = b.client
                        AND t1.dim_value = b.project
                        AND t1.price_fx != b.price
                        AND b.client = t2.client
                        AND b.project = t2.col1_value
                  LEFT JOIN tablec c
                     ON     t1.client = c.client
                        AND t1.dim_value = c.project
                        AND t1.price_fx != c.price
                        AND c.client = t2.client
                        AND c.project = t2.col1_value
           WHERE  t2.col5_value = 'KB01');

您可以使用execute immediate在PL / SQL中动态执行此操作,但如果可能,我会尽量避免使用该解决方案。动态SQL往往更脆弱,难以维护。

DECLARE
   v_sql VARCHAR2 (2000) := 'UPDATE table1 a 
SET a.price_fx = 
  (SELECT b.price 
   FROM [table_name] b, table2 c
   WHERE a.client = b.client 
   AND a.dim_value = b.project 
   AND a.price_fx != b.price
   AND b.client = c.client
   AND b.project = c.col1_value
   AND c.col4_value = :1
   AND c.col5_value = :2);';
   v_col4_value table2.col4_value%TYPE := '11';
   v_col5_value table2.col5_value%TYPE := 'KB01';
   v_table_name VARCHAR2 (30);
BEGIN
   v_table_name :=
      DBMS_ASSERT.sql_object_name (
         CASE v_col4_value
            WHEN '11' THEN 'tablea'
            WHEN '3' THEN 'tableb'
            WHEN '4' THEN 'tablec'
         END);
   v_sql := REPLACE ('[table_name]', v_table_name);

   EXECUTE IMMEDIATE v_sql USING v_col4_value, v_col5_value;
END;