我一直在尝试寻找在查询中动态更改表名的方法,但到目前为止还没有找到可行的方法。该查询具有重复的代码(每个case语句中包含约150行代码),因此我试图找到一种更好的方法。
我当前的程序如下所示:
CREATE OR REPLACE PROCEDURE PROC_MY_TEST (P_INPUTVAR NUMBER,
P_OUT OUT SYS_REFCURSOR)
AS
BEGIN
CASE P_INPUTVAR
WHEN 1
THEN
OPEN P_OUT FOR
WITH CTE
AS (SELECT COL_M, COL_N
FROM TBL_TEST
WHERE COL_G = 'mycondition1')
SELECT COL_M, COL_N
FROM TABLE_A a LEFT JOIN CTE m ON a.col1 = b.col1
WHERE a.col2 = 'xyz' AND b.col4 = 'abc';
WHEN 2
THEN
OPEN P_OUT FOR
WITH CTE
AS (SELECT COL_M, COL_N
FROM TBL_TEST
WHERE COL_G = 'mycondition1')
SELECT COL_M, COL_N
FROM TABLE_B a LEFT JOIN CTE m ON a.col1 = b.col1
WHERE a.col2 = 'xyz' AND b.col4 = 'abc';
WHEN 3
THEN
OPEN P_OUT FOR
WITH CTE
AS (SELECT COL_M, COL_N
FROM TBL_TEST
WHERE COL_G = 'mycondition1')
SELECT COL_M, COL_N
FROM TABLE_C a LEFT JOIN CTE m ON a.col1 = b.col1
WHERE a.col2 = 'xyz' AND b.col4 = 'abc';
WHEN 4
THEN
OPEN P_OUT FOR
WITH CTE
AS (SELECT COL_M, COL_N
FROM TBL_TEST
WHERE COL_G = 'mycondition1')
SELECT COL_M, COL_N
FROM TABLE_D a LEFT JOIN CTE m ON a.col1 = b.col1
WHERE a.col2 = 'xyz' AND b.col4 = 'abc';
END CASE;
END;
一些SQL解决方案建议采用以下格式,但会给出错误消息“表L_Temp不存在”:
CREATE OR REPLACE PROCEDURE PROC_MY_TEST (P_INPUTVAR NUMBER,
P_OUT OUT SYS_REFCURSOR)
AS
L_Temp VARCHAR2 (200);
BEGIN
L_Temp :=
CASE P_INPUTVAR
WHEN 1 THEN 'TABLE_A'
WHEN 2 THEN 'TABLE_B'
WHEN 3 THEN 'TABLE_C'
WHEN 4 THEN 'TABLE_D'
ELSE NULL
END;
OPEN P_OUT FOR
WITH CTE
AS (SELECT COL_M, COL_N
FROM TBL_TEST
WHERE COL_G = 'mycondition1')
SELECT COL_M, COL_N
FROM L_Temp a LEFT JOIN CTE m ON a.col1 = b.col1
WHERE a.col2 = 'xyz' AND b.col4 = 'abc';
END;
当所有目标表都包含相似的列名时,是否可以动态更改表名?
*已编辑* 添加了用于其他更新语句示例的代码:
CREATE OR REPLACE PROCEDURE PROC_MY_TEST (P_INPUTVAR NUMBER,
P_OUT OUT SYS_REFCURSOR)
AS
L_Temp VARCHAR2 (200);
L_Total NUMBER;
BEGIN
L_Temp :=
CASE P_INPUTVAR
WHEN 1 THEN 'TABLE_A'
WHEN 2 THEN 'TABLE_B'
WHEN 3 THEN 'TABLE_C'
WHEN 4 THEN 'TABLE_D'
ELSE NULL
END;
OPEN P_OUT FOR
WITH CTE
AS (SELECT COL_M, COL_N
FROM TBL_TEST
WHERE COL_G = 'mycondition1')
SELECT COL_M, COL_N
FROM L_Temp a LEFT JOIN CTE m ON a.col1 = b.col1
WHERE a.col2 = 'xyz' AND b.col4 = 'abc';
SELECT TOTAL INTO L_Total FROM L_Temp;
UPDATE TBL_TEST2
SET a.TOTAL = l_Total
WHERE a.col2 = 'xyz';
END;
答案 0 :(得分:1)
您需要使用EXECUTE IMMEDIATE Statement
EXECUTE IMMEDIATE语句执行动态SQL语句或匿名PL / SQL块。您可以使用它来发出不能直接在PL / SQL中表示的SQL语句,或者在不知道所有表名的地方建立语句
对于example :
execute immediate ' update ' || myTable || ' ... ';
答案 1 :(得分:1)
您需要将语句创建为字符串,然后将其作为游标打开:
CREATE OR REPLACE PROCEDURE PROC_MY_TEST (P_INPUT_VAR IN NUMBER,
P_OUT OUT SYS_REFCURSOR)
AS
strTable VARCHAR2(30);
strStmt VARCHAR2(32767);
BEGIN
strTable := CASE P_INPUT_VAR
WHEN 1 THEN 'TABLE_A'
WHEN 2 THEN 'TABLE_B'
WHEN 3 THEN 'TABLE_C'
WHEN 4 THEN 'TABLE_D'
END;
strStmt := 'WITH CTE AS (SELECT COL_M, COL_1, COL_4 ' ||
' FROM TBL_TEST ' ||
' WHERE COL_G = ''mycondition1'') ' ||
'SELECT COL_M, COL_N ' ||
' FROM ' || strTable || ' t ' ||
' LEFT JOIN CTE m ' ||
' ON t.COL1 = m.COL_1 ' ||
' WHERE a.COL2 = ''xyz'' AND ' ||
' m.COL_4 = ''abc''';
OPEN P_OUT FOR strStmt;
END PROC_MY_TEST;
请注意,由于您使用的表快捷方式和列名称似乎与其余代码不匹配,因此我对SQL进行了少许更改。