嗨,
我需要為 from 子句創建一個帶有條件的選擇:如果變數等于POSselect 必須用 table 完成,tb_a如果變數等于PREselected 將用 table 完成tb_b。
我嘗試了以下兩種方法,但都沒有奏效。
SELECT * FROM tb_a WHERE '&prod' = 'POS'
UNION ALL
SELECT * FROM tb_b WHERE '&prod' = 'PRE';
SELECT *
FROM
(CASE '&prod'
WHEN 'prod' = 'POS' THEN tb_a
WHEN 'prod' = 'PRE' THEN tb_b
END);
你能幫我嗎?
uj5u.com熱心網友回復:
當然有效。
SQL> create table tb_a as select * from dept where deptno in (10, 20); --> for POS
Table created.
SQL> create table tb_b as select * from dept where deptno in (30, 40); --> for PRE
Table created.
SQL> select * from tb_a where '&&prod' = 'POS'
2 union all
3 select * from tb_b where '&&prod' = 'PRE';
Enter value for prod: POS
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
SQL> undefine prod
SQL> /
Enter value for prod: PRE
DEPTNO DNAME LOC
---------- -------------- -------------
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL>
uj5u.com熱心網友回復:
您可以創建一個函式(或程序),它SYS_REFCURSOR在接受您的一個引數(POS,PRE)后回傳型別引數的記錄集,無論您的表(tb_a或tb_b)具有什么結構,例如
CREATE OR REPLACE FUNCTION Get_tab_ab( i_prod VARCHAR2 ) RETURN SYS_REFCURSOR IS
v_recordset SYS_REFCURSOR;
v_sql VARCHAR2(32767);
BEGIN
v_sql := 'SELECT * FROM '||CASE
WHEN i_prod = 'POS' THEN
'tb_a'
WHEN i_prod = 'PRE' THEN
'tb_b'
END;
OPEN v_recordset FOR v_sql;
RETURN v_recordset;
END;
/
然后像這樣從 SQL Developer 的控制臺呼叫
SQL> DECLARE
res SYS_REFCURSOR;
BEGIN
:res := Get_tab_ab('POS');
END;
/
SQL> PRINT res;
或者您可以使用公共ROWTYPE變數,因為表(tb_a或tb_b)的結構是相同的,因為您將它們與UNION ALL運算子和FETCH..INTO子句組合在一起。這次直接列印出需要的列,不需要創建函式或程序等存盤物件,只需切換變數的值v_prod
DECLARE
v_recordset SYS_REFCURSOR;
v_rec tb_a%ROWTYPE;
v_sql VARCHAR2(32767);
v_prod VARCHAR2(3) := 'POS';
BEGIN
v_sql := 'SELECT * FROM '||CASE
WHEN v_prod = 'POS' THEN
'tb_a'
WHEN v_prod = 'PRE' THEN
'tb_b'
END;
OPEN v_recordset FOR v_sql;
LOOP
FETCH v_recordset INTO v_rec;
EXIT WHEN v_recordset%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_rec.col1||' '||v_rec.col2||' '||v_rec.col3);
END LOOP;
CLOSE v_recordset;
END;
/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/402009.html
標籤:sql 甲骨文 oracle-sqldeveloper
