Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

oracle - pl/sql - Using a dynamic query inside a stored procedure

I am using a stored procedure to insert data into a temp table using a cursor. This procedure stores a dynamic query inside a variable to mount the insert/update command.

Here is the code(not the full query, I've cut some parts to make it easier to read):

 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

Inside the dynamic query, in this part "SET TARGET = ' || VC2.OBJETIVO || '" the value VC2.OBJETIVO is a Number type, and it's replaced like "62481,76". In other words, this comma is making the command wrong and doesn't work.

Is there an easy way to replace the "," for "."?

Thank you very much! (:

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Don't build your query by appending strings. You leave yourself open to lots of bugs and vulnerabilities, first of all SQL injection. The need to use dynamic queries doesn't justify not using bind variables. If you really need to use dynamic queries (it is not clear from your example why static update wouldn't work?!), do this instead:

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 will correctly bind with the appropriate type.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...