Oratcl is a collection of Tcl commands and a Tcl global array that provides access to an Oracle Database Server. Each Oratcl command generally invokes several Oracle Call Interface (OCI) library functions. Programmers using Oratcl should be familar with basic concepts of OCI programming.
name
name/password
name@n:dbname
name/password@n:dbname
A logon handle is returned and should be used for all other Oratcl commands using this connection that require a logon handle. Multiple connections to the same or different servers are allowed, up to a maximum of 25 total connections. Oralogon raises a Tcl error if the connection is not made for any reason (login or password incorrect, network unavailable, etc.). If the connect string does not include a database specification, the value of the environment variable ORACLE_SID is used as the server.
The oramsg array index rowid is set with the Oracle ROWID of the last row processed in an insert, update, or delete statement.
Only a single SQL statement may be specified in sql-statement . Orafetch allows retrieval of return rows generated.
The optional -parseonly argument parses but does not execute the SQL statement. The SQL statement may contain bind variables that begin with a colon (':'). The statement may then be executed with the orabindexec command, allowing bind variables to be substituted with values. Bind variables should only be used for SQL statements select, insert, update, or delete .
The optional -async argument specifies the that SQL should be executed asynchronously. Orasql will return the numeric code "3123" when using -async. Note that -async is only available for orasql when Oratcl is compiled with Oracle 7.2 or higher libraries, and when connected to an Oracle server of version 7.2 or higher. See orapoll below.
Only -parseonly or -async may be specified.
Orasql performs an implicit oracancel if any results are still pending from the last execution of orasql. Orasql raises a Tcl error if the cursor handle specified is not open, or if the SQL statement is syntactically incorrect.
Table inserts made with orasql should follow conversion rules in the Oracle SQL Reference manual.
The optional -async argument specifies the that SQL should be executed asynchronously. Orasql will return the numeric code 3123 when using -async. If -async is specified, it must preceed any remaining :varname value pairs for the command. Note that -async is only available for orasql when Oratcl is compiled with Oracle 7.2 or higher libraries, and when connected to an Oracle server of version 7.2 or higher. See orapoll below.
Optional :varname value pairs allow substitutions on SQL bind variables before execution. As many :varname value pairs should be specified as there are defined in the previously parsed SQL statement. Varnames must be prefixed by a colon ":".
Orabindexec will return "0" when the SQL is executed successfully; "3123" when executed with the -async argument; "1003" if a previous SQL has not been parsed with orasql; "1008" if not all SQL bind variables have been specified. Refer to Oracle error numbers and messages for other possible values.
The oramsg array index rowid is set with the Oracle ROWID of the last row processed in an insert, update, or delete statement.
The optional commands argument allows orafetch to repeatedly fetch rows and execute commands for each row. Substitutions are made on commands before passing it to Tcl_Eval() for each row. An optional fourth argument consisting of a single character can be specified for a column number substitution character. If none is specified the character '@' will be used to denote the substitution character. If the substitution character is a null string, no column substitutions will be performed on the commands string. Orafetch interprets the substitution character followed by a number (@n ) in commands as a result column specification. For example, @1, @2, @3 refer to the first, second, and third columns in the result. @0 refers to the entire result row, as a Tcl list. Substitution columns may appear in any order, or more than once in the same command. Substituted columns are inserted into the commands string as proper list elements, i.e., one space will be added before and after the substitution and column values with embedded spaces are enclosed by {} if needed.
Tcl variables may also be set for commands on each row that is processed. Tcl variables are specified after the substitution_character , consisting of matching pairs of Tcl variable names and a column numbers. Column number may be "0", in which the Tcl variable is set to the entire result row as a Tcl list. Column numbers must be less than or equal to the number of columns in the SQL result set.
A Tcl error is raised if a column substitution number is greater than the number of columns in the results. If the commands execute break , orafetch execution is interrupted and returns with TCL_OK. Remaining rows may be fetched with a subsequent orafetch command. If the commands execute return or continue , the remaining commands are skipped and orafetch execution continues with the next row. Orafetch will raise a Tcl error if the commands return an error. Commands should be enclosed in "" or {}.
Oratcl performs conversions for all data types. Raw data is returned as a hexadecimal string, without a leading "0x". Use the SQL functions to force a specific conversion.
If an SQL statement has been executed in asynchrounous mode (-async argument on orasql or orabindexec ), executing orafetch will block until SQL execution is complete. See orapoll below.
The oramsg array index rc is set with the return code of the fetch. 0 indicates the row was fetched successfully; 1403 indicates the end of data was reached.
The index rows is set to the cumulative number of rows fetched so far. The oramsg array index rowid is set with the Oracle ROWID of the last row fetched when retrieved with a select for update statement.
The oramsg array index maxlong limits the amount of long or long raw data returned for each column returned. The default is 32768 bytes.
The oramsg array index nullvalue can be set to specify the value returned when a column is null. The default is "0" for numeric data, and "" for other datatypes.
The optional argument -all may be specified to return a list of all cursor handles that have results waiting.
Note that orapoll is only available when Oratcl is compiled with Oracle 7.2 or higher libraries, and when connected to an Oracle server of version 7.2 or higher.
Asynchronous processing (-async argument on orasql or orabindexec ) is actually done on a logon-connection basis. Executing orasql or orabindexec with -async causes all open cursors through the same logon connection handle to be changed to asycnchronous mode. Likewise, if orafetch is executed on a cursor, all open cursors through the same logon connection handle will be changed to blocking mode. It is recommended that asynchronous processing be limited to one cursor per logon connection to avoid unexpected changes of blocking to/from asynchronous mode for other cursors.
Note that orabreak is only available when Oratcl is compiled with Oracle 7.2 or higher libraries, and when connected to an Oracle server of version 7.2 or higher.
Cursor variables may be returned from a PL/SQL block by specifing an open cursor as the bind value for a :varname bind variable. The cursor must have previously been opened by oraopen using the same logon handle as the cursor used to execute the oraplexec command. The cursor is closed and re-opened with the results of a PL/SQL "OPEN :cursor FOR select" statement. After oraplexec completes, the cursor returned may then fetch result rows by using orafetch; column information is available by using oracols.
Note that cursor variables are only available for oraplexec when Oratcl is compiled with Oracle 7.2 or higher libraries, and when connected to an Oracle server of version 7.2 or higher.
Oraplexec returns the contents of each :varname as a Tcl list upon the termination of PL/SQL block. Oraplexec raises a Tcl error if the cursor handle specified is not open, or if the PL/SQL block is in error. The oramsg array index rc contains the return code from the stored procedure.
The oramsg array index collengths is set to a Tcl list corresponding to the lengths of the columns; index coltypes is set to a Tcl list corresponding to the types of the columns; index colprecs is set to a Tcl list corresponding to the precision of the numeric columns, other corresponding non-numeric columns are a null string (Version 7 only); index colscales is set to a Tcl list corresponding to the scale of the numeric columns, other corresponding non-numeric columns are a null string (Version 7 only). Oracols raises a Tcl error if the cursor handle specified is not open.
Orawritelong returns a decimal number upon successful completion of the number of bytes written to the LONG column. A properly formatted Rowid may be obtained through a prior execution of orasql, "select rowid from table where ..." .
Orawritelong raises a Tcl error if the cursor handle specified is not open, or if rowid, table, or column are invalid, or if the row does not exist.
Orareadlong returns a decimal number upon successful completion of the number of bytes read from the LONG column.
Orareadlong raises a Tcl error if the cursor handle specified is not open, or if rowid, table, or column are invalid, or if the row does not exist.
Oratcl creates and maintains a Tcl global array to provide feedback of Oracle server messages, named oramsg . Oramsg is also used to communicate with the Oratcl interface routines to specify null return values and LONG limits. In all cases except for nullvalue and maxlong , each element is reset to null upon invocation of any Oratcl command, and any element affected by the command is set. The oramsg array is shared among all open Oratcl handles. Oramsg should be defined with the global statement in any Tcl procedure needing access to oramsg.
Oramsg elements:
Function completed normally, without error.
"version_6" or "version_7" - reflects the Oracle version
"non_blocking" and "cursor_variables" - Oracle version 7.2+ non-blocking SQL execution and PL/SQL cursor variables.
Tcl errors can also be raised by any Oratcl command if a command's internal calls to OCI library routines fail.
Oracle is very particular about using date literals in SQL. The proper date format is 'dd-mmm-yy', where dd is a numeric day, mmm is a three character month name, yy is two digit year. Some versions of Oracle give very strange results or failures if date values are not in this format.
The limit of the number of simultaneous connections and cursors is artificial, based on a fixed table in oratcl.c. Change the source #define ORATCLLDAS or #define ORATCLCURS if more are needed.
Oratcl does not mix well with Tcl slave interpreters. If Oratcl functions are needed in a slave, set up alias commands in the slave to execute Oratcl commands in the master interpreter. See the 'interp' man page.
The maximum amount of LONG or LONG RAW data returned by orafetch is ultimately dependent on Oratcl's ability to malloc() maxlong bytes of memory for each LONG/LONG RAW column retrieved. Setting oramsg(maxlong) to too high a value may cause core dumps or memory shortages.
Orareadlong compiled for Version 7 will utilize the oflng() OCI function; otherwise, a single data allocation will be made to hold the entire data. If memory cannot be allocated, the command will fail.
Unfortunately, OCI does not provide a way to write a LONG/LONG RAW column in chunks. The entire amount of data required to perform orawritelong is allocated in a single request. Again, if memory cannot be allocated, the command will fail.
Orafetch normally caches 10 rows at a time from the Oracle server. When a query contains a LONG or LONG RAW column, single rows are retrieved from the server in order to prevent memory shortages.
Cursor variables returned by oraplexec must be specified as a currently open cursor from the same logon connection:
set lda [oralogon scott/tiger]
set exec_cur [oraopen $lda]
set fetch_cur [oraopen $lda]
set plsql { begin
open :fetchcur for select empno, ename
from emp where job = :job ;
end;
}
oraplexec $exec_cur $plsql :job ANALYST :fetchcur $fetch_cur
orafetch $fetch_cur {puts "$empno $ename"} "" empno 1 ename 2
Using SQL bind variables are more efficient than letting Oracle reparse SQL statements. Use a combination of orasql ... -parseonly / orabindexec:
set sql "insert into name_tab(first_name) values(:firstname)"rather than:
orasql $cur $sql -parseonly
foreach name [list Ted Alice John Sue] {
orabindexec $cur :firstname $name
}
foreach name [list Ted Alice John Sue] {
set sql "insert into name_tab(first_name) values('$name')"
orasql $cur $sql
}
Oracle OCI (Oracle Call Interface) libraries for Oracle release 7.1.4 may cause problems due to changes that Oracle introduced in that version. Use OCI libraries 7.0.x or 7.1.6+ if you experience symptoms of excessively long connect times (2+ minutes) or "fetch out of sequence" errors.