2013-01-17 68 views
1

我創建一個這樣的查詢:如何構建查詢動態

v_sql:=' SELECT abc FROM '||v_table||' 
     WHERE area IN ('''||v_area||''') 
      AND (
       ('''||p_supp_nbr||''' IS NULL) 
       OR 
       supplr_vn IN ('''||p_supp_nbr||''') 
       ) 

現在當p_supp_nbrNULL那麼它不採取。

我得到這樣的:

((''IS NULL) OR (supplr_vn =''))

在表格中的檢查空間

,但我想((NULL IS NULL) OR (supplr_vn =NULL))使病情bcomes無效

+1

不需要檢查'null是否爲null'。 – 2013-01-17 11:04:15

+0

我將需要檢查bcos它是一個可選參數。目前它的檢查空間在表 – Satheesh

+0

不,你不明白。沒有必要在任何'where'子句中包含null作爲null的一部分。如果'p_supp_nbr爲null',則不要包含'where'子句的那部分。 – 2013-01-17 11:10:01

回答

1

試試這個:

v_sql:=' SELECT abc FROM '||v_table||' 
WHERE area IN ('''||v_area||''') 
    AND (('''||p_supp_nbr||''' IS NULL) 
    OR supplr_vn IN ('''||NVL(p_supp_nbr, 'NULL')||''')) 
+0

在上面的查詢中,當p_supp_nbr爲NULL時,那麼它的檢查''是NULL.so空格不是NULL right – Satheesh

7

不要做在!您冒着SQL注入問題的風險。使用綁定變量:

v_sql:= 'SELECT abc FROM '||v_table|| 
     ' WHERE area = :v_area 
      AND (
       :p_supp_nbr IS NULL 
       OR 
       supplr_vn = :p_supp_nbr 
       ) 

當然,因爲你知道在生成的動態SQL是否值點爲空,你可以不是這樣做:

v_sql:= 'SELECT abc FROM '||v_table||' 
     WHERE area = :v_area'; 
IF p_supp_nbr IS NULL THEN 
    v_sql := v_sql || ' AND :p_supp_nbr IS NULL'; 
ELSE 
    v_sql := v_sql || ' AND supplr_vn = :p_supp_nbr'; 
END IF; 

無論哪種方式,那麼你就可以綁定值在這樣運行:

OPEN my_refcursor FOR v_sql USING v_area, p_supp_nbr; 
+0

我最喜歡第二個!但是,「if」陳述的第一部分不是多餘的?這不會工作:'如果p_supp_nbr不是NULL,則v_sql:= v_sql || 'AND supplr_vn =:p_supp_nbr'; END IF;' – glh

+2

@glh我應該在我的回答中解釋:是的,它在邏輯上是多餘的,但Native Dynamic SQL只適用於綁定變量的數量是固定的,所以我們需要在查詢中引用:p_supp_nbr是否使用它或不。 –

0

一般甲骨文例如:

DECLARE 
    v_sql1  VARCHAR2(200); 
    v_sql2  VARCHAR2(200); 
    v_tab_name VARCHAR2(200):= 'scott.emp'; 
    v_listCol  VARCHAR2(200):= 'job'; 
    v_list  VARCHAR2(200):= '''MANAGER'', ''CLERK'''; 
-- 
    v_colName  VARCHAR2(200):= 'comm'; 
    v_comm  NUMBER:= 1400; 
BEGIN 
    v_sql1:= 'SELECT * FROM '|| v_tab_name ||' WHERE '||v_listCol ||' IN (:v)'; 
    v_sql2:= 'SELECT * FROM '|| v_tab_name ||' WHERE ('||v_colName ||' = :v OR '||v_colName ||' IS NULL)'; 
-- 
    EXECUTE IMMEDIATE v_sql1 USING v_list; 
    dbms_output.put_line(v_sql1); 
-- 
    EXECUTE IMMEDIATE v_sql2 USING v_comm; 
    dbms_output.put_line(v_sql2); 
END; 
/