6

I would like to issue a parameterized to Oracle via sqlplus with all the the parameters provided in a text file. Is there a way to do this? The query has more parameters than is reasonable for a person to be prompted for and we would like to eliminate user error when entering the parameter for this.

The reason we need to issue a parameterized query is that we are seeing a huge difference in performance between a straight sql statement and the same query issued as a parameterized query in our application. We would like to remove any application code from the chain and have the difference evident with only Oracle tools.

asked Jun 1, 2011 at 18:11

4 Answers 4

5

If you want the SQL in one file and the parameters in another, this is an option. Have query.sql assigning positional parameters to bind variables and then executing a query:

variable p_owner varchar2(30);
variable p_column varchar2(30);
set verify off
set feedback off
begin
 :p_owner := '&1';
 :P_column := '&2';
end;
/
set feedback on
select table_name
from all_tab_columns
where owner = :p_owner
and column_name = :p_column;
exit 0;

And put the parameter values in a text file, say parms.txt:

SYS
OSUSER

And put it together with:

sqlplus -s user/password @query `cat parms.txt`

(This is for Unix, obviously; not sure off-hand what the command-line equivalent is for Windows). Change parms.txt, or use different files, and you'll still get the same hard-parsed plan each time.

Your performance problem sounds like it might possibly be related to bind variable peeking, particularly the 'stuck with a bad plan' description. The execution plan is determined by the first query run, which might choose suitable indexes etc. for those parameters; subsequent runs then use the same plan even if different indexes might be more suitable for the new parameters. The stand-alone straight SQL will have a separate parse and thus possibly different (more suitable) plan. In the past I've had to gather stats manually to prevent histograms being used, which at least stabilises things.

answered Jun 2, 2011 at 8:20
4

Well, a parameterized query is going to do better, hands down. The way we used to do something similar to this was by using an anonymous PL/SQL block that would use UTLFILE to open and read the parameters, feeding them to query in the block, and writing the output back to the file system.

YMMV of course.

answered Jun 1, 2011 at 19:19
3
  • Actually the issue we have is the paramertized query gets stuck with a bad plan and performs poorly. The DBA will test it with a plain sql statement and report nothing is wrong. For some some small queries doing parameters manually is ok for some we need a better way to provide them to the dba. Do you have an example that uses UTLFILE do read in parameters? Commented Jun 1, 2011 at 19:46
  • For 11g see: download.oracle.com/docs/cd/E11882_01/appdev.112/e16760/…. Commented Jun 1, 2011 at 21:07
  • 10g: download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/… Commented Jun 1, 2011 at 21:09
3

Since you mention SQL Plus, I assume you're doing this at the command line? If so, this might work for you:

parms.shl:
export parm1=1
export parm2=15
export parm3=150
dojob.shl:
#!/bin/sh
# source our variables into our context.
. parms.shl 
# call sqlplus and have the variables embedded.
sqlplus -s <<EOF
-- we're now in SQLPLUS
SELECT '$parm1', '$parm2', '$parm3'
 FROM DUAL;
-- and exit out
EXIT;
EOF

Then, at the command prompt, run:

./dojob.shl

And the results should match the incoming parameters. The catch is that the SQL needs to be in the shell script. (Pretty sure that using the @filename.sql feature of sqlplus will not see the OS-level environment variables.)

Not the most elegant, but it should work without UTF_FILE overhead/risks. It should work on most *NIX/BSD variants, but it shouldn't be hard to convert to a Windows batch file.

Side Note: Why not store the parameters in a place that's already ready made for storing data? That is, your database? If the parameters need to be changeable, then write a screen or other process that lets the parameters be updated by the end-user, and just link to the table in your process.

Side Side Note: In my example, I am not doing anything with regards to binding variables. Therefore performance is not likely to be great when used in a long-running statement. You can use sqlplus's variables to mitigate the effect (setting them to the OS variable via VARIABLE, and then re-using sqlplus's variables in your actual code. Then Oracle should be able to optimize the statement nicely. See http://www.adp-gmbh.ch/ora/sqlplus/use_vars.html )

answered Jun 2, 2011 at 5:24
2

Define named parameters owner and table in file params.sql:

 define owner=scott
 define table=emp

Call the definition file and use the parameters in file query.sql

 @params.sql
 select count(*) from &owner..&table
 /
 exit

The .. (two dots) after &owner are intended.

Now change to the directory where params.sql and query.sql are and call

 sqlplus user/password@database @query.sql

The named parameters can be used in the file query.sql in the same way as command line parameters of SQLPlus. The file params.sql can contain other statements than define. There are a lot of technics that can be used with SQLPlus that are described in the SQL*plus manual.

mustaccio
28.7k24 gold badges60 silver badges77 bronze badges
answered Jun 6, 2011 at 12:48

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.