2011-02-15 61 views
3

我正在使用存儲過程將數據插入到使用遊標的臨時表中。 此過程在變量內部存儲動態查詢以裝入插入/更新命令。pl/sql - 在存儲過程中使用動態查詢

這裏是代碼(不是完整的查詢,我剪了一些地區,使其更易於閱讀):

FOR VC2 IN (SELECT C.OBJETIVO, 
       C.AUDITORIA , 
       C.NOME, 
       C.PRODUTO 
      FROM CALCULO C) 
    LOOP 

    SELECT ' V_UPD NUMBER := 0; 

       SELECT (SELECT ID_TIPO_TERR 
       FROM ZREPORTYTD_TMP 
      WHERE AUDITORIA = ''' || VC2.AUDITORIA || ''' 
       AND TERRITORIO = ''' || VC2.NOME || ''' 
       AND PRODUTO = ''' || VC2.PRODUTO || ''') 
       INTO V_UPD FROM DUAL; 

        UPDATE ZReportYTD_TMP 
        SET TARGET = ' || VC2.OBJETIVO || ' 
        WHERE AUDITORIA = ''' || VC2.AUDITORIA || ''' 
        AND TERRITORIO = ''' || VC2.NOME || ''' 
        AND PRODUTO = ''' || VC2.PRODUTO || ''';' 

       INTO V_SQL FROM DUAL; 

       EXECUTE IMMEDIATE (V_SQL); 

    END LOOP 

裏面的動態查詢,在這部分"SET TARGET = ' || VC2.OBJETIVO || '"價值​​是Number類型,它被替換爲「62481,76」。換句話說,這個逗號使得命令錯誤並且不起作用。

有沒有一種簡單的方法來代替「」爲「」?

非常感謝! (:

+0

什麼是OBJETIVO的數據類型? – Chandu 2011-02-15 18:21:39

+0

這是一個數字(38,10)。 – gabsferreira 2011-02-15 18:23:29

+1

然後我不確定爲什麼它會返回格式化值的數字。 – Chandu 2011-02-15 18:24:52

回答

14

不要通過附加字符串構建查詢你會把自己暴露給大量的漏洞和薄弱環節,首先SQL注入的使用動態查詢不使用綁定變量並不能證明需求如果你。確實需要使用動態查詢(它不是從你的例子,爲什麼靜態更新將無法正常工作?清楚),而是執行此操作:

FOR vc2 IN (...) LOOP 
    v_sql := 
     'BEGIN 
      V_UPD NUMBER := 0; 

      SELECT (SELECT ID_TIPO_TERR 
       FROM ZREPORTYTD_TMP 
      WHERE AUDITORIA = :p1 
       AND TERRITORIO = :p2 
       AND PRODUTO = :p3) 
       INTO V_UPD FROM DUAL; 

      UPDATE ZReportYTD_TMP 
       SET TARGET = :p4 
      WHERE AUDITORIA = :p5 
       AND TERRITORIO = :p6 
       AND PRODUTO = :p7; 
     END'; 
    EXECUTE IMMEDIATE v_sql USING VC2.AUDITORIA, VC2.NOME, VC2.PRODUTO, 
           VC2.OBJETIVO, VC2.AUDITORIA, VC2.NOME, 
           VC2.PRODUTO; 
END LOOP; 

Oracle會正確使用合適的類型綁定

1

我沒有看到任何需要使用動態SQL。

爲什麼不一樣的東西:

FOR VC2 IN (SELECT C.OBJETIVO, 
       C.AUDITORIA , 
       C.NOME, 
       C.PRODUTO 
      FROM CALCULO C) LOOP 

    v_upd := 0; 

    SELECT 
     ID_TIPO_TERR 
    into 
     v_UPD 
    FROM 
     ZREPORTYTD_TMP 
    WHERE 
     AUDITORIA = VC2.AUDITORIA 
    AND TERRITORIO = VC2.NOME 
    AND PRODUTO = VC2.PRODUTO; 

    -- is v_upd used anywhere? 

    UPDATE 
     ZReportYTD_TMP 
    SET 
     TARGET = VC2.OBJETIVO 
    WHERE 
     AUDITORIA = VC2.AUDITORIA 
    AND TERRITORIO = VC2.NOME 
    AND PRODUTO = VC2.PRODUTO; 

END LOOP; 
0

我使用的是Oracle 11g,最後幾日的我面臨的 問題在Oracle程序執行動態查詢。我做了很多搜索。 終於我有解決辦法。

-- In blow procedure we pass multiple argument at run time 
-- We need reference cursor for dynamic query execution 
create or replace PROCEDURE FETCH_REPORT1_NEW(IPID IN number ,CAID IN number, 
ZOID IN number,CLID IN number,SDATE VARCHAR2 , EDATE 
VARCHAR2,OUT_VALUE OUT VARCHAR2) 

IS 

    l_sql varchar(200); TYPE cursor_ref IS REF CURSOR; c1 
cursor_ref; 

    UZID transaction_data.zone_id%TYPE; OUTAGE_MINS 
transaction_data.durationmin%TYPE; 

BEGIN 

    l_sql := 'select Avg (durationmin) , zone_id , 
    from transaction_data where alarm_id in (1,21,26,20) and zone_id not in(5)'; 

     IF IPID>0 THEN 

     l_sql := l_sql||' and IP_ID = '||IPID; 

     END IF;   


     l_sql := l_sql||' group by (zone_id)'; 
     open c1 for l_sql; 

      loop 
       fetch c1 into OUTAGE_MINS,UZID; 

         dbms_output.put_line(OUTAGE_MINS||UZID); 

       exit when c1%notfound; 

      end loop; 
    close c1; 
    END;