我有三个语句可以工作(见下文),但是我想将这三个语句组合成一个动态语句,其中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版
答案 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;