0

How can I insert into a record the text of a procedure stored in ALL_SOURCE.TEXT ?

This part of code gives me error: "missing comma"

  execute immediate '
               insert into results(SrcProcedure)  values(' ''
               || tabela_temporare(1).text ||
               '' ')';

I think this is due to the unescaped characters contained in the text of the stored procedure, but I can't find a way to fix it.

Desaretiuss
  • 311
  • 1
  • 3
  • 12

3 Answers3

0

If you want to have the string delimiting character (apostrophe: ') inside a Varchar, you must use two consecutive apostrophes and then another one to end the string. It gives you an error because you ended the string first. Try this piece of code:

EXECUTE IMMEDIATE 'INSERT INTO results(SrcProcedure)  values(''' || tabela_temporare(1).text || ''')';

EDIT: Better use Bind Variables, see my sample Code:

CREATE TABLE RESULTS (SRCPROCEDURE VARCHAR2 (300));

DECLARE
      v_SQL VARCHAR2(4000) := 'INSERT INTO results(SrcProcedure) VALUES(:1)';
BEGIN
     EXECUTE IMMEDIATE v_SQL USING 'something2';
END;

I hope it works now! :)

Kuvick
  • 48
  • 6
  • That's what I've writen in the question – Desaretiuss Apr 28 '15 at 14:37
  • look closely to see the difference between your code and mine and go through my answer text again ;-) – Kuvick Apr 28 '15 at 14:43
  • Your dynamic SQL using a bind variable is much better. However, there is no more need to use a dynamic sql, you can leave the `EXECUTE IMMEDIATE` itself out. Also your datatype for SRCPROCEDURE will be much safer being a CLOB. – YoYo Apr 28 '15 at 16:04
0

What about simply doing this in your PL/SQL:

INSERT INTO results(SrcProcedure) VALUES (tabela_temporare(1).text);

Internally it will use bind variables to pass your PL/SQL variable into the INSERT.

Note that it is highly advised to stay away from dynamic SQL (EXECUTE IMMEDIATE and the likes), because that code will be prone to SQL injection.

[UPDATE] I don't know what more to tell. However consider these things for using a dynamically built SQL within a FOR loop using string search and replace:

  1. It will be terribly slow, because for each loop iteration, you recompile the dynamic SQL.
  2. The SQL itself will execute slower because it cannot be cached.
  3. You have the danger of SQL injection that can lead to bugs and security issues. You think you fixed it by search and replace quotes, but I bet there might be scenario's you did not take into account.
  4. The process itself of search and replace for quotes is also terribly slow.

There are good uses of dynamic SQL, but that is just not one of them, and it is also against all possible advice to 'concatenate' parameters vs 'binding' them.

YoYo
  • 9,157
  • 8
  • 57
  • 74
  • This time I only needed to make it work, using utl_match to compare source procedures of different users, though in the future I'll have to take into consideration these warnings on performance / security issues. – Desaretiuss Apr 29 '15 at 09:31
-1

If that text field contains actual stored pl/sql code, the only character likely to cause problems is the single quote.

So replace each instance with two single quotes which will then get parsed as a properly escaped single quote. Of course, you have to escape the quote in the replace statement to get it to work, but try this:

execute immediate '
           insert into results(SrcProcedure)  values(' ''
           || replace(tabela_temporare(1).text,'''','''''') ||
           '' ')';
Michael Broughton
  • 4,045
  • 14
  • 12