2013-10-15 20 views
0

我有3個輸入參數,基於每個輸入參數的值,我必須動態地在過程中準備SQL。我正在做下面的方式,但它是失敗的,如果參數值爲空,那麼我必須從where子句中排除。在oracle存儲過程中動態地準備sql

IN參數:

EMPID在VARCHAR2 || empname IN varchar2 || empsal IN VARCHAR2

SELECT 
     EMP_NAME 
INTO 
     V_EMP_NAME 
FROM 
     EMPLOYEE 
WHERE 
     (EMP_ID = EMPID 
      OR (EMP_ID IS NULL 
      AND EMPID IS NULL)) 
     AND (EMP_NAME = EMPNAME 
      OR (EMP_NAME IS NULL 
      AND EMPNAME IS NULL)) 
     AND (EMP_SAL = EMPSAL 
      OR (EMP_SAL IS NULL 
      AND EMPSAL IS NULL)); 

後更新我修改查詢類似下面,它被編譯,但給人運行時錯誤說ORA-00933:SQL命令不能正確地結束上只執行立即之前

V_SQL :='SELECT EMP_NAME INTO V_empname FROM employee WHERE '; 
    BEGIN 
    IF(EMPID IS NOT NULL) THEN 
    V_SQL := V_SQL || ' emp_id='||EMPID; 
    END IF; 
    IF(EMPNAME IS NOT NULL) THEN 
     V_SQL := V_SQL || ' AND emp_name='||EMPNAME; 
    END IF; 
    IF(V_empsalIS NOT NULL) THEN 
     V_SQL := V_SQL || ' AND emp_sal='||empsal; 
V_SQL := V_SQL ||' AND ACTIVE =''Y''' ; 
    END IF; 
     EXECUTE IMMEDIATE V_SQL; 
    EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
     V_check:= '' ; 
    END; 

回答

1

在這裏,你有另一種選擇:

V_SQL_WHERE := null; 

    V_SQL :='SELECT EMP_NAME INTO V_empname FROM employee'; 
    BEGIN 

    IF(EMPID IS NOT NULL) THEN 
     V_SQL_WHERE := V_SQL_WHERE || ' emp_id='||EMPID; 
    END IF; 

    IF(EMPNAME IS NOT NULL) THEN 

     IF (V_SQL_WHERE is not null) THEN 
     V_SQL_WHERE := V_SQL_WHERE || ' AND '; 
     END IF; 

     V_SQL_WHERE := V_SQL_WHERE || ' emp_name='||EMPNAME; 
    END IF; 

    IF(V_empsalIS NOT NULL) THEN 

     IF (V_SQL_WHERE is not null) THEN 
     V_SQL_WHERE := V_SQL_WHERE || ' AND '; 
     END IF; 
     V_SQL_WHERE := V_SQL_WHERE || ' emp_sal=' || empsal; 
     V_SQL_WHERE := V_SQL_WHERE || ' AND ACTIVE =''Y''' ; 

    END IF; 

    IF (V_SQL_WHERE is not null) then 
     V_SQL := V_SQL || ' WHERE ' || V_SQL_WHERE; 
    end if; 

     EXECUTE IMMEDIATE V_SQL; 
    EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
     V_check:= '' ; 
    END; 
+0

只是一個信息,這是一個小問題。你需要在每個whaere子句輸入參數之間添加單引號 – rajputhch

0

您可以從頭開始創建一個,包括if和elses,也可以使用名爲plsql-utils的包SQL_BUILDER_PKG。它爲你完成整個工作。

SQL公用事業

http://code.google.com/p/plsql-utils/

如看:

declare 
    l_my_query sql_builder_pkg.t_query; 
    l_sql varchar2(32000); 
begin 

    sql_builder_pkg.add_select (l_my_query, 'ename'); 
    sql_builder_pkg.add_select (l_my_query, 'sal'); 
    sql_builder_pkg.add_select (l_my_query, 'deptno'); 
    sql_builder_pkg.add_from (l_my_query, 'emp'); 
    sql_builder_pkg.add_where (l_my_query, 'ename = :p_ename'); 
    sql_builder_pkg.add_where (l_my_query, 'sal > :p_sal'); 
    l_sql := sql_builder_pkg.get_sql (l_my_query); 
    dbms_output.put_line (l_sql); 
end; 

我用它在一個項目中,這是一個很好的工具。

+0

如何用簡單的做,如果語句 – rajputhch

+0

我猜realspirituals已經回答了這個一個在下面。這並不完美,但你可以得到理想的結果。如果您要創建更多動態查詢,我仍然建議您使用上面的包。 – VancleiP

+0

我想這樣做:V_SQL:= V_SQL || 'EMP_ID =' || || EMPID;但它給錯誤 – rajputhch

0

事情是這樣的:(沒有測試,但只是一個想法)

BEGIN 
    IF EMPID IS NOT NULL 
    THEN 
     CLAUSE1 := 'EMP_ID = EMPID'; 
    ELSE 
     CLAUSE1 := '1=1'; 
    END IF; 

    IF EMPNAME IS NOT NULL 
    THEN 
     CLAUSE2 := 'EMP_NAME = EMPNAME'; 
    ELSE 
     CLAUSE2 := '1=1'; 
    END IF; 

    IF EMPSAL IS NOT NULL 
    THEN 
     CLAUSE3 := 'EMP_SAL = EMPSAL'; 
    ELSE 
     CLAUSE3 := '1=1'; 
    END IF; 

    IF ( EMPSAL IS NULL 
     AND EMPNAME IS NULL 
     AND EMPID IS NOT NULL) 
    THEN 
     CLAUSE1 := '1=0'; 
     CLAUSE2 := '1=0'; 

     CLAUSE3 := '1=0'; 
    END IF; 

    QUERY_STR := 
      ' SELECT EMP_NAME INTO V_EMP_NAME FROM EMPLOYEE WHERE' 
     || CLAUSE1 
     || ' AND ' 
     || CLAUSE2 
     || ' AND ' 
     || CLAUSE3; 
END; 
+0

你缺少報價。 EMP_SAL ='<>'。如何在單引號中寫入值 – rajputhch

+0

您想要硬編碼!那麼試試'empsalvalues varchar2(100):='1020';'並在select * from table where where column =('|| empsalvalues ||')'' – SriniV

+0

''中使用相同的方式。和插入,以及所需的輸出,你嘗試過的代碼段),我們可以提供幫助。 – SriniV