Class: OCI8

Inherits:
OCIHandle show all
Defined in:
lib/oci8/oci8.rb,
lib/oci8/object.rb,
lib/oci8/object.rb,
lib/oci8/bindtype.rb,
lib/oci8/datetime.rb,
lib/oci8/metadata.rb,
lib/oci8/properties.rb,
lib/oci8/encoding-init.rb,
lib/oci8/oracle_version.rb,
lib/oci8/connection_pool.rb,
ext/oci8/lob.c,
ext/oci8/stmt.c,
ext/oci8/encoding.c,
ext/oci8/ocinumber.c,
ext/oci8/connection_pool.c

Overview

A connection to a Oracle database server.

example:

# output the emp table's content as CSV format.
conn = OCI8.new(username, password)
conn.exec('select * from emp') do |row|
  puts row.join(',')
end

# execute PL/SQL block with bind variables.
conn = OCI8.new(username, password)
conn.exec('BEGIN procedure_name(:1, :2); END;',
           value_for_the_first_parameter,
           value_for_the_second_parameter)

Defined Under Namespace

Modules: BindType, Math, Metadata, Object Classes: BFILE, BLOB, CLOB, ConnectionPool, Cursor, LOB, NCLOB, OracleVersion, TDO

Constant Summary collapse

@@properties =
{
  :length_semantics => :byte,
  :bind_string_as_nchar => false,
  :float_conversion_type => :ruby,
  :statement_cache_size => 20,
}
@@client_charset_name =
'US7ASCII'

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ OCI8

call-seq:

new(username, password, dbname = nil, privilege = nil)

Connects to an Oracle database server by username and password at dbname as privilege.

connecting to the local server

Set username and password or pass “username/password” as a single argument.

OCI8.new('scott', 'tiger')

or

OCI8.new('scott/tiger')

connecting to a remote server

Set username, password and dbname or pass “username/password@dbname” as a single argument.

OCI8.new('scott', 'tiger', 'orcl.world')

or

OCI8.new('scott/[email protected]')

The dbname is a net service name or an easy connectection identifier. The former is a name listed in the file tnsnames.ora. Ask to your DBA if you don’t know what it is. The latter has the syntax as “//host:port/service_name”.

OCI8.new('scott', 'tiger', '//remote-host:1521/XE')

or

OCI8.new('scott/tiger@//remote-host:1521/XE')

connecting as a privileged user

Set :SYSDBA or :SYSOPER to privilege, otherwise “username/password as sysdba” or “username/password as sysoper” as a single argument.

OCI8.new('sys', 'change_on_install', nil, :SYSDBA)

or

OCI8.new('sys/change_on_install as sysdba')

external OS authentication

Set nil to username and password, or “/” as a single argument.

OCI8.new(nil, nil)

or

OCI8.new('/')

To connect to a remote host:

OCI8.new(nil, nil, 'dbname')

or

OCI8.new('/@dbname')

proxy authentication

Enclose end user’s username with square brackets and add it at the end of proxy user’s username.

OCI8.new('proxy_user_name[end_user_name]', 'proxy_password')

or

OCI8.new('proxy_user_name[end_user_name]/proxy_password')


95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/oci8/oci8.rb', line 95

def initialize(*args)
  if args.length == 1
    username, password, dbname, mode = parse_connect_string(args[0])
  else
    username, password, dbname, mode = args
  end

  if username.nil? and password.nil?
    cred = OCI_CRED_EXT
  end
  case mode
  when :SYSDBA
    mode = OCI_SYSDBA
  when :SYSOPER
    mode = OCI_SYSOPER
  when :SYSASM
    if OCI8.oracle_client_version < OCI8::ORAVER_11_1
      raise "SYSASM is not supported on Oracle version #{OCI8.oracle_client_version}"
    end
    mode = OCI_SYSASM
  when nil
    # do nothing
  else
    raise "unknown privilege type #{mode}"
  end

  stmt_cache_size = OCI8.properties[:statement_cache_size]

  if mode.nil? and cred.nil?
    # logon by the OCI function OCILogon2().
    logon2_mode = 0
    if dbname.is_a? OCI8::ConnectionPool
      @pool = dbname # to prevent GC from freeing the connection pool.
      dbname = dbname.send(:pool_name)
      logon2_mode |= 0x0200 # OCI_LOGON2_CPOOL
    end
    if stmt_cache_size
      # enable statement caching
      logon2_mode |= 0x0004 # OCI_LOGON2_STMTCACHE
    end

    logon2(username, password, dbname, logon2_mode)

    if stmt_cache_size
      # set statement cache size
      attr_set_ub4(176, stmt_cache_size) # 176: OCI_ATTR_STMTCACHESIZE
    end
  else
    # logon by the OCI function OCISessionBegin().
    attach_mode = 0
    if dbname.is_a? OCI8::ConnectionPool
      @pool = dbname # to prevent GC from freeing the connection pool.
      dbname = dbname.send(:pool_name)
      attach_mode |= 0x0200 # OCI_CPOOL
    end
    if stmt_cache_size
      # enable statement caching
      attach_mode |= 0x0004 # OCI_STMT_CACHE
    end

    allocate_handles()
    session_handle.send(:attr_set_string, OCI_ATTR_USERNAME, username) if username
    session_handle.send(:attr_set_string, OCI_ATTR_PASSWORD, password) if password
    server_attach(dbname, attach_mode)
    session_begin(cred ? cred : OCI_CRED_RDBMS, mode ? mode : OCI_DEFAULT)

    if stmt_cache_size
      # set statement cache size
      attr_set_ub4(176, stmt_cache_size) # 176: OCI_ATTR_STMTCACHESIZE
    end
  end

  @prefetch_rows = nil
  @username = nil
end

Class Method Details

.[](name) ⇒ Object

Raises:

  • (IndexError)


19
20
21
22
# File 'lib/oci8/properties.rb', line 19

def @@properties.[](name)
  raise IndexError, "No such property name: #{name}" unless @@properties.has_key?(name)
  super(name)
end

.[]=(name, val) ⇒ Object

Raises:

  • (IndexError)


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/oci8/properties.rb', line 24

def @@properties.[]=(name, val)
  raise IndexError, "No such property name: #{name}" unless @@properties.has_key?(name)
  case name
  when :length_semantic
    if val != :byte and val != :char
      raise ArgumentError, "Invalid property value #{val} for :length_semantics."
    end
  when :bind_string_as_nchar
    val = val ? true : false
  when :float_conversion_type
    # handled by native code in oci8lib_xx.so.
    OCI8.__set_property(name, val)
  when :statement_cache_size
    if OCI8.oracle_client_version < OCI8::ORAVER_9_2
      raise RuntimeError, ":statement_cache_size is disabled on Oracle 9iR1 client."
    end
    val = val.to_i
    raise ArgumentError, "The property value for :statement_cache_size must not be negative." if val < 0
  end
  super(name, val)
end

.client_charset_nameObject

:call-seq:

OCI8.client_charset_name -> string

(new in 2.1.0)

Returns the client character set name.



378
379
380
# File 'lib/oci8/oci8.rb', line 378

def self.client_charset_name
  @@client_charset_name
end

.encodingObject

(new in 2.0.0 and ruby 1.9)

Returns the Oracle client encoding.

When string data, such as SQL statements and bind variables, are passed to Oracle, they are converted to OCI8.encoding in advance.

# When OCI8.encoding is ISO-8859-1,
conn.exec('insert into country_code values(:1, :2, :3)',
          'AT', 'Austria', "\u00d6sterreichs")
# "\u00d6sterreichs" is 'Österreichs' encoded by UTF-8.
# It is converted to ISO-8859-1 before it is passed to
# the Oracle C API.

When string data, such as fetched values and bind variable for output, are retrieved from Oracle, they are encoded by OCI8.encoding if Encoding.default_internal is nil. If it isn’t nil, they are converted from OCI8.encoding to Encoding.default_internal.

If OCI8.encoding is ASCII-8BIT, no encoding conversions are done.



242
243
244
245
# File 'ext/oci8/encoding.c', line 242

static VALUE oci8_get_encoding(VALUE klass)
{
    return rb_enc_from_encoding(oci8_encoding);
}

.encoding=(enc) ⇒ Object

(new in 2.0.0 and ruby 1.9)

Sets Oracle client encoding. You must not use this method. You should set the environment variable NLS_LANG properly to change OCI8.encoding.



257
258
259
260
261
262
263
264
265
# File 'ext/oci8/encoding.c', line 257

static VALUE oci8_set_encoding(VALUE klass, VALUE encoding)
{
    if (NIL_P(encoding)) {
        oci8_encoding = NULL;
    } else {
        oci8_encoding = rb_to_encoding(encoding);
    }
    return encoding;
}

.nls_ratioInteger

(new in 2.1.0)

Gets NLS ratio, maximum number of bytes per one character of the current NLS chracter set. It is a factor to calculate the internal buffer size of a string bind variable whose nls length semantics is char.

Returns:

  • (Integer)


186
187
188
189
# File 'ext/oci8/encoding.c', line 186

static VALUE oci8_get_nls_ratio(VALUE klass)
{
    return INT2NUM(oci8_nls_ratio);
}

.nls_ratio=(integer) ⇒ Object

(new in 2.1.0)

Sets NLS ratio, maximum number of bytes per one character of the current NLS chracter set. It is initialized in ‘oci8/encoding-init.rb’ when oci8 is required. You have no need to set it explicitly.



201
202
203
204
205
206
207
208
209
# File 'ext/oci8/encoding.c', line 201

static VALUE oci8_set_nls_ratio(VALUE klass, VALUE val)
{
    int v = NUM2INT(val);
    if (v <= 0) {
        rb_raise(rb_eRangeError, "expected a positive integer but %d", v);
    }
    oci8_nls_ratio = v;
    return val;
}

.propertiesObject

call-seq:

OCI8.properties -> a customized Hash

(new in 2.0.5)

Returns a Hash which ruby-oci8 global settings. The hash’s setter and getter methods are customized to check property names and values.

# get properties
OCI8.properties[:bind_string_as_nchar]  # => false
OCI8.properties[:invalid_property_name] # raises an IndexError

# set properties
OCI8.properties[:bind_string_as_nchar] = true
OCI8.properties[:invalid_property_name] = true # raises an IndexError

Supported properties are listed below:

:length_semantics

(new in 2.1.0)

:char when Oracle character length is counted by the number of characters. :byte when it is counted by the number of bytes. The default setting is :byte because :char causes unexpected behaviour on Oracle 9i.

:bind_string_as_nchar

true when string bind variables are bound as NCHAR, otherwise false. The default value is false.

:float_conversion_type

(new in 2.1.0)

:ruby when Oracle decimal numbers are converted to ruby Float values same as Float#to_s does. (default) :oracle: when they are done by Oracle OCI functions.

From ruby 1.9.2, a float value converted from Oracle number 15.7 by the Oracle function OCINumberToReal() makes a string representation 15.700000000000001 by Float#to_s. See: rubyforge.org/forum/forum.php?thread_id=50030&forum_id=1078

:statement_cache_size

(new in 2.1.1)

The statement cache size per each session. The default value is 20 statements. This feature is available on Oracle 9iR2 or later. See: docs.oracle.com/cd/E11882_01/appdev.112/e10646/oci09adv.htm#i471377



96
97
98
# File 'lib/oci8/properties.rb', line 96

def self.properties
  @@properties
end

Instance Method Details

#charset_id2name(charset_id) ⇒ Object

(new in 2.0.0)

Returns the Oracle character set name from the specified character set ID if it is valid. Otherwise, nil is returned.

Oracle 9iR2 client or upper

It is done by using the mapping table stored in the client side.

Oracle 9iR1 client or lower

It executes the following PL/SQL block internally to use the mapping table stored in the server side.

BEGIN
  :name := nls_charset_name(:csid);
END;


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'ext/oci8/encoding.c', line 52

VALUE oci8_charset_id2name(VALUE svc, VALUE csid)
{
    VALUE name = rb_hash_aref(csid2name, csid);

    if (!NIL_P(name)) {
        return name;
    }
    Check_Type(csid, T_FIXNUM);
    if (have_OCINlsCharSetIdToName) {
        /* Oracle 9iR2 or upper */
        char buf[OCI_NLS_MAXBUFSZ];
        sword rv;

        rv = OCINlsCharSetIdToName(oci8_envhp, TO_ORATEXT(buf), sizeof(buf), (ub2)FIX2INT(csid));
        if (rv != OCI_SUCCESS) {
            return Qnil;
        }
        name = rb_usascii_str_new_cstr(buf);
    } else {
        /* Oracle 9iR1 or lower */
        oci8_exec_sql_var_t bind_vars[2];
        char buf[OCI_NLS_MAXBUFSZ];
        ub2 buflen = 0;
        int ival = FIX2INT(csid);

        /* :name */
        bind_vars[0].valuep = buf;
        bind_vars[0].value_sz = OCI_NLS_MAXBUFSZ;
        bind_vars[0].dty = SQLT_CHR;
        bind_vars[0].indp = NULL;
        bind_vars[0].alenp = &buflen;
        /* :csid */
        bind_vars[1].valuep = &ival;
        bind_vars[1].value_sz = sizeof(int);
        bind_vars[1].dty = SQLT_INT;
        bind_vars[1].indp = NULL;
        bind_vars[1].alenp = NULL;

        /* convert chaset id to charset name by querying Oracle server. */
        oci8_exec_sql(oci8_get_svcctx(svc), "BEGIN :name := nls_charset_name(:csid); END;", 0, NULL, 2, bind_vars, 1);
        if (buflen == 0) {
            return Qnil;
        }
        name = rb_usascii_str_new(buf, buflen);
    }
    OBJ_FREEZE(name);
    rb_hash_aset(csid2name, csid, name);
    rb_hash_aset(csname2id, name, csid);
    return name;
}

#charset_name2id(charset_name) ⇒ Object

(new in 2.0.0)

Returns the Oracle character set ID for the specified Oracle character set name if it is valid. Othewise, nil is returned.

Oracle 9iR2 client or upper

It is done by using the mapping table stored in the client side.

Oracle 9iR1 client or lower

It executes the following PL/SQL block internally to use the mapping table stored in the server side.

BEGIN
  :csid := nls_charset_id(:name);
END;


126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'ext/oci8/encoding.c', line 126

static VALUE oci8_charset_name2id(VALUE svc, VALUE name)
{
    VALUE csid;

    name = rb_funcall(name, id_upcase, 0);
    csid = rb_hash_aref(csname2id, StringValue(name));
    if (!NIL_P(csid)) {
        return csid;
    }
    if (have_OCINlsCharSetNameToId) {
        /* Oracle 9iR2 or upper */
        ub2 rv;

        rv = OCINlsCharSetNameToId(oci8_envhp, RSTRING_ORATEXT(name));
        if (rv == 0) {
            return Qnil;
        }
        csid = INT2FIX(rv);
    } else {
        /* Oracle 9iR1 or lower */
        oci8_exec_sql_var_t bind_vars[2];
        int ival;
        sb2 ind = 0; /* null indicator */

        /* :csid */
        bind_vars[0].valuep = &ival;
        bind_vars[0].value_sz = sizeof(int);
        bind_vars[0].dty = SQLT_INT;
        bind_vars[0].indp = &ind;
        bind_vars[0].alenp = NULL;
        /* :name */
        bind_vars[1].valuep = RSTRING_PTR(name);
        bind_vars[1].value_sz = RSTRING_LEN(name);
        bind_vars[1].dty = SQLT_CHR;
        bind_vars[1].indp = NULL;
        bind_vars[1].alenp = NULL;

        /* convert chaset name to charset id by querying Oracle server. */
        oci8_exec_sql(oci8_get_svcctx(svc), "BEGIN :csid := nls_charset_id(:name); END;", 0, NULL, 2, bind_vars, 1);
        if (ind) {
            return Qnil;
        }
        csid = INT2FIX(ival);
    }
    rb_hash_aset(csid2name, csid, name);
    rb_hash_aset(csname2id, name, csid);
    return csid;
}

#database_charset_nameObject

:call-seq:

database_charset_name -> string

(new in 2.1.0)

Returns the database character set name.



368
369
370
# File 'lib/oci8/oci8.rb', line 368

def database_charset_name
  charset_id2name(server_handle.send(:attr_get_ub2, OCI_ATTR_CHARSET_ID))
end

#describe_any(object_name) ⇒ Object

return a subclass of OCI8::Metadata::Base which has information about object_name. OCI8::Metadata::Table, OCI8::Metadata::View, OCI8::Metadata::Procedure, OCI8::Metadata::Function, OCI8::Metadata::Package, OCI8::Metadata::Type, OCI8::Metadata::Synonym or OCI8::Metadata::Sequence



2069
2070
2071
# File 'lib/oci8/metadata.rb', line 2069

def describe_any(object_name)
  __describe(object_name, OCI8::Metadata::Unknown, true)
end

#describe_database(database_name) ⇒ Object

returns a OCI8::Metadata::Database.



2129
2130
2131
# File 'lib/oci8/metadata.rb', line 2129

def describe_database(database_name)
  __describe(database_name, OCI8::Metadata::Database, false)
end

#describe_function(function_name) ⇒ Object

returns a OCI8::Metadata::Function in the current schema.



2105
2106
2107
# File 'lib/oci8/metadata.rb', line 2105

def describe_function(function_name)
  __describe(function_name, OCI8::Metadata::Function, false)
end

#describe_package(package_name) ⇒ Object

returns a OCI8::Metadata::Package in the current schema.



2109
2110
2111
# File 'lib/oci8/metadata.rb', line 2109

def describe_package(package_name)
  __describe(package_name, OCI8::Metadata::Package, false)
end

#describe_procedure(procedure_name) ⇒ Object

returns a OCI8::Metadata::Procedure in the current schema.



2101
2102
2103
# File 'lib/oci8/metadata.rb', line 2101

def describe_procedure(procedure_name)
  __describe(procedure_name, OCI8::Metadata::Procedure, false)
end

#describe_schema(schema_name) ⇒ Object

returns a OCI8::Metadata::Schema in the database.



2125
2126
2127
# File 'lib/oci8/metadata.rb', line 2125

def describe_schema(schema_name)
  __describe(schema_name, OCI8::Metadata::Schema, false)
end

#describe_sequence(sequence_name) ⇒ Object

returns a OCI8::Metadata::Sequence in the current schema.



2121
2122
2123
# File 'lib/oci8/metadata.rb', line 2121

def describe_sequence(sequence_name)
  __describe(sequence_name, OCI8::Metadata::Sequence, false)
end

#describe_synonym(synonym_name, check_public_also = true) ⇒ Object

returns a OCI8::Metadata::Synonym in the current schema.



2117
2118
2119
# File 'lib/oci8/metadata.rb', line 2117

def describe_synonym(synonym_name, check_public_also = true)
  __describe(synonym_name, OCI8::Metadata::Synonym, check_public_also)
end

#describe_table(table_name, table_only = false) ⇒ Object

returns a OCI8::Metadata::Table or a OCI8::Metadata::View. If the name is a current schema’s synonym name or a public synonym name, it returns a OCI8::Metadata::Table or a OCI8::Metadata::View which the synonym refers.

If the second argument is true, this returns a OCI8::Metadata::Table in the current schema.



2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
# File 'lib/oci8/metadata.rb', line 2079

def describe_table(table_name, table_only = false)
  if table_only
    # check my own tables only.
    __describe(table_name, OCI8::Metadata::Table, false)
  else
    # check tables, views, synonyms and public synonyms.
     = __describe(table_name, OCI8::Metadata::Unknown, true)
    case 
    when OCI8::Metadata::Table, OCI8::Metadata::View
      
    when OCI8::Metadata::Synonym
      describe_table(.translated_name)
    else
      raise OCIError.new("ORA-04043: object #{table_name} does not exist", 4043)
    end
  end
end

#describe_type(type_name) ⇒ Object

returns a OCI8::Metadata::Type in the current schema.



2113
2114
2115
# File 'lib/oci8/metadata.rb', line 2113

def describe_type(type_name)
  __describe(type_name, OCI8::Metadata::Type, false)
end

#describe_view(view_name) ⇒ Object

returns a OCI8::Metadata::View in the current schema.



2097
2098
2099
# File 'lib/oci8/metadata.rb', line 2097

def describe_view(view_name)
  __describe(view_name, OCI8::Metadata::View, false)
end

#exec(sql, *bindvars, &block) ⇒ Object

Executes the sql statement. The type of return value depends on the type of sql statement: select; insert, update and delete; create, alter and drop; and PL/SQL.

When bindvars are specified, they are bound as bind variables before execution.

select statements without block

It returns the instance of OCI8::Cursor.

example:

conn = OCI8.new('scott', 'tiger')
cursor = conn.exec('SELECT * FROM emp')
while r = cursor.fetch()
  puts r.join(',')
end
cursor.close
conn.logoff

select statements with a block

It acts as iterator and returns the processed row counts. Fetched data is passed to the block as array. NULL value becomes nil in ruby.

example:

conn = OCI8.new('scott', 'tiger')
num_rows = conn.exec('SELECT * FROM emp') do |r|
  puts r.join(',')
end
puts num_rows.to_s + ' rows were processed.'
conn.logoff

PL/SQL block (ruby-oci8 1.0)

It returns the array of bind variables’ values.

example:

conn = OCI8.new('scott', 'tiger')
conn.exec("BEGIN :str := TO_CHAR(:num, 'FM0999'); END;", 'ABCD', 123)
# => ["0123", 123]
conn.logoff

Above example uses two bind variables which names are :str and :num. These initial values are “the string whose width is 4 and whose value is ‘ABCD’” and “the number whose value is 123”. This method returns the array of these bind variables, which may modified by PL/SQL statement. The order of array is same with that of bind variables.

If a block is given, it is ignored.

PL/SQL block (ruby-oci8 2.0)

It returns the number of processed rows.

example:

conn = OCI8.new('scott', 'tiger')
conn.exec("BEGIN :str := TO_CHAR(:num, 'FM0999'); END;", 'ABCD', 123)
# => 1
conn.logoff

If a block is given, the bind variables’ values are passed to the block after executed.

conn = OCI8.new('scott', 'tiger')
conn.exec("BEGIN :str := TO_CHAR(:num, 'FM0999'); END;", 'ABCD', 123) do |str, num|
  puts str # => '0123'
  puts num # => 123
end
conn.logoff

FYI, the following code do same on ruby-oci8 1.0 and ruby-oci8 2.0.

conn.exec(sql, *bindvars) { |*outvars| outvars }

Other SQL statements

It returns the number of processed rows.

example:

conn = OCI8.new('scott', 'tiger')
num_rows = conn.exec('UPDATE emp SET sal = sal * 1.1')
puts num_rows.to_s + ' rows were updated.'
conn.logoff

example:

conn = OCI8.new('scott', 'tiger')
conn.exec('CREATE TABLE test (col1 CHAR(6))') # => 0
conn.logoff


272
273
274
275
# File 'lib/oci8/oci8.rb', line 272

def exec(sql, *bindvars, &block)
  @last_error = nil
  exec_internal(sql, *bindvars, &block)
end

#exec_internal(sql, *bindvars) ⇒ Object

same with OCI8#exec except that this doesn’t reset OCI8#last_error.



278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
# File 'lib/oci8/oci8.rb', line 278

def exec_internal(sql, *bindvars)
  begin
    cursor = parse(sql)
    ret = cursor.exec(*bindvars)
    case cursor.type
    when :select_stmt
      if block_given?
        cursor.fetch { |row| yield(row) }   # for each row
        ret = cursor.row_count()
      else
        ret = cursor
        cursor = nil # unset cursor to skip cursor.close in ensure block
        ret
      end
    when :begin_stmt, :declare_stmt # PL/SQL block
      if block_given?
        ary = []
        cursor.keys.sort.each do |key|
          ary << cursor[key]
        end
        yield(*ary)
      else
        ret
      end
    else
      ret # number of rows processed
    end
  ensure
    cursor.nil? || cursor.close
  end
end

#inspectObject



333
334
335
# File 'lib/oci8/oci8.rb', line 333

def inspect
  "#<OCI8:#{username}>"
end

#oracle_server_versionObject

:call-seq:

oracle_server_version -> oraver

Returns an OCI8::OracleVersion of the Oracle server version.

See also: OCI8.oracle_client_version



343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
# File 'lib/oci8/oci8.rb', line 343

def oracle_server_version
  unless defined? @oracle_server_version
    if vernum = oracle_server_vernum
      # If the Oracle client is Oracle 9i or upper,
      # get the server version from the OCI function OCIServerRelease.
      @oracle_server_version = OCI8::OracleVersion.new(vernum)
    else
      # Otherwise, get it from v$version.
      self.exec('select banner from v$version') do |row|
        if /^Oracle.*?(\d+\.\d+\.\d+\.\d+\.\d+)/ =~ row[0]
          @oracle_server_version = OCI8::OracleVersion.new($1)
          break
        end
      end
    end
  end
  @oracle_server_version
end

#parse(sql) ⇒ Object

call-seq:

parse(sql_text) -> an OCI8::Cursor

Returns a prepared SQL handle.



175
176
177
178
# File 'lib/oci8/oci8.rb', line 175

def parse(sql)
  @last_error = nil
  parse_internal(sql)
end

#parse_internal(sql) ⇒ Object

same with OCI8#parse except that this doesn’t reset OCI8#last_error.



181
182
183
184
185
# File 'lib/oci8/oci8.rb', line 181

def parse_internal(sql)
  cursor = OCI8::Cursor.new(self, sql)
  cursor.prefetch_rows = @prefetch_rows if @prefetch_rows
  cursor
end

#select_one(sql, *bindvars) ⇒ Object

:call-seq:

select_one(sql, *bindvars) -> first_one_row


313
314
315
316
317
318
319
320
321
322
# File 'lib/oci8/oci8.rb', line 313

def select_one(sql, *bindvars)
  cursor = self.parse(sql)
  begin
    cursor.exec(*bindvars)
    row = cursor.fetch
  ensure
    cursor.close
  end
  return row
end

#usernameObject



324
325
326
327
328
329
330
331
# File 'lib/oci8/oci8.rb', line 324

def username
  @username || begin
    exec('select user from dual') do |row|
      @username = row[0]
    end
    @username
  end
end