class OCI8
def self.client_charset_name
- See: OCI8.encoding -
Other tags:
- Private: -
Returns:
-
(String)
- client-side character set name
Other tags:
- Since: - 2.1.0
def self.client_charset_name @@client_charset_name end
def self.in_cond(bind_name_prefix, array, type = nil, length = nil)
-
(OCI8::InCondBindHelper)
-
Parameters:
-
length
(Integer
) -- maximum bind length for string values. This is used as the fourth argument of {OCI8::Cursor#bind_param}. -
type
(Class
) -- data type. This is used as the third argument of {OCI8::Cursor#bind_param}. -
array
(Object
) -- an array of values to be bound. -
bind_name_prefix
(Symbol
) -- prefix of the place holder name
def self.in_cond(bind_name_prefix, array, type = nil, length = nil) InCondBindHelper.new(bind_name_prefix, array, type, length) end
def self.oracle_client_version
- See: OCI8#oracle_server_version -
Returns:
-
(OCI8::OracleVersion)
- Oracle client version
def self.oracle_client_version @@oracle_client_version end
def self.properties
- Since: - 2.0.5
Returns:
-
(a customized Hash)
-
def self.properties @@properties end
def database_charset_name
-
(String)
- Oracle database character set name
Other tags:
- Since: - 2.1.0
def database_charset_name charset_id2name(@server_handle.send(:attr_get_ub2, OCI_ATTR_CHARSET_ID)) end
def describe_any(object_name)
-
(a subclass of OCI8::Metadata::Base)
-
Parameters:
-
object_name
(String
) --
def describe_any(object_name) if /^PUBLIC\.(.*)/i =~ object_name md = __describe($1, OCI8::Metadata::Unknown, true) raise OCIError.new(4043, object_name) if md.obj_schema != 'PUBLIC' md else __describe(object_name, OCI8::Metadata::Unknown, true) end end
def describe_database(database_name)
-
(OCI8::Metadata::Database)
-
Parameters:
-
database_name
(String
) --
def describe_database(database_name) __describe(database_name, OCI8::Metadata::Database, false) end
def describe_function(function_name)
-
(OCI8::Metadata::Function)
-
Parameters:
-
function_name
(String
) --
def describe_function(function_name) __describe(function_name, OCI8::Metadata::Function, false) end
def describe_package(package_name)
-
(OCI8::Metadata::Package)
-
Parameters:
-
package_name
(String
) --
def describe_package(package_name) __describe(package_name, OCI8::Metadata::Package, false) end
def describe_procedure(procedure_name)
-
(OCI8::Metadata::Procedure)
-
Parameters:
-
procedure_name
(String
) --
def describe_procedure(procedure_name) __describe(procedure_name, OCI8::Metadata::Procedure, false) end
def describe_schema(schema_name)
-
(OCI8::Metadata::Schema)
-
Parameters:
-
schema_name
(String
) --
def describe_schema(schema_name) __describe(schema_name, OCI8::Metadata::Schema, false) end
def describe_sequence(sequence_name)
-
(OCI8::Metadata::Sequence)
-
Parameters:
-
sequence_name
(String
) --
def describe_sequence(sequence_name) __describe(sequence_name, OCI8::Metadata::Sequence, false) end
def describe_synonym(synonym_name, check_public_also = true)
-
(OCI8::Metadata::Synonym)
-
Parameters:
-
synonym_name
(String
) --
def describe_synonym(synonym_name, check_public_also = true) if /^PUBLIC\.(.*)/i =~ synonym_name md = __describe($1, OCI8::Metadata::Synonym, true) raise OCIError.new(4043, synonym_name) if md.obj_schema != 'PUBLIC' md else __describe(synonym_name, OCI8::Metadata::Synonym, check_public_also) end end
def describe_table(table_name, table_only = false)
-
(OCI8::Metadata::Table or OCI8::Metadata::View)
-
Parameters:
-
table_only
(Boolean
) -- (default: false) -
table_name
(String
) --
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. # follow synonyms up to 20 times to prevent infinite loop # caused by recursive synonyms. recursive_level = 20 recursive_level.times do metadata = __describe(table_name, OCI8::Metadata::Unknown, true) case metadata when OCI8::Metadata::Table, OCI8::Metadata::View return metadata when OCI8::Metadata::Synonym table_name = metadata.translated_name if metadata.obj_link and metadata.link.nil? # table_name is a synonym in a remote database for an object in the # remote database itself. table_name = "#{table_name}@#{metadata.obj_link}" end else raise OCIError.new(4043, table_name) # ORA-04043: object %s does not exist end end raise OCIError.new(36, recursive_level) # ORA-00036: maximum number of recursive SQL levels (%s) exceeded end end
def describe_type(type_name)
-
(OCI8::Metadata::Type)
-
Parameters:
-
type_name
(String
) --
def describe_type(type_name) __describe(type_name, OCI8::Metadata::Type, false) end
def describe_view(view_name)
-
(OCI8::Metadata::View)
-
Parameters:
-
view_name
(String
) --
def describe_view(view_name) __describe(view_name, OCI8::Metadata::View, false) end
def exec(sql, *bindvars, &block)
conn.logoff
conn.exec('CREATE TABLE test (col1 CHAR(6))') # => 0
conn = OCI8.new('scott', 'tiger')
example:
conn.logoff
puts num_rows.to_s + ' rows were updated.'
num_rows = conn.exec('UPDATE emp SET sal = sal * 1.1')
conn = OCI8.new('scott', 'tiger')
example:
It returns the number of processed rows.
== Other SQL statements
conn.exec(sql, *bindvars) { |*outvars| outvars }
FYI, the following code do same on ruby-oci8 1.0 and ruby-oci8 2.0.
conn.logoff
end
puts num # => 123
puts str # => '0123'
conn.exec("BEGIN :str := TO_CHAR(:num, 'FM0999'); END;", 'ABCD', 123) do |str, num|
conn = OCI8.new('scott', 'tiger')
executed.
If a block is given, the bind variables' values are passed to the block after
conn.logoff
# => 1
conn.exec("BEGIN :str := TO_CHAR(:num, 'FM0999'); END;", 'ABCD', 123)
conn = OCI8.new('scott', 'tiger')
example:
It returns the number of processed rows.
== PL/SQL block (ruby-oci8 2.0)
If a block is given, it is ignored.
same with that of bind variables.
which may modified by PL/SQL statement. The order of array is
123". This method returns the array of these bind variables,
is 4 and whose value is 'ABCD'" and "the number whose value is
and :num. These initial values are "the string whose width
Above example uses two bind variables which names are :str
conn.logoff
# => ["0123", 123]
conn.exec("BEGIN :str := TO_CHAR(:num, 'FM0999'); END;", 'ABCD', 123)
conn = OCI8.new('scott', 'tiger')
example:
It returns the array of bind variables' values.
== PL/SQL block (ruby-oci8 1.0)
conn.logoff
puts num_rows.to_s + ' rows were processed.'
end
puts r.join(',')
num_rows = conn.exec('SELECT * FROM emp') do |r|
conn = OCI8.new('scott', 'tiger')
example:
data is passed to the block as array. NULL value becomes nil in ruby.
It acts as iterator and returns the processed row counts. Fetched
== select statements with a block
conn.logoff
cursor.close
end
puts r.join(',')
while r = cursor.fetch()
cursor = conn.exec('SELECT * FROM emp')
conn = OCI8.new('scott', 'tiger')
example:
It returns the instance of OCI8::Cursor.
== select statements without block
before execution.
When bindvars are specified, they are bound as bind variables
create, alter and drop; and PL/SQL.
the type of sql statement: select; insert, update and delete;
Executes the sql statement. The type of return value depends on
def exec(sql, *bindvars, &block) @last_error = nil exec_internal(sql, *bindvars, &block) end
def exec_internal(sql, *bindvars)
- Private: -
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 # exec
def get_tdo_by_class(klass)
- Private: -
Returns:
-
(OCI8::TDO)
-
Parameters:
-
klass
(class of an OCI8::Object::Base's subclass
) --
def get_tdo_by_class(klass) @id_to_tdo ||= {} @name_to_tdo ||= {} tdo = @name_to_tdo[klass.typename] return tdo if tdo # found in the cache. metadata = describe_any(klass.typename) if metadata.is_a? OCI8::Metadata::Synonym metadata = describe_any(metadata.translated_name) end unless metadata.is_a? OCI8::Metadata::Type raise "unknown typename #{klass.typename}" end OCI8::TDO.new(self, metadata, klass) end
def get_tdo_by_metadata(metadata)
- Private: -
Returns:
-
(OCI8::TDO)
-
Parameters:
-
metadata
(OCI8::Metadata::Base's subclass
) --
def get_tdo_by_metadata(metadata) @id_to_tdo ||= {} @name_to_tdo ||= {} tdo = @id_to_tdo[metadata.tdo_id] return tdo if tdo schema_name = metadata.schema_name name = metadata.name full_name = schema_name + '.' + name klass = OCI8::Object::Base.get_class_by_typename(full_name) klass = OCI8::Object::Base.get_class_by_typename(name) if klass.nil? if klass.nil? if schema_name == username eval <<EOS dule Object class #{name.downcase.gsub(/(^|_)(.)/) { $2.upcase }} < OCI8::Object::Base set_typename('#{name}') end d S klass = OCI8::Object::Base.get_class_by_typename(name) else eval <<EOS dule Object module #{schema_name.downcase.gsub(/(^|_)(.)/) { $2.upcase }} class #{name.downcase.gsub(/(^|_)(.)/) { $2.upcase }} < OCI8::Object::Base set_typename('#{full_name}') end end d S klass = OCI8::Object::Base.get_class_by_typename(full_name) end end OCI8::TDO.new(self, metadata, klass) end
def get_tdo_by_typename(typename)
- Private: -
Returns:
-
(OCI8::TDO)
-
Parameters:
-
typename
(String
) --
def get_tdo_by_typename(typename) @name_to_tdo ||= {} tdo = @name_to_tdo[typename] return tdo if tdo metadata = describe_any(typename) if metadata.is_a? OCI8::Metadata::Synonym metadata = describe_any(metadata.translated_name) end unless metadata.is_a? OCI8::Metadata::Type raise "unknown typename #{typename}" end tdo = get_tdo_by_metadata(metadata) @name_to_tdo[typename] = tdo tdo end
def initialize(*args)
-
initialize(username, password, dbname = nil, privilege = nil)
def initialize(*args) if args.length == 1 username, password, dbname, privilege = parse_connect_string(args[0]) else username, password, dbname, privilege = args end if username.nil? and password.nil? cred = OCI_CRED_EXT end auth_mode = to_auth_mode(privilege) stmt_cache_size = OCI8.properties[:statement_cache_size] stmt_cache_size = nil if stmt_cache_size == 0 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 else tcp_connect_timeout = OCI8::properties[:tcp_connect_timeout] connect_timeout = OCI8::properties[:connect_timeout] tcp_keepalive = OCI8::properties[:tcp_keepalive] if tcp_connect_timeout || connect_timeout || tcp_keepalive dbname = to_connect_descriptor(dbname, tcp_connect_timeout, connect_timeout, tcp_keepalive) end end if stmt_cache_size # enable statement caching attach_mode |= 0x0004 # OCI_STMT_CACHE end # logon by the OCI function OCISessionBegin(). 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 if @@oracle_client_version >= ORAVER_11_1 # Sets the driver name displayed in V$SESSION_CONNECT_INFO.CLIENT_DRIVER # if both the client and the server are Oracle 11g or upper. # Only the first 8 chracters "ruby-oci" are displayed when the Oracle # server version is lower than 12.0.1.2. # 424: OCI_ATTR_DRIVER_NAME @session_handle.send(:attr_set_string, 424, "ruby-oci8 : #{OCI8::VERSION}") end server_attach(dbname, attach_mode) if OCI8.oracle_client_version >= OCI8::ORAVER_11_1 self.send_timeout = OCI8::properties[:send_timeout] if OCI8::properties[:send_timeout] self.recv_timeout = OCI8::properties[:recv_timeout] if OCI8::properties[:recv_timeout] end session_begin(cred ? cred : OCI_CRED_RDBMS, auth_mode) if stmt_cache_size # set statement cache size attr_set_ub4(176, stmt_cache_size) # 176: OCI_ATTR_STMTCACHESIZE end @prefetch_rows = 100 @username = nil end
def inspect
- Private: -
def inspect "#<OCI8:#{username}>" end
def oracle_server_version
-
(OCI8::OracleVersion)
-
Other tags:
- See: OCI8.oracle_client_version -
def oracle_server_version @oracle_server_version ||= OCI8::OracleVersion.new(oracle_server_vernum) end
def parse(sql)
-
(OCI8::Cursor)
-
Parameters:
-
sql
(String
) -- SQL statement
def parse(sql) @last_error = nil parse_internal(sql) end
def parse_internal(sql)
- Private: -
def parse_internal(sql) cursor = OCI8::Cursor.new(self, sql) cursor end
def prefetch_rows=(num)
retrieving specified number of rows in one round trip.
prefetch buffer to reduce the number of network round trips by
When a select statement is executed, the OCI library allocate
Sets the prefetch rows size. The default value is 100.
def prefetch_rows=(num) @prefetch_rows = num end
def recv_timeout
- Since: - 2.1.8 and Oracle 11.1
Other tags:
- See: #send_timeout -
Returns:
-
(Float)
- seconds
def recv_timeout # OCI_ATTR_RECEIVE_TIMEOUT = 436 @server_handle.send(:attr_get_ub4, 436).to_f / 1000 end
def recv_timeout
def recv_timeout raise NotImplementedError, 'recv_timeout is unimplemented in this Oracle version' end
def recv_timeout=(timeout)
- Since: - 2.1.8 and Oracle 11.1
Other tags:
- See: #send_timeout= -
Returns:
-
(void)
-
Parameters:
-
timeout
(Float
) --
def recv_timeout=(timeout) # OCI_ATTR_RECEIVE_TIMEOUT = 436 @server_handle.send(:attr_set_ub4, 436, timeout * 1000) end
def recv_timeout=(timeout)
def recv_timeout=(timeout) raise NotImplementedError, 'revc_timeout= is unimplemented in this Oracle version' end
def select_one(sql, *bindvars)
-
(Array)
- an array of first row.
Parameters:
-
bindvars
(Object
) -- bind variables -
sql
(String
) -- SQL statement
def select_one(sql, *bindvars) cursor = self.parse(sql) cursor.prefetch_rows = 1 begin cursor.exec(*bindvars) row = cursor.fetch ensure cursor.close end return row end
def send_timeout
- Since: - 2.1.8 and Oracle 11.1
Other tags:
- See: #recv_timeout -
Returns:
-
(Float)
- seconds
def send_timeout # OCI_ATTR_SEND_TIMEOUT = 435 @server_handle.send(:attr_get_ub4, 435).to_f / 1000 end
def send_timeout
def send_timeout raise NotImplementedError, 'send_timeout is unimplemented in this Oracle version' end
def send_timeout=(timeout)
- Since: - 2.1.8 and Oracle 11.1
Other tags:
- See: #recv_timeout= -
Returns:
-
(void)
-
Parameters:
-
timeout
(Float
) --
def send_timeout=(timeout) # OCI_ATTR_SEND_TIMEOUT = 435 @server_handle.send(:attr_set_ub4, 435, timeout * 1000) end
def send_timeout=(timeout)
def send_timeout=(timeout) raise NotImplementedError, 'send_timeout= is unimplemented in this Oracle version' end
def to_auth_mode(privilege)
- Private: -
def to_auth_mode(privilege) case privilege when :SYSDBA 0x00000002 # OCI_SYSDBA in oci.h when :SYSOPER 0x00000004 # OCI_SYSOPER in oci.h when :SYSASM if OCI8.oracle_client_version < OCI8::ORAVER_11_1 raise "SYSASM is not supported on Oracle version #{OCI8.oracle_client_version}" end 0x00008000 # OCI_SYSASM in oci.h when :SYSBACKUP if OCI8.oracle_client_version < OCI8::ORAVER_12_1 raise "SYSBACKUP is not supported on Oracle version #{OCI8.oracle_client_version}" end 0x00020000 # OCI_SYSBKP in oci.h when :SYSDG if OCI8.oracle_client_version < OCI8::ORAVER_12_1 raise "SYSDG is not supported on Oracle version #{OCI8.oracle_client_version}" end 0x00040000 # OCI_SYSDGD in oci.h when :SYSKM if OCI8.oracle_client_version < OCI8::ORAVER_12_1 raise "SYSKM is not supported on Oracle version #{OCI8.oracle_client_version}" end 0x00080000 # OCI_SYSKMT in oci.h when nil 0 # OCI_DEFAULT else raise "unknown privilege type #{privilege}" end end
def to_connect_descriptor(database, tcp_connect_timeout, connect_timeout, tcp_keepalive)
- Private: -
def to_connect_descriptor(database, tcp_connect_timeout, connect_timeout, tcp_keepalive) if @@easy_connect_naming_regex =~ database && ($1 || $2 || $4 || $5 || $6 || $7) connect_data = [] connect_data << "(SERVICE_NAME=#$5)" connect_data << "(SERVER=#$6)" if $6 connect_data << "(INSTANCE_NAME=#$7)" if $7 desc = [] desc << "(CONNECT_DATA=#{connect_data.join})" desc << "(ADDRESS=(PROTOCOL=TCP)(HOST=#{$2 || $3})(PORT=#{$4 || 1521}))" if tcp_connect_timeout desc << "(TRANSPORT_CONNECT_TIMEOUT=#{tcp_connect_timeout})" end if connect_timeout desc << "(CONNECT_TIMEOUT=#{connect_timeout})" end if tcp_keepalive desc << "(ENABLE=BROKEN)" end "(DESCRIPTION=#{desc.join})" else database end end
def username
def username @username || begin exec('select user from dual') do |row| @username = row[0] end @username end end