oratcl — Tcl 9 interface to Oracle via ODPI-C 5.6.4
oralogon connect-string ?-pool {min max incr}?
?-homogeneous 0|1?
?-getmode wait|nowait|forceget|timedwait?
?-waittimeout ms? ?-timeout s? ?-maxlifetime s?
?-pinginterval s? ?-pingtimeout ms?
?-stmtcachesize n?
?-failovercallback proc?
oralogoff logon-handle
oraopen logon-handle # open a statement handle
orastmt logon-handle # alias of oraopen
oraclose statement-handle
oraparse statement-handle ?-novalidate? sql-text
orasql statement-handle sql-text ?-parseonly? ?-commit?
oraplexec statement-handle {pl/sql block} ?-commit?
oraexec statement-handle ?-commit?
orabind statement-handle :name value ? :name value ... ?
orabindexec statement-handle ?-commit? ?-arraydml? :name list ...
orafetch statement-handle
?-datavariable varName?
?-dataarray arrayName?
?-indexbyname|-indexbynumber?
?-command script?
?-max N?
?-resultvariable varName?
?-returnrows?
?-asdict?
oracols statement-handle
oradesc logon-handle object-name
oraconfig handle ?name ?value??
oramsg handle rc|error|rows|peo|ocicode|sqltype|fn|action|sqlstate|recoverable|warning|offset|all|allx
oralob size|read|write|trim|close lob-handle ?args...?
oraautocommit logon-handle 0|1
oracommit logon-handle
orarollback logon-handle
orabreak logon-handle # cancel active call
oraexecasync statement-handle ?-commit?
orawaitasync statement-handle ?-timeout milliseconds?
oratcl 9.1 implements the classic Oratcl API on top of ODPI-C (no OCI). It targets Tcl 9: command signatures use Tcl_Size and are thread/multi-interp safe. One ODPI context is created per process; per-interp state (handles, registries) is created on each load.
Async execution uses a persistent thread pool with reference-counted entries and a shared work queue. All operations on a physical Oracle connection are serialized through a shared per-connection gate, ensuring safe concurrent use across interpreter threads and async workers.
All commands are registered both at global scope (backward compatibility) and under the ::oratcl
namespace. Use namespace import ::oratcl::* to access the namespaced forms.
Connect using either username/password@connect_identifier, or external auth (leave user/pw empty).
Quoted passwords with backslash escapes are supported: user/"pass\"word"@db. Options:
-pool {min max incr} — Create a session pool (or acquire from an existing one) and check out the first connection.
Multiple oralogon -pool calls with identical parameters share one underlying session pool process-wide; only the first call creates the pool.
-homogeneous 0|1 — Homogeneous pool (default 1).
-getmode wait|nowait|forceget|timedwait — Pool get mode. Use -waittimeout together with timedwait.
-waittimeout ms — Maximum wait in milliseconds for an available session when -getmode timedwait is active.
-timeout s — Idle session eviction timeout in seconds.
-maxlifetime s — Maximum session lifetime in seconds.
-pinginterval s — Liveness ping interval in seconds (0 to disable).
-pingtimeout ms — Ping timeout in milliseconds.
-stmtcachesize n — Statement cache size for sessions created from this pool.
-failovercallback proc — Register a Tcl proc invoked on recoverable errors (driver-side failover). Can also be set later via oraconfig.
Returns a logon-handle (e.g. "oraL1").
Close the connection. Cancels pending async operations, releases associated LOBs and statements in phased order.
Set autocommit. DML/PLSQL commit on success when enabled or when -commit is supplied to exec commands. The change is propagated to the shared adoption record.
Return a dict with the current connection info. Currently returns autocommit only.
Open a statement handle.
Prepare a SQL statement. By default a server round-trip validates the SQL at parse time, reporting syntax errors immediately. With -novalidate the prepare is client-side only and errors surface at execute time; use this on hot paths where the SQL is known-good and the round-trip cost is measurable.
Parse and, unless -parseonly, execute once. Clears the per-statement stored-bind cache if text changes.
Execute the already-parsed statement (single execution). Supports driver-side failover with configurable retry/backoff.
Prepare and execute a PL/SQL block.
Bind scalars by name. LOB type is inferred by name suffix (_blob, _clob) and/or value representation.
Array DML with name→list pairs. String values are pinned for the duration of the executeMany call; the lists must not be modified while the call is in progress.
Fetches up to -max N rows and returns 0 while data remains, or 1403 at end-of-data. Use -returnrows or -resultvariable to obtain a list of rows; -asdict returns dicts keyed by column names.
Fetched data is deep-copied into local snapshots so that -command callbacks can safely issue other database operations (including closing the statement) without deadlock. Column names are uppercased with Unicode-aware conversion.
Return column names of the current query. Names are uppercased with Unicode-aware conversion.
Return {name type} pairs for the columns of the given table or view.
oralob read lob-handle offset amount — Read as a bytearray.
oralob write lob-handle offset data — Write data to the LOB.
oralob trim lob-handle newsize — Truncate the LOB.
oralob size lob-handle — Return the current size.
oralob close lob-handle — Release the LOB handle.
When inlineLobs is enabled at the connection, orafetch returns raw data instead of LOB handles. LOB handles reference the shared connection gate for serialized I/O.
Submit the statement for execution on a persistent worker thread pool. Failover policy fields are snapshotted at enqueue time to avoid data races. The worker holds addRef() on the underlying dpi handles and serializes through the shared connection gate.
Wait for completion or timeout. Returns 0 on success, -3123 on timeout, or the Oracle error code on execution failure. On completion, temp LOBs created by orabind are released. On timeout, the async entry is marked as orphaned; the worker self-cleans on completion.
Commit the current transaction.
Roll back the current transaction.
Cancel the currently executing call on this connection via the shared connection gate.
Return per-handle diagnostic information. Fields: rc, error, rows, peo (parse error offset), ocicode, sqltype, fn, action, sqlstate, recoverable, warning, offset, all, allx.
Use oraconfig on a logon-handle or a statement-handle. With no name/value, returns all keys; with a name only, returns that value; with name/value pairs, sets them.
Connection-level keys:
stmtcachesize, fetcharraysize, prefetchrows, calltimeout (ms),
inlineLobs (0/1), and failover policy: foMaxAttempts (capped at 1000), foBackoffMs,
foBackoffFactor, foErrorClasses (network and/or connlost),
foDebounceMs, failovercallback.
Statement-level keys:
fetchrows, prefetchrows (overrides connection default when set; 0 reverts to connection default).
Configuration changes on connections are synced to the shared adoption record so all wrappers on the same physical session remain consistent.
Basic select:
set L [oralogon "scott/tiger@//dbhost/pdb"]
set S [oraopen $L]
oraparse $S {select empno, ename from emp where deptno = :d}
orabind $S :d 10
oraexec $S
set rows {}
while 1 {
set rc [orafetch $S -asdict -datavariable row]
if {$rc == 1403} break
lappend rows [dict get $row EMPNO] [dict get $row ENAME]
}
oraclose $S
oralogoff $L
Array DML:
set S [oraopen $L]
oraparse $S {insert into t(x,y) values(:x,:y)}
orabindexec $S -commit -arraydml :x {1 2 3} :y {A B C}
Async:
oraparse $S {begin dbms_lock.sleep(2); end;}
oraexecasync $S
# do other work...
orawaitasync $S -timeout 3000
Pooled connection with failover:
set L [oralogon "scott/tiger@//dbhost/pdb" -pool {2 10 2} \
-failovercallback myFailoverHandler]
oraconfig $L foMaxAttempts 3 foBackoffMs 500 \
foBackoffFactor 2.0 foErrorClasses {network connlost}
Namespace import:
namespace import ::oratcl::*
set L [oralogon "scott/tiger@//dbhost/pdb"]
The test suite uses ORATCL_CONNECT for the connect string.
One global ODPI context is created lazily and destroyed on process exit (two-phase teardown). Each interpreter has isolated handle registries.
Connections can be adopted across interpreters: the adopter gets its own wrapper backed by the same
physical dpiConn*, serialized through a shared per-connection operation gate. Behavioral
configuration (autocommit, fetch sizes, failover policy) is synced to a shared record so adopters
inherit consistent settings.
Async execution uses a persistent thread pool. Workers hold addRef'd dpi handles and operate only through the shared gate. Teardown uses interp-scoped cancellation with finite timeouts and an orphan mechanism for workers that do not complete in time.
oratcl_SafeInit rejects loading into safe interpreters with a descriptive error.
↑ Top