2011-02-15 43 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;