Вопрос

Thanks for your time!

I want to use ruby oci8 to connect to oracle database to generate AWR report.

When I do this through command line, the code is like this:

sqlplus sys/a@10.69.152.97/load as sysdba
SQL> define num_days = ''
SQL> define report_type = "html"
SQL> define begin_snap = 100
SQL> define end_snap = 101
SQL> define report_name = C:\tttt.html
SQL> @?\rdbms\admin\awrrpt.sql

I just want to automate the job using Ruby. I google it and find oci8 may help. So I just form my codes like this:

require 'oci8'
onn = OCI8.new('sys/a@10.69.152.97/load as sysdba')
conn.exec("define num_days = '';")
conn.exec('define report_type="html"')
onn.exec('define begin_snap = 100')
conn.exec('define end_snap = 101')
conn.exec('define report_name = C:\tttt.html')
conn.exec('@?\rdbms\admin\awrrpt.sql') { |r| puts r}

When I run it in cmd, it failed.

the failed message is :

    Warning: NLS_LANG is not set. fallback to US7ASCII.

    stmt.c:253:in oci8lib_191.so: ORA-00900: invalid SQL statement (OCIError)

    from C:/Ruby192/lib/ruby/gems/1.9.1/gems/ruby-oci8-2.1.2-x86-mingw32/lib/oci8/oci8.rb:474:in `exec'

    from C:/Ruby192/lib/ruby/gems/1.9.1/gems/ruby-oci8-2.1.2-x86-mingw32/lib/oci8/oci8.rb:282:in `exec_internal'

    from C:/Ruby192/lib/ruby/gems/1.9.1/gems/ruby-oci8-2.1.2-x86-mingw32/lib/oci8/oci8.rb:275:in `exec'

    from automate_awr.rb:4:in `<main>'

Besides, I can successfully log in to oracle and execute a select statement using oci8.

Where am I wrong ?

Thanks in advance!

Это было полезно?

Решение

The main problem is you make confusion between queries supposed to be executed on server-side, and sqlplus commands to be executed on client-side.

The define and @ commands are sqlplus commands, executed on client-side. They are not sent to Oracle. With the oci8 module, Ruby can connect to Oracle using OCI. It can send any query to the server but of course, it will not be able to run sqlplus commands.

The scripts in "?\rdbms\admin" are supposed to be executed from sqlplus. If you really need to run them from Ruby, I would suggest to use the Ruby Open3 module to fork a sqlplus process and provide the input parameters using pipes.

It should be possible to use something based on the following code:

commands = "
  define num_days = ''
  define report_type = 'html'
  define begin_snap = 100
  define end_snap = 101
  define report_name = C:\tttt.html
  @?\rdbms\admin\awrrpt.sql
"
res, s = Open3.capture2e("sqlplus -S sys/a@10.69.152.97/load as sysdba", :stdin_data=>commands)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top