Question

We are trying to perform routine maintenance tasks on our Oracle databases using Perl. I have user access to the databases and am doing all my scripting locally on the databases. I would like to run a SQL statement on the database to generate a pfile and save it to the tmp folder so that I can view it later.

However, we do not have DBI installed on our systems so I cannot use it to connect to the DB and execute SQL statements. I have admin access, but we are trying to avoid using DBI since this script will be deployed locally on each machine and we do not want to install DBI on all of our databases. Is there any possible way to execute SQL statements on an Oracle db without using DBI if you are running scripts locally on the DB?

For example, I would need to run this SQL statement in order to generate a pfile:

create pfile='/tmp/pfile.ora' from spfile

If I were doing this manually, I would have to su as oracle and then start up sqlplus on the machine to execute a SQL statement. I tried to sort of emulate this by putting these commands into a here-doc and then throwing it into a system() function:

my $result =<<EOF;
su - oracle
sqlplus / as sysdba
create pfile='/tmp/pfile.ora' from spfile;
exit
EOF

system($result);

But this does not work because it waits for the su - oracle command to exit before continuing on with the remainder of the statements (this also feels like a sloppy way of doing things). I also tried to do the same thing by creating a shell script and then executing the script from within perl using system("sh script.sh") but this yielded the same results.

Is there any way to achieve what I am trying to do, or should I be telling the higher ups that there's no other way to do this other than DBI?

Was it helpful?

Solution 2

I managed to get this work by placing the set of SQL commands in a string and then executing it using a system() function:

my $result = 'sqlplus / as sysdba <<EOF;
create pfile=\'/tmp/pfile.ora\' from spfile;
exit;
EOF
';

system($result);

The first line tells it to execute the following here-doc in sqlplus / as sysdba. The backslashes escape the single quotes in the pfile directory. Also, since only oracle can run sqlplus, it is already presumed that they are running the script as oracle, negating the need to su into it.

OTHER TIPS

To run multiple commands, waiting for responses in between, you would need to use the Expect module. However this is not in the perl core, so if you don't have DBI, then you probably don't have Expect either. If you're going to be installing a module anyways, then you might as well install DBI and do it the correct way.

It may, however, be possible to do this in one line, with something like:

open my $of, ">", "/tmp/pfile.sql";
$of->print("create pfile='/tmp/pfile.ora' from spfile");
close $of;
system("su - oracle -c 'sqlplus / as sysdba < /tmp/pfile.sql'");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top