[ Home ] [ English | Japanese ]
OCI ハンドルの抽象クラスです。 クラス階層 を参照してください。
OCIHandle#attrSet(type, value)対応するネイティブOCI関数: OCIAttrSet
OCIHandle#attrGet(type)対応するネイティブOCI関数: OCIAttrGet
OCIHandle#free()OCI のデータ構造を明示的に解放する。
対応するネイティブOCI関数: OCIHandleFree
環境ハンドル。このハンドルがすべての OCI オブジェクトの元となる。 たいていはひとつのアプリケーションにひとつのインスタンスです。
親クラス: OCIHandle
対応するネイティブOCIデータタイプ: OCIEnv
OCIEnv.create([mode])環境ハンドルを作成する。new は呼ばないでください。
OCI_DEFAULT, OCI_THREADED, OCI_OBJECT, OCI_SHARED もしくはこれらの組み合わせが指定可能です。しかし動作テストしてるのは OCI_DEFAULT のみです。デフォルト値は OCI_DEFAULT です。
OCI_THREADED: ネイティブスレッド(ruby のスレッドとは別)を使用しているとき。
OCI_OBJECT: OCI オブジェクトを使うとき指定します。しかし、今の実装では OCI オブジェクトリレーショナル関数をサポートしていませんし、計画にもはいって いません。
OCI_SHARED(Oracle 8i以降): 共有データ・モードを使用するとき指定します。
対応するネイティブOCI関数: OCIEnvCreate (OCIEnvCreate がないときは OCIInitialize と OCIEnvInit を使用)
OCIEnv.terminate([mode])対応するネイティブOCI関数: OCITerminate
OCIEnv#alloc(handle)新しい OCI ハンドルを作成します。
対応するネイティブOCI関数: OCIHandleAlloc
OCIEnv#logon(username, password, dbname)オラクルにログオンします。
単純化されたログインと明示的な連結(アタッチ)及び開始セッションも参照してください。
例:
env = OCIEnv.create()
svc = env.logon("SCOTT", "TIGER", nil)
or
svc = env.logon("SCOTT", "TIGER", "ORCL.WORLD")
対応するネイティブOCI関数: OCILogon
サービス・コンテキスト・ハンドル。このハンドルは他の一般的なデータ ベースインターフェースのセッションに相当します。
内部的にサーバー・ハンドル、ユーザ・セッション・ハンドル、 トランザクション・ハンドルの3種類のハンドルと協同して動きますが、特別な用途を除いて これらの内部ハンドルを直接あつかう必要はありません。
親クラス: OCIHandle
対応するネイティブOCIデータタイプ: OCISvcCtx
OCISvcCtx#logoff()オラクルとの接続を切断します。
ログインするのにOCIServer#attachとOCISession#begin を使った場合は、代わりにOCIServer#detachとOCISession#end を用いてください。 単純化されたログインと明示的な連結(アタッチ)及び開始セッション も参照してください。
対応するネイティブOCI関数: OCILogoff
OCISvcCtx#passwordChange(username, old_password, new_password [, mode])OCI_DEFAULT or OCI_AUTH. Default value is OCI_DEFAULT.
For most cases, use default value. If you want to know detail, see "Oracle Call Interface Programmer's Guide".
correspond native OCI function: OCIPasswordChange
OCISvcCtx#commit([flags])トランザクションを確定(コミット)します。
対応するネイティブOCI関数: OCITransCommit
OCISvcCtx#rollback([flags])トランザクションを取り消(ロールバック)します。
対応するネイティブOCI関数: OCITransRollback
OCISvcCtx#version()get server version.
string of server version. For example
Oracle8 Release 8.0.5.0.0 - Production PL/SQL Release 8.0.5.0.0 - Production
correspond native OCI function: OCIServerVersion
OCISvcCtx#release()get server version number and string
array of number and string. For example
version_number, version_str = svc.release() version_number is 0x8005000. version_str is Oracle8 Release 8.0.5.0.0 - Production PL/SQL Release 8.0.5.0.0 - Production
correspond native OCI function: OCIServerVersion
Oracle 9i or later?
サーバー・ハンドル。OCIEnv#logonを使った場合は、このハンドルを直接使う必要はありません。 というのも、OCIEnv#logonが暗黙のうちにハンドルを生成して、OCISvcCtxに設定するからです。
親クラス: OCIHandle
対応するネイティブOCIデータタイプ: OCIServer
OCIServer#attach(dbname [, mode])データベースに連結(アタッチ)する。
OCI_DEFAULTもしくはOCI_CPOOL(Oracle 9i)。デフォルト値はOCI_DEFAULTです。
この ruby モジュールは OCI の提供するコネクションプーリングをサポートしていません。 したがって、OCI_CPOOLは現在のところ無効な値です。
対応するネイティブOCI関数: OCIServerAttach
OCIServer#detach([mode])データベースとの連結を切り放します。
対応するネイティブOCI関数: OCIServerDetach
OCIServer#version()get server version.
string of server version. For example
Oracle8 Release 8.0.5.0.0 - Production PL/SQL Release 8.0.5.0.0 - Production
correspond native OCI function: OCIServerVersion
OCIServer#release()get server version number and string
array of number and string. For example
version_number, version_str = srv.release() version_number is 0x8005000. version_str is Oracle8 Release 8.0.5.0.0 - Production PL/SQL Release 8.0.5.0.0 - Production
correspond native OCI function: OCIServerVersion
Oracle 9i or later?
サーバー・ハンドル。OCIEnv#logonを使った場合は、このハンドルを直接使う必要はありません。 というのも、OCIEnv#logonが暗黙のうちにハンドルを生成して、OCISvcCtxに設定するからです。
親クラス: OCIHandle
対応するネイティブOCIデータタイプ: OCISession
OCISession#begin(svc [, credt [, mode]])指定されたサーバコンテキストの元で、ユーザセッションを開始します。
OCI_CRED_RDBMSもしくはOCI_CRED_EXT。 デフォルト値はOCI_CRED_RDBMSです。
OCI_CRED_RDBMSを使用する場合は、事前にOCI_ATTR_USERNAMEとOCI_ATTR_PASSWORD を設定してください。
OCI_DEFAULT、OCI_MIGRATE、OCI_SYSDBA、OCI_SYSOPER、 (OCI_SYSDBA | OCI_PRELIM_AUTH)、もしくは(OCI_SYSOPER | OCI_PRELIM_AUTH)。 デフォルト値はOCI_DEFAULTです。
SYSDBA権限もしくはSYSOPER権限が必要なときは、 OCI_SYSDBAもしくはOCI_SYSOPERを使ってつださい。
対応するネイティブOCI関数: OCISessionBegin
OCISession#end(svc [, vmode])ユーザ認証のコンテキストを終了する。
対応するネイティブOCI関数: OCISessionEnd
文ハンドル。このハンドルで SQL や PL/SQL とその属性を識別します。
SQL や PL/SQL の入出力変数の情報はバインド・ハンドルにて、 Select 文で select されるデータの情報は定義ハンドルにて 管理されます。
親クラス: OCIHandle
対応するネイティブOCIデータタイプ: OCIStmt
OCIStmt#prepare(stmt [, language [, mode]])SQL 文を設定して、実行の準備を行います。
OCI_DEFAULT または OCI_NO_SHARING。デフォルト値はOCI_DEFAULT。
OCI_NO_SHARING を指定すると、この文のついてのみ、共有データ・モード を無効にします。
対応するネイティブOCI関数: OCIStmtPrepare
OCIStmt#defineByPos(position, type [, length [, mode]])select 文の実行でとりだされるデータのデータタイプを定義します。 select 文からデータを取り出す前に、すべてのカラムの定義を行わないといけません。
対応するネイティブOCI関数: OCIDefineByPos
OCIStmt#bindByPos(position, type [, length [, mode]])バインド変数のデータタイプを位置指定で定義します。
対応するネイティブOCI関数: OCIBindByPos
OCIStmt#bindByName(name, type [, length [, mode]])バインド変数のデータタイプを名前で定義します。
例
stmt = env.alloc(OCIStmt)
stmt.prepare("SELECT * FROM EMP
WHERE ename = :ENAME
AND sal > :SAL
AND hiredate >= :HIREDATE")
b_ename = stmt.bindByName(":ENAME", String, 10)
b_sal = stmt.bindByName(":SAL", Fixnum)
b_hiredate = stmt.bindByName(":HIREDATE", OraDate)
対応するネイティブOCI関数: OCIBindByName
OCIStmt#execute(svc [, iters [, mode]])文と指定されたサービス・コンテキスト・ハンドルのもとで実行します。
実行する回数を指定します。
select 文に対して、OCIStmt#defineByPosで定義してないカラムがあり、 正の値のとき、例外が起こります。0 のときは例外が起こります。どちらにし ても、OCIStmt#fetchを呼ぶ前にはすべてのカラムが定義してないといけ ません。
非select文に対しては正の値を指定してください。
デフォルト値は、select 文に対しては 0, それ以外は 1 です。
note: 現在の実装は配列のフェッチやバッチモードをサポートしていません。 したがって有効な値は 0 か 1 です。
OCI_DEFAULT, OCI_BATCH_ERRORS, OCI_COMMIT_ON_SUCCESS, OCI_DESCRIBE_ONLY, OCI_EXACT_FETCH, OCI_PARSE_ONLY, これらの任意の組み合わせ、もしくは OCI_STMT_SCROLLABLE_READONLY. デフォルト値はOCI_DEFAULTです。
OCI_BATCH_ERRORSとOCI_STMT_SCROLLABLE_READONLYは現在の実行では サポートされていません。
対応するネイティブOCI関数: OCIStmtExecute
OCIStmt#fetch([nrows [, orientation [, mode]]])select 文より選択結果を取り出します。 選択された値は前もって定義した定義ハンドル に設定されます。
フェッチする行数を指定します。0 の場合、カーソルが取り消されます。 デフォルト値は 1 です。
配列のフェッチがサポートされてないので、有効な値は 0 と 1 のみです。
対応するネイティブOCI関数: OCIStmtFetch
OCIStmt#paramGet(position)実行された select 文のカラム情報を取得します。 カラムタイブが不明なテーブルの selectを参考してください。
対応するネイティブOCI関数: OCIParamGet
定義ハンドル。OCIStmt#defineByPos により生成され、SELECT 文から値を得るには このハンドルを経由します。
親クラス: OCIHandle
対応するネイティブOCIデータタイプ: OCIDefine
OCIDefine#get()SELECT された値を得ます。
対応するネイティブOCI関数: なし
バインドハンドル。OCIStmt#bindByPos や OCIStmt#bindByName により生成されます。
親クラス: OCIHandle
対応するネイティブOCIデータタイプ: OCIBind
OCIBind#get()OCI コールのよって設定されたバインド値を取得します。
対応するネイティブOCI関数: なし
OCIBind#set(value)OCI コール経由でオラクルにわたすバインド値を設定します。
対応するネイティブOCI関数: なし
記述ハンドル。明示的な記述を行うときに使用されます。
親クラス: OCIHandle
対応するネイティブOCIデータタイプ: OCIDescribe
例:
dsc = env.alloc(OCIDescribe) dsc.describeAny(svc, "EMP", OCI_PTYPE_TABLE) parm = dsc.attrGet(OCI_ATTR_PARAM) ...get various information from parm...
このクラス経由で OCISvcCtx より OCIParam を取得する。
OCIDescribe#describeAny(svc, name, type)オラクルのスキーマオブジェクト、たとえば、テーブル、ビュー、シノニム、 プロシージャ、ファンクション、パッケージ、シーケンス等のさまざまな情 報を得る。使い方はOCIDescribeを参照してください。
対応するネイティブOCI関数: OCIDescribeAny
注意: Linux 版の Oracle 8.0.5 でこのメソッドを使用するときは、 OCIEnv.create を OCI_OBJECT 付きで呼んでください。さもないと segmentation fault が起きます。このバグは 8.0.6 以降で修正されています。
OCI 記述子の抽象クラス
OCIDescriptor#attrGet(type)ハンドル及び記述子の属性 を参照。
OCIDescriptor#free()super class: OCIDescriptor
OCIError#code()OCIError#codes()OCIError#message()OCIError#messages()OCIError#parseErrorOffset()OCIError#sql()date and time between 4712 B.C. and 9999 A.D.
OraDate.new([year [, month [, day [, hour [, min [,sec]]]]]])OraDate.now()OraDate#to_s()OraDate#to_a()OraDate#yearOraDate#monthOraDate#dayOraDate#hourOraDate#minuteOraDate#secondOraDate#trunc()This is not a numeric class, so algebra operations and setter methods are not permitted, but a place to hold fetched date from Oracle server.
In fact as matter, this is a test class to check the algorithm to convert Oracle internal number format to Ruby's number, which is internally used by, for example, OCIStmt#attrGet(OCI_ATTR_MIN).
OraNumber.new()OraNumber#to_i()OraNumber#to_f()OraNumber#to_s()属性を設定するには、OCIHandle#attrSet もしくは OCIDescriptor#attrSet を、 属性値を得るには、OCIHandle#attrGet もしくは OCIDescriptor#attrGet を使用してください。
詳細は "Oracle Call Interfaceプログラマーズ・ガイド" を見てください。マニュアルを持ってない場合は、 OTN Japan から PDF ドキュメントを取得できます。
OCIStmt より現在のカーソル位置の ROWID を得る。 この仕様はまだ FIX していません。 ROWID サポートを参照のこと。
(Oracle 9i or later.)
OCIStmt よりステートメントの種類を取得する。
戻り値は OCI_STMT_SELECT, OCI_STMT_UPDATE, OCI_STMT_DELETE, OCI_STMT_INSERT, OCI_STMT_CREATE OCI_STMT_DROP, OCI_STMT_ALTER, OCI_STMT_BEGIN, OCI_STMT_DECLARE のどれか。
get or set the maxinum number of characters from OCIDefine or OCIBind, rather than the number of bytes.
Don't set larger number than previous one.
(Oracle 9i or later?)
get whether the type of length semantics from OCIParam of column. If true, in characters. If false, in bytes.
(Oracle 9i or later?)
get the maximum size of the column, argument and so on in characters form OCIParam. To get in bytes, use OCI_ATTR_DATA_SIZE.
(Oracle 9i or later?)
select 文を実行して、結果を得るには、OCIStmt#defineByPos を実行 して取得するデータの種類を定義する必要があります。select した結果は、 カラムを定義した時に得られる定義ハンドルでもって知るこ とができます。
require 'oci8'
# 環境ハンドル作成
env = OCIEnv.create()
# オラクルへログオン
svc = env.logon("SCOTT", "TIGER", nil)
# 文ハンドルの準備
stmt = env.alloc(OCIStmt)
stmt.prepare("SELECT TO_CHAR(SYSDATE, 'YYYY/MM/DD') FROM DUAL")
# 一番目のカラムを 幅 10文字の String として定義
col1 = stmt.defineByPos(1, String, 10)
# svc の元で一回実行
stmt.execute(svc, 1)
# 定義ハンドルより結果を取得。
p col1.get()
# 文ハンドルを解放
stmt.free()
# ログオフ
svc.logoff()
OCIStmt#defineByPos の第二引数に指定できるのは、以下の7種です。
String を指定したときは、さらに長さの指定が必要です。
例
stmt.defineByPos(1, String, 100) stmt.defineByPos(2, Fixnum) stmt.defineByPos(3, Integer) stmt.defineByPos(4, Float) stmt.defineByPos(5, Time) stmt.defineByPos(6, OraDate) stmt.defineByPos(7, OraNumber)
一行以上の行を取得するには、OCIStmt#fetch を使用します。
OCIStmt#fetch はデータが取得できたときは事前に OCIStmt#defineByPos で定義した定義ハンドルの配列 を返します。データが終わりのときは nil を返します。
require 'oci8'
# 環境ハンドル作成
env = OCIEnv.create()
# オラクルへログオン
svc = env.logon("SCOTT", "TIGER", nil)
# 文ハンドルの準備
stmt = env.alloc(OCIStmt)
stmt.prepare("SELECT ename, sal FROM emp")
stmt.defineByPos(1, String, 10)
stmt.defineByPos(2, Fixnum)
# svc の元で実行。fetch を使うときは、第二引数は不要。
stmt.execute(svc)
# fetch を繰り返す。
while result = stmt.fetch()
p result[0].get() # 1番目のカラム
p result[1].get() # 2番目のカラム
end
# 文ハンドルを解放
stmt.free()
# ログオフ
svc.logoff()
select 文で返されるデータの数とデータタイプは 読み取り専用パラメータ記述子を経由して動的に知ることが できます。
あとは、動的に得たデータタイプも元に、select 結果のデータタイプを定義 すれば、結果を得ることができます。
require 'oci8'
env = OCIEnv.create()
svc = env.logon("SCOTT", "TIGER", nil)
stmt = env.alloc(OCIStmt)
stmt.prepare("SELECT * FROM emp")
stmt.execute(svc)
# select 文を実行したあとに、
# 1 からパラメータの数までループを回す。
num_of_columns = stmt.attrGet(OCI_ATTR_PARAM_COUNT)
1.upto(num_of_columns) do |i|
# i 番目の読み取り専用パラメータ記述子を得る。
parm = stmt.paramGet(i)
# 各パラメータを得る。
name = parm.attrGet(OCI_ATTR_NAME)
datatype = parm.attrGet(OCI_ATTR_DATA_TYPE)
datasize = parm.attrGet(OCI_ATTR_DATA_SIZE)
scale = parm.attrGet(OCI_ATTR_SCALE)
precision = parm.attrGet(OCI_ATTR_PRECISION)
# datatype 毎に、カラム定義の種類を変える。
case datatype
when OCI_TYPECODE_VARCHAR
stmt.defineByPos(i, String, datasize)
when OCI_TYPECODE_CHAR
stmt.defineByPos(i, String, datasize)
when OCI_TYPECODE_RAW
stmt.defineByPos(i, OCI_TYPECODE_RAW, datasize)
when OCI_TYPECODE_NUMBER
if scale == 0
# 整数の場合
if precision <= 9 # Fixnum の精度 (31 ビットと仮定)
stmt.defineByPos(i, Fixnum)
else
stmt.defineByPos(i, Integer)
end
else
# 小数点以下がある場合
if precision < 15 # Float の精度
stmt.defineByPos(i, Float)
else
stmt.defineByPos(i, OraNumber)
end
end
when OCI_TYPECODE_DATE
stmt.defineByPos(i, OraDate)
# or stmt.defineByPos(i, Time)
else
raise "unsupported datatype: #{datatype}"
end
print(", ") if i != 1
print(name)
end
print("\n")
while result = stmt.fetch()
# OCI は 1 から数え、配列は 0 から数える。
0.upto(num_of_columns - 1) do |i|
print(", ") if i != 0
print(result[i].get())
end
print("\n")
end
stmt.free()
svc.logoff()
バインド変数からの値の取得および設定は、バインド・ハンドル 経由で行います。バインド・ハンドルの使用方法は値の set が可能なことを 除いて定義ハンドルと同じです。
stmt = env.alloc(OCIStmt)
stmt.prepare("SELECT sal FROM emp WHARE ename = :1")
stmt.defineByPos(1, Fixnum)
stmt.bindByPos(1, String, 20).set("SMITH")
stmt.execute(svc)
stmt = env.alloc(OCIStmt)
stmt.prepare("SELECT sal FROM emp WHARE ename = :ename")
stmt.defineByPos(1, Fixnum)
stmt.bindByName(":ename", String, 20).set("SMITH")
stmt.execute(svc)
準備済み文ハンドルに対して、バインド・ハンドルに値を設定して実行を繰り返 すこともできます。
例:
stmt.prepare("INSERT INTO emp(ename, sal) VALUES(:ename, :sal)")
bind_ename = stmt.bindByName(":ename", String, 20)
bind_sal = stmt.bindByName(":sal", Fixnum)
for line in ARVF
ename, sal = line.split(",")
bind_ename.set(ename)
bind_sal.set(sal.to_i)
stmt.execute(svc)
end
バインド・ハンドルは文ハンドルが解放されるか、再度 prepare するまで解放 されないので、ループ内でバインド・ハンドルを作成しないで下さい。
悪い例:
stmt.prepare("INSERT INTO emp(ename, sal) VALUES(:ename, :sal)")
for line in ARVF
ename, sal = line.split(",")
stmt.bindByName(":ename", String, 20).set(ename) # 悪い例
stmt.bindByName(":sal", Fixnum).set(sal.to_i) # 悪い例
stmt.execute(svc)
end
PL/SQL ブロックから値を取り出すには、バインド変数をバインドしたあと、 バインド・ハンドルより、OCIBind#get で取り出します。 バインドのやりかたは入力用と同じです。
例:
stmt.prepare("BEGIN :foo = BAR_FUNCTION(:baz); END;")
foo = stmt.bindByName(":foo", String, 30)
baz = stmt.bindByName(":baz", String, 30)
baz.set("BAZOON") # 入力用ハンドルに値を設定
stmt.execute(svc)
p foo.get() # 出力用ハンドルより値を取得
require 'oci8'
begin
env = OCIEnv.create()
svc = env.logon("SCOTT", "TIGER", nil)
stmt = env.alloc(OCIStmt)
stmt.prepare("select * from table_name_which_does_not_exist")
stmt.execute(svc)
rescue OCIError
print "Error code is " + $!.code.to_s + ".\n"
print $!.message + "\n"
offset = $!.parseErrorOffset
if ! offset.nil?
if $!.respond_to?("sql")
# Oracle 8.1.6 or later.
print "sql is: " + $!.sql + "\n"
print "error at" + " " * offset + "^here\n"
else
print "error at " + offset.to_s + "\n"
end
end
ensure
stmt.free() if ! stmt.nil?
svc.logoff() if ! svc.nil?
env.free if ! env.nil?
end
require 'oci8' username = "SYS" password = "CHANGE_ON_INSTALL" dbname = nil privilege = OCI_SYSDBA env = OCIEnv.create() srv = env.alloc(OCIServer) srv.attach(dbname) svc = env.alloc(OCISvcCtx) svc.attrSet(OCI_ATTR_SERVER, srv) auth = env.alloc(OCISession) auth.attrSet(OCI_ATTR_USERNAME, username) auth.attrSet(OCI_ATTR_PASSWORD, password) auth.begin(svc, OCI_CRED_RDBMS, privilege) svc.attrSet(OCI_ATTR_SESSION, auth) ... do SYSDBA jobs ... auth.end(svc) srv.detach() svc.free() env.free()
ROWID記述子(OCIRowid)を追加したので、この節は書き直します。
シングルユーザ・シングルセッションのとき使用します。 明示的な連結(アタッチ)及び開始セッションも見てください。
例:
env = OCIEnv.create() svc = env.logon(username, password, dbname)
To logoff:
svc.logoff()
複数のセッション・複数の接続を使用するとき、または、 SYSDBA権限、SYSOPER権限が必要なときに使用します。 単純化されたログインも見てください。
For example:
# connect as SYSDBA env = OCIEnv.create() svc = env.alloc(OCISvcCtx) srv = env.alloc(OCIServer) srv.attach(dbname) svc.attrSet(OCI_ATTR_SERVER, srv) auth = env.alloc(OCISession) auth.attrSet(OCI_ATTR_USERNAME, username) auth.attrSet(OCI_ATTR_PASSWORD, password) auth.begin(svc, OCI_CRED_RDBMS, OCI_SYSDBA) svc.attrSet(OCI_ATTR_SESSION, auth)
To logoff:
srv.detach() auth.end(svc) svc.free()