Executing Oracle PL/SQL from Ant

While not being that new of a problem, I ran over it today. So if you ever run into that kind of problem, here’s what you can do. I had the specific issue of dropping all tables in a specific user’s schema. Ant’s <sql> task can’t run any PL/SQL without specific options, because as default, every single line of the input (be it a file or SQL embedded into your build file) is executed separately.

So I have a small PL/SQL script that looks like this:

declare
   table_name varchar2(30);
   cursor usertables is select * from user_tables where table_name not like ‘BIN$%’;
begin
   for next_row in usertables
   loop
      execute immediate ‘drop table ‘ || next_row.table_name || ‘ cascade constraints’;
   end loop;
end;
/

Don’t worry about any inefficiencies, that this snippet might have, for now ;)

So if you stuff this piece of code into Oracle using Ant’s <sql> task, you get a nice error complaining about the second line containing declare.... We build on the following snippet of Ant build file code:

<sql rdbms=“oracle”
     
userid=“scott”
     
password=“tiger”
     
driver=“oracle.jdbc.OracleDriver”
     
url=“jdbc:oracle:thin:@myhost:1521:orcl”
     
classpathref=“classpath”
   
<transaction src=“drop-tables.sql”/>
</sql>

So this is the code that will throw an error when executing a bunch of PL/SQL code. But don’t worry, fixing it is just easy:

<sql rdbms=“oracle”
     
userid=“scott”
     
password=“tiger”
     
driver=“oracle.jdbc.OracleDriver”
     
url=“jdbc:oracle:thin:@myhost:1521:orcl”
     
classpathref=“classpath”
     
delimiter=“/”
     
delimitertype=“row”
     
keepformat=“yes”
   
<transaction src=“drop-tables.sql”/>
</sql>

That’s it you’re saying? Yes! Adding the attributes delimiter and delimitertype tells the task to throw the whole bunch of code directly over to Oracle without worrying about anything except a / on a single line. delimiter tells Ant to look for the / as a separator for a signle set of statements to be executed at once. Since we’re all huge fans of SQL*Plus, we’ll even tell Ant to look for the / (that’s what the attribute delimitertype is for) on a single line by itself. Only then will the bunch of statements that occured since the last / be thrown over to Oracle and be executed. Ah, the joy of delegating.

As a bonus, we’ll throw in the attribute keepformat, since we want to see the PL/SQL code executed as we have it in the file, right? But this only comes in handy when debugging Ant. Newlines will not be removed so that the output will look like the input.

25 Responses to “Executing Oracle PL/SQL from Ant”

  1. [...] Tools Databases — Lucas Jellema @ 5:42 pm See Post Report Just read the post Executing Oracle PL/SQL from Ant on how to u [...]

  2. [...] Javaddicts and the Amis blog are reporting about executing pl/sql statements from Ant: Executing Oracle PL/SQL from Ant, Executing PL/SQL from ANT [...]

  3. Ken Weiner says:

    I just wanted to say thank you so much for providing this information. I found your blog post on Google and it solved the exact problem I was trying to solve: running PL/SQL from both ant and SQLPLUS.

  4. Devin Erickson says:

    Thank you very much for posting this. It’s an elegant solution to a simple problem. You actually solved several of my problems at once.

    Keep up the good work!

  5. Mohin M says:

    I came across this problem recently, and tried something very very similar to what you have here, without success. Regardless, my unsophisticated method was to put things like triggers and pl/sql statements in a seperate file/script and set the delimiter to slash. Thus, no conflict with standard sql statements and no need to convert any semicolons to slashes.

    Might give this method verbatim a go when I stop being lazy.

  6. Kyle Dyer says:

    Thank you so much. This post really helped me out as well.

  7. Alper Akture says:

    And me as well. Thanks.

  8. MgM says:

    Thank you very much for this tip !

  9. Zdenek Vrablik says:

    Hi,

    thanks it works. But in this case i am not able to get possible compilation errors back to ANT. Is there any way how to do it? Thanks
    Zdenek

  10. Fred says:

    Hello,

    Unfortunately, for complex PLSQL scripts involving user defined procedure, the tasks doesn’t work even with your tip.

    The solution is found is:
    http://incanto.sourceforge.net/usage-sqlplus.html

    Here is the script:

    <!-- Initialization variables -->
    <property environment="env" />
    
    <property name="database.driver.dir" value="${env.JBOSS_HOME}/lib/"/>
    <property name="database.driver.jar" value="ojdbc14.jar"/>
    
    <path id="sql.classpath">
        <fileset dir="${database.driver.dir}">
            <include name="${database.driver.jar}"/>
        </fileset>
    </path>
    
    <!-- ====================================== -->
    <target name="init" description="Creates test data in the database.">
    
        <ora:sqlplus
           logon="user/pwd@DB"
           silent="true"
           failonerror="true"
           start="physical_data_model.sql">
        </ora:sqlplus>
    
     </target>
    

    Fred

  11. Nilesh GHorpade says:

    The PL/SQL snippet was really useful to me as I was stuck with some silly error for dropping the user tables.

    Thanks a lot. :-)

    Regards

    Nile

  12. Kan says:

    Thanks work nice..

  13. ejboy says:

    Scriptella (http://scriptella.javaforge.com) open source ETL tool also supports execution of PL/SQL scripts. See faq entry http://scriptella.javaforge.com/faq.html#PLSQL

  14. littlemoney says:

    weird oracles!

  15. RAJASEKAR.PV says:

    Great Idea and Suggesstion. Really it solves the exact problem.

    Let your service continues…..Let all the glories get to you…….

    Regards,
    Rajasekar.PV

  16. Srinivas says:

    But how did you get this?

  17. Michel says:

    Works very fine !

  18. subramanya says:

    can run more than one sql file under a folder in a single shot without specifying the file name ie, *.sql

  19. subramanya says:

    can i run more than one sql file under a folder in a single shot without specifying the file name ie, *.sql

  20. Mathias says:

    Yes, you can. Just use a fileset inside the sql task. You won\’t have control over the execution order of the files though.

  21. I want you to know that we are very pleased with the quality of Article you have provided. I sincerely appreciate your responsiveness and the way you conduct. I have recommended your to others because of our satisfaction. I look forward to doing with you further comment or suggestions. regards.

  22. Kurt says:

    Thanks. Excellent tip. I’ve been wrestling with this issue off and on for a month or so.

    The Ant sql task documentation leaves something to be desired.

  23. paperless says:

    Another way that supports execution of SQL is at paperlessme.wordpress.com

  24. Kennedy says:

    Awesome, i tried and it worked fine. But one thing i have i mind is to execute a list of sql scripts file using a simgle task(eg fileset type of mechanism).

    Thanks.

  25. Adarsh Kumar says:

    Excellent …

Leave a Reply

You must be logged in to post a comment.