1<?xml version="1.0" encoding="UTF-8"?> 2<section id="oracle"><title>&oracle-link; Interface</title> 3<para> 4The &oracle-link; module allows a &clisp; program to act as client to an 5&oracle-link; database server. The module includes full 6SQL support, transactions (including auto-commit), support for most 7&oracle-link; data types (<type>LONG</type>, <type>BLOB</type>, 8<type>CLOB</type>, <type>RAW</type>, etc.), automatic conversion 9between &oracle-link; and &cl; data types, database connection caching and 10retry, concurrent connections to multiple databases, proper handling 11of &oracle-link; errors, and more.</para> 12<para>The module can be used to build sophisticated &oracle-link; database 13applications in &cl;.</para> 14<simpara>When this module is present, &features-my; contains the 15 symbol <constant>:ORACLE</constant>.</simpara> 16 17<section id="ora-functionality"><title>Functions and Macros in 18 package <quote role="package">ORACLE</quote></title> 19<para>Access to &oracle-link; is via these functions and macros in 20package <quote role="package">ORACLE</quote>. 21When any &oracle-link; function fails, the general Lisp function 22&error; is called, with the condition string set to 23include the &oracle-link; error number, the &oracle-link; message text, 24and other context of the error (e.g., the text and parse location of a 25SQL query).</para> 26 27<!-- List of functions an macros --> 28<variablelist> 29 30 <!-- CONNECT --> 31 32<varlistentry id="ora-connect"><term><code>(ORACLE:CONNECT 33&user-r; &pass-r; 34<replaceable>server</replaceable> 35&optional-amp; 36<replaceable>schema</replaceable> 37<replaceable>auto-commit</replaceable> 38<replaceable>prefetch-buffer-bytes</replaceable> 39<replaceable>long-len</replaceable> 40<replaceable>truncate-ok</replaceable>)</code></term> 41<listitem> 42<simpara> 43 44Connect to an &oracle-link; database. All subsequent operations will affect 45this database until the next call to &ora-connect;. A 46single program can access different &oracle-link; schemas concurrently by 47repeated calls to &ora-connect;. Database connections 48are cached and re-used: if you call &ora-connect; again 49with the same &user-r;, 50<replaceable>schema</replaceable>, and 51<replaceable>server</replaceable>, the previous &oracle-link; connection will 52be re-used. &ora-connect; may not be called inside 53<function>WITH-TRANSACTION</function>. 54 55Returns: &t; if a cached connection was re-used, &nil; if a new 56connection was created (and cached). 57 58The meaning of the arguments is as follows: 59</simpara> 60<variablelist><title>Arguments for &ora-connect;</title> 61<varlistentry><term>&user-r;</term> 62 <listitem><simpara>&oracle-link; user ID</simpara></listitem></varlistentry> 63<varlistentry><term>&pass-r;</term> 64 <listitem><simpara>Password for user, or &nil; if 65 &user-r; has no password (!). 66</simpara></listitem></varlistentry> 67<varlistentry><term><replaceable>server</replaceable></term> 68 <listitem><simpara>&oracle-link; server ID (SID). 69</simpara></listitem></varlistentry> 70<varlistentry><term><replaceable>schema</replaceable></term> 71 <listitem><simpara>&oracle-link; default schema (default: &nil;). 72 If &nil;, same as user. This allows you to log on with one user's 73 id/password but see the database as if you were some other user. 74</simpara></listitem></varlistentry> 75<varlistentry><term><replaceable>auto-commit</replaceable></term> 76 <listitem><simpara>Flag: whether to commit after every operation 77 (default: &t;). Set this to &nil; if you intend to do transactions 78 and call <function>COMMIT</function> explicitly. However, 79 <function>WITH-TRANSACTION</function> is probably easier. 80</simpara></listitem></varlistentry> 81<varlistentry><term><replaceable>prefetch-buffer-bytes</replaceable></term> 82 <listitem><simpara>Number of bytes to cache from SQL SELECT fetches 83 (default: 64 Kbytes) If you are very short of memory, or have a slow 84 connection to &oracle-link;, you can reduce this to 10k or so. 85 Alternatively, if you have a fast connection to &oracle-link; and 86 regularly do large queries, you can increase throughput by increasing 87 this value.</simpara></listitem></varlistentry> 88 89<varlistentry><term><replaceable>long-len</replaceable></term> 90 <listitem><simpara>Number of bytes to fetch for "long" (LONG, [BC]LOB) 91 types. Long data that exceeds this size will raise an error, or be 92 truncated depending on the value of <replaceable>truncate-ok</replaceable> 93 (below). Setting <replaceable>long-len</replaceable> to zero and 94 <replaceable>truncate-ok</replaceable> to &nil; will disable long 95 fetching entirely. If <replaceable>long-len</replaceable> is &nil; 96 or negative, defaults to 500k bytes.</simpara></listitem></varlistentry> 97 98<varlistentry><term><replaceable>truncate-ok</replaceable></term> 99 <listitem><simpara>Flag: if set, allow truncation of LONG columns to 100 <replaceable>long-len</replaceable> bytes on fetch; otherwise, fetches 101 of LONG columns exceeding <replaceable>long-len</replaceable> bytes 102 will raise an error. Default: &nil;.</simpara></listitem></varlistentry> 103</variablelist></listitem></varlistentry> 104 105 <!-- DISCONNECT --> 106 107<varlistentry id="ora-disconnect"><term><code>(ORACLE:DISCONNECT)</code></term> 108<listitem> 109<simpara> 110Disconnect from the database currently connected. No more calls can 111be made until &ora-connect; is called again. The 112connection is closed and removed from the connection cache. Does 113nothing if there is no connection. <function>DISCONNECT</function> 114may not be called inside <function>WITH-TRANSACTION</function>. 115Returns &nil;. 116</simpara></listitem></varlistentry> 117 118 119 <!-- RUN-SQL --> 120 121<varlistentry id="ora-run-sql"><term><code>(ORACLE:RUN-SQL 122<replaceable>sql</replaceable> 123&optional-amp; 124<replaceable>params</replaceable> 125<replaceable>is-select</replaceable>)</code></term> 126<listitem> 127<simpara>Execute a SQL statement. Must be &ora-connect;ed 128to a database. Returns the number of rows affected by the SQL operation, 129for non-SELECT statements, zero for SELECT statements. For 130destructive database operations (INSERT, UPDATE, DELETE), the results 131are committed to the database immediately if 132<replaceable>auto-commit</replaceable> when establishing the current 133connection; see &ora-connect;. The meaning of the 134arguments is as follows: </simpara> 135<variablelist><title>Arguments for <function>RUN-SQL</function></title> 136<varlistentry><term><replaceable>sql</replaceable></term> 137 <listitem><simpara>Text of SQL statement, as a string. 138 The <replaceable>sql</replaceable> statement may contain 139 &oracle-link; "named parameters," e.g. ":myparam" whose values will 140 be substituted from the parameters given 141 in <replaceable>params</replaceable>. 142</simpara></listitem></varlistentry> 143<varlistentry><term><replaceable>params</replaceable></term> 144 <listitem><simpara>A mapping of the names of the bind-parameters in the 145 query to their values. The set of named parameters in the query must 146 match exactly the keys mapped by <replaceable>params</replaceable>. 147 The mapping may be passed as either (1) a hash table whose keys are 148 the named parameters or (2) a list of pairs, ((name value) (name 149 value) ...). Parameter values passed from Lisp are converted to the 150 appropriate &oracle-link; data types (see <function>FETCH</function>). 151</simpara></listitem></varlistentry> 152<varlistentry><term><replaceable>is-select</replaceable></term> 153 <listitem><simpara>Flag: whether the statement is a SELECT query. You 154 usually do not need to set this as it is detected by default based on 155 the SQL text. However, there are situations, such as when a SELECT 156 query begins with comment, that you need to specify it explicitly. 157</simpara></listitem></varlistentry></variablelist></listitem></varlistentry> 158 159 <!-- DO-ROWS --> 160 161<varlistentry id="ora-do-rows"><term><code>(ORACLE:DO-ROWS 162<replaceable>vars</replaceable> &body-amp; &body-r;)</code></term> 163 <listitem><simpara> Macro which loops over a SQL SELECT result, 164 evaluating, for each row in the result, the forms in &body-r;, 165 binding symbols given in <replaceable>vars</replaceable> to 166 corresponding database columns in the SELECT result. The 167 argument <replaceable>vars</replaceable> must be a non-empty list of 168 symbols matching a subset of the columns of an active SELECT query. 169 If a SELECT column is an &oracle-link; expression such as 170 <literal>SUBSTR(mycol, 1, 10)</literal>, it is recommended to use a 171 column alias, e.g., <literal>SELECT SUBSTR(mycol, 1, 10) AS 172 myvar</literal>, in which case the column alias will be used as the 173 symbol bound to the column value.</simpara> 174 <simpara>As <function>DO-ROWS</function> expands into a &do-star; 175 loop, it may be terminated prematurely, before all rows are fetched, 176 by using &return; anywhere in &body-r;.</simpara> 177 <simpara>It is allowed to call &ora-connect; in the 178 &body-r; of the loop, but only to switch the connection to a database 179 other than the one that was used to do the SELECT. This is useful 180 for reading from one database while writing to another. 181 </simpara> 182 <simpara>In <replaceable>vars</replaceable>, instead of a single 183 symbol, a pair (<replaceable>bound-var</replaceable> 184 <replaceable>"column-name"</replaceable>) may be specified, which 185 will cause values from the SELECTed column or alias , 186 <replaceable>column-name</replaceable>, to be bound to Lisp variable, 187 <replaceable>bound-var</replaceable>. This is for unusual cases 188 where a Lisp variable cannot be created with the same name as the 189 column (e.g., a column named "T"), or when it is inconvenient or 190 impossible to alias the column with <literal>SELECT ... AS</literal>. 191</simpara></listitem></varlistentry> 192 193 <!-- FETCH --> 194<varlistentry id="ora-fetch"><term><code>(ORACLE:FETCH 195 &optional-amp; &res-type-r;)</code></term> 196 <listitem><para>Fetch a single row of data. Returns a row of values 197 corresponding to the columns of an active SELECT statment. The row 198 data is returned in one of three different forms, depending on the 199 value of the symbol &res-type-r;: 200<variablelist><title>Return values for <function>FETCH</function></title> 201 <varlistentry><term><classname>ARRAY</classname></term> 202 <listitem><simpara>Values will be returned in an &array-t; with the 203 same number of columns as in the SELECT statement, in the same 204 order. This is the default.</simpara></listitem></varlistentry> 205 <varlistentry><term><classname>PAIRS</classname></term> 206 <listitem><simpara>A list of pairs, <literal>((column, value) 207 ...)</literal> is be returned. The number and order of pairs is 208 the same as the columns in the SELECT statement. 209 </simpara></listitem></varlistentry> 210 <varlistentry><term><classname>HASH</classname></term> 211 <listitem><simpara>A &hash-table-t; whose keys are the column names 212 and whose values are the column values in the row. The SELECT 213 columns <emphasis>must be unique</emphasis> and be valid Lisp 214 symbols to use this option. If you are SELECTing an expression, you 215 probably want to use a column alias: <literal>SELECT <expr> AS 216 some_alias ...</literal></simpara></listitem></varlistentry> 217</variablelist></para> 218<para>The following data type conversions are done between &oracle-link; 219 datatypes and &cl; data types: 220 <informaltable id="ora-fetch-data-types-tab" frame="all"><tgroup cols="2"> 221 <thead><row><entry>&oracle-link; type</entry> 222 <entry>Converts to/from &cl; type</entry></row></thead> 223 <tbody><row><entry>Numeric (NUMBER, INTEGER, FLOAT)</entry> 224 <entry>The appropriate &cl; numeric type (&fixnum-t;, &bignum-t;, 225 &float-t;)</entry></row> 226 <row><entry>String (CHAR, VARCHAR, VARCHAR2)</entry> 227 <entry>A &cl; &string-t;. Note that CHAR will be padded out to its 228 full, fixed length as defined in &oracle-link;; VARCHAR will be a 229 string of variable length. Also note that &oracle-link; has no 230 "zero-length string" value - it returns the SQL special value 231 &c-NULL; which is converted to &nil; (see below).</entry></row> 232 <row><entry>DATE</entry> 233 <entry>A string of the form "YYYY-MM-DD HH:MM:SS" where HH is 234 24-hour form. If you want dates formatted differently, convert 235 them to strings in &oracle-link; using <literal>SELECT 236 TO_CHAR(mydate, '<replaceable>template</replaceable>') AS 237 mydate</literal>; the result will then be returned as a string, 238 formatted as per <replaceable>template</replaceable>.</entry></row> 239 <row><entry>RAW, LONG RAW</entry> 240 <entry>A hexadecimal string, with two hex digits for each byte of 241 &oracle-link; data. Note that this means the Lisp string will be 242 twice the size, in bytes, as the &oracle-link; data.</entry></row> 243 <row><entry>"Large" types (LONG, BLOB, CLOB)</entry> 244 <entry>A Lisp string of (arbitrary, possibly binary) data. Note 245 that truncation may occur; see the &ora-connect; 246 parameters <replaceable>long-len</replaceable> 247 and <replaceable>truncate-ok</replaceable>.</entry></row> 248 <row><entry>&c-NULL;</entry> 249 <entry>The &cl; value &nil;</entry></row> 250 </tbody></tgroup></informaltable> 251</para></listitem></varlistentry> 252 253 <!-- FETCH-ALL --> 254 255<varlistentry id="ora-fetch-all"><term><code>(ORACLE:FETCH-ALL 256&optional-amp; 257<replaceable>max-rows</replaceable> 258&res-type-r; 259<replaceable>item-type</replaceable>)</code></term> 260<listitem><simpara>Fetch some or all the rows from a query and return 261result as a sequence of sequences. Arguments are all optional: 262<replaceable>max-rows</replaceable> limits the result to 263that numbers of rows; 264&res-type-r; is the type of 265sequence of the rows, either 266'<classname>ARRAY</classname> (the default) or 267'<classname>LIST</classname>; 268<replaceable>item-type</replaceable> is the type of 269sequence of the column values for each row, either 270'<classname>ARRAY</classname> (the default) or 271'<classname>LIST</classname>. 272Each row fetched always contains the full set of column values SELECTed. 273</simpara> 274<simpara> 275<function>FETCH-ALL</function> is often useful in conjunction with 276<function>MAP</function> or <function>REDUCE</function> to iterate 277over an entire SELECT result to construct a single Lisp value. 278 279</simpara> 280</listitem> 281</varlistentry> 282 283 <!-- PEEK--> 284 285<varlistentry id="ora-peek"><term><code>(ORACLE:PEEK &optional-amp; 286 &res-type-r;)</code></term><listitem> 287<simpara> 288 289Peek at next row of data (without fetching it). Returns a row a la 290<function>FETCH</function>, except does not advance to the next row. 291Repeated calls to <function>PEEK</function> will thus return the same 292row of data. Returns &nil; if at EOF. If data is available, returns 293row data just as <function>FETCH</function> (see 294<function>FETCH</function> for data format and conversions done). 295Optional argument &res-type-r; is the type 296of sequence of the column values for the returned row, either 297&array-t; (the default) or &list-t;. 298<function>PEEK</function> is a useful look-ahead 299for database reporting functions that may need to "break" on changes in 300data to print headers, summaries, etc. 301</simpara></listitem></varlistentry> 302 303 <!-- COLUMNS --> 304 305<varlistentry id="ora-columns"><term><code>(ORACLE:COLUMNS)</code></term> 306<listitem><para>Returns information on the columns of a SELECT 307 result, in the form of an array of SQLCOL structures, one for each 308 result column in the most recent SELECT statement. It is not 309 necessary to have called <function>FETCH</function> before requesting 310 column information on the query, however the query must have been 311 compiled and executed with <function>RUN-SQL</function>. Each SQLCOL 312 structure has these slots: 313<variablelist><title>Slots of <classname>SQLCOL</classname></title> 314 <varlistentry><term>NAME</term> 315 <listitem><simpara>The &oracle-link; column name or the expression 316 selected. If the query used a column alias, <literal>SELECT 317 <replaceable>expr</replaceable> AS 318 <replaceable>alias</replaceable></literal>, then 319 <replaceable>alias</replaceable> will be returned as the column name. 320 </simpara></listitem></varlistentry> 321 <varlistentry><term>TYPE</term> 322 <listitem><simpara>&oracle-link; data type (VARCHAR, NUMBER, DATE, ...) 323 </simpara></listitem></varlistentry> 324 <varlistentry><term>SIZE</term> 325 <listitem><simpara>&oracle-link; data length (useful mostly for 326 character types)</simpara></listitem></varlistentry> 327 <varlistentry><term>SCALE</term> 328 <listitem><simpara>For numeric (NUMBER) types, number of digits to right of 329 decimal; NIL for FLOAT</simpara></listitem></varlistentry> 330 <varlistentry><term>PRECISION</term> 331 <listitem><simpara>For numeric types, total number of significant 332 digits (decimal digits for NUMBER, bits for FLOAT)</simpara></listitem></varlistentry> 333 <varlistentry><term>NULL_OK</term> 334 <listitem><simpara>&t; if &c-NULL;s allowed, &nil; if &c-NULL;s are 335 not allowed.</simpara></listitem></varlistentry> 336 </variablelist></para> 337 <simpara>To access the values of the SQLCOL structures, use the standard 338 accessor functions, e.g., <literal>(ORACLE:SQLCOL-NAME (elt 339 (ORACLE:COLUMNS) 0))</literal></simpara></listitem></varlistentry> 340 341 <!-- EOF --> 342 343<varlistentry id="ora-eof"><term><code>(ORACLE:EOF)</code></term> 344<listitem> 345<simpara> 346Returns EOF status. A SELECT query cursor is considered at EOF if the next 347FETCH would return no data. Must be connected to a database, and have 348an active SELECT statement. 349</simpara></listitem></varlistentry> 350 351 <!-- INSERT-ROW --> 352<varlistentry id="ora-insert-row"><term><code>(ORACLE:INSERT-ROW 353<replaceable>table</replaceable> 354<replaceable>values</replaceable>)</code></term> 355<listitem> 356<simpara> 357Inserts a single row into <replaceable>table</replaceable>. 358Second argument <replaceable>values</replaceable> is a map of 359column names to values: either a hash table whose keys are the column 360names, or a list of (name, value) pairs. Columns missing from the map 361will be given the default &oracle-link; value, or &c-NULL;. 362Returns the number of rows inserted (i.e., always 1). 363</simpara></listitem></varlistentry> 364 365 <!-- UPDATE-ROW --> 366<varlistentry id="ora-update-row"><term><code>(ORACLE:UPDATE-ROW 367<replaceable>table</replaceable> 368<replaceable>condition</replaceable> 369<replaceable>vals</replaceable> 370&optional-amp; 371<replaceable>params</replaceable>)</code></term> 372<listitem> 373<simpara> 374Updates rows in <replaceable>table</replaceable>. Second argument 375<replaceable>condition</replaceable> is a string expression for a WHERE 376clause (without the "WHERE") which determines which rows are updated. 377Third argument <replaceable>vals</replaceable> is a map of columns to 378be updated to their new values: a hash table whose keys are column 379names, or list of (name, value) pairs. Optional 380<replaceable>params</replaceable> specifies values for named 381parameters that may occur in <replaceable>condition</replaceable>, 382e.g., when the condition is a match on a primary key, e.g.: <literal>"pk_column 383= :pk_val"</literal>. Returns the number of rows updated. 384</simpara></listitem></varlistentry> 385 386 <!-- ROW-COUNT --> 387 388<varlistentry id="ora-row-count"><term><code>(ORACLE:ROW-COUNT)</code></term> 389<listitem> 390<simpara> 391For SELECT statements, returns the number of rows 392<function>FETCH</function>ed (¬-e; 393<function>PEEK</function>ed) so far. For other statements (e.g., 394INSERT, UPDATE, DELETE), returns the number of rows affected by the 395last operation (e.g., inserted, updated, deleted). Must be connected 396to a database and have an active SQL statement. 397</simpara></listitem></varlistentry> 398 399 <!-- WITH-TRANSACTION --> 400 401<varlistentry id="ora-with-transaction"><term><code>(ORACLE:WITH-TRANSACTION 402&body-amp; 403&body-r;)</code></term> 404<listitem> 405<simpara> 406 407Evaluates the forms in &body-r; atomically as a 408database transaction, ensuring that either all the database operations 409done in &body-r; complete successfully, or none 410of them do. If pending (un-committed) changes exist when this macro 411is entered, they are <emphasis>rolled back</emphasis> (undone), so 412that the database is affected only by the subsequent updates inside 413&body-r;. Nesting of 414<function>WITH-TRANSACTION</function> blocks is not allowed and will 415raise an error. There is no effect on the status of 416<replaceable>auto-commit</replaceable> given in 417&ora-connect;; it resumes its previous state when the 418macro exits. The value of the <function>WITH-TRANSACTION</function> 419expression is that of the last form in &body-r;. 420</simpara></listitem></varlistentry> 421 422 <!-- COMMIT --> 423 424<varlistentry id="ora-commit"><term><code>(ORACLE:COMMIT)</code></term> 425<listitem> 426<simpara> 427Commits (makes permanent) any pending changes to the database. The 428<replaceable>auto-commit</replaceable> parameter to 429&ora-connect; must not have been set to use this 430function, nor can it be called inside a 431<function>WITH-TRANSACTION</function> block. Always returns NIL. 432</simpara></listitem></varlistentry> 433 434 <!-- ROLLBACK --> 435 436<varlistentry id="ora-rollback"><term><code>(ORACLE:ROLLBACK)</code></term> 437<listitem> 438<simpara> 439Rolls back (undoes and abandons) any pending changes to the database. 440The <replaceable>auto-commit</replaceable> parameter to 441&ora-connect; must not have been set to use this 442function, nor can it be called inside a 443<function>WITH-TRANSACTION</function> block. Always returns NIL. 444</simpara></listitem></varlistentry> 445 446 <!-- AUTO-COMMIT --> 447 448<varlistentry id="ora-auto-commit"><term><code>(ORACLE:AUTO-COMMIT)</code></term> 449<listitem> 450<simpara> 451Toggles the state of <replaceable>auto-commit</replaceable> initially 452given to &ora-connect; for the current connection. 453With <replaceable>auto-commit</replaceable> enabled, modifications to 454the database are committed (made permanent) after each destructive SQL 455operation made with calls to <function>RUN-SQL</function>, 456<function>INSERT-ROW</function>, <function>UPDATE_ROW</function>, etc. 457With <replaceable>auto-commit</replaceable> disabled, transactional 458integrity is under the programmer's control and is managed either by 459(1) explicitly calling <function>COMMIT</function> or 460<function>ROLLBACK</function> to commit or undo the pending 461operations, or (2) wrapping code blocks with database operations 462inside the <function>WITH-TRANSACTION</function> macro. 463<function>AUTO-COMMIT</function> returns the previous status of 464<replaceable>auto-commit</replaceable>. 465<function>AUTO-COMMIT</function> may not be called inside 466<function>WITH-TRANSACTION</function>. 467</simpara></listitem></varlistentry> 468 469 470<!-- =-=-==-=-==-=-==-=-==-=-==-=-= End of functions section --> 471 472</variablelist> 473</section> 474 475<section id="ora-example"><title>&oracle-link; Example</title> 476 477<para> 478Below is a simple example script which uses &oracle-link;'s demo database 479schema, <literal>SCOTT</literal>. 480 481<programlisting language="lisp"> 482(setf server "orcl") <lineannotation>; Change this to your server's SID</lineannotation> 483(oracle:connect "scott" "tiger" server) 484 485(oracle:run-sql "SELECT deptno, dname, loc FROM dept ORDER BY DNAME") 486(oracle:do-rows (deptno dname loc) 487 (format t "Dept. no is '~A', " deptno) 488 (format t "Dept. name is '~A', " dname) 489 (format t "Dept. loc is '~A'~%" loc)) 490 491(oracle:update-row "dept" "dname = :acctval" '(("dname" "NEWACCT")) '(("acctval" "ACCOUNTING"))) 492 493(oracle:run-sql "SELECT deptno, dname, loc FROM dept ORDER BY DNAME") 494(oracle:do-rows (deptno dname loc) 495 (format t "Dept. no is '~A', " deptno) 496 (format t "Dept. name is '~A', " dname) 497 (format t "Dept. loc is '~A'~%" loc)) 498 499(oracle:update-row "dept" "dname = :acctval" '(("dname" "ACCOUNTING")) '(("acctval" "NEWACCT"))) 500</programlisting> 501</para> 502</section> 503 504 505 506 507<section id="ora-config"><title>&oracle-link; Configuration</title> 508 509<para>Obviously, a working &oracle-link; environment is required. It is 510recommended that you first be able to log on and use the &oracle-link; 511SQL*Plus application to test your environment 512&before-e; attempting &oracle-link; access via the &clisp; module. 513At a minimum you will need to set environment variables 514<envar>ORACLE_HOME</envar> to the &oracle-link; base directory and 515<envar>LD_LIBRARY_PATH</envar> to include 516<literal>$<envar>ORACLE_HOME</envar>/lib</literal> and possibly other 517directories.</para> 518 519</section> 520 521<section id="ora-build"><title>Building the &oracle-link; Interface</title> 522 523<para>The module uses the &oracle-link; Call Interface (&oracle-oci;) 524&c-lang; library. To build the module you will need the &oracle-link; 525&oracle-oci; headers and link libraries; as a quick check, make sure 526you have the file <filename>oci.h</filename> somewhere 527under <envar>ORACLE_HOME</envar>, probably 528in <filename>$<envar>ORACLE_HOME</envar>/rdbms/demo/oci.h</filename>.</para> 529 530<para>To build the module into &clisp;, configure with 531<command>./configure ... --with-module=oracle ...</command>. 532The &full; &linkset; will contain the module, 533so you will need to use the &opt-K; option to use it. 534You can test that you really have the &oracle-link;-enabled &clisp; by 535evaluating <code>(&describe; 'oracle:connect)</code>.</para> 536 537<note><para>It may be necessary to edit file 538<filename role="clisp-cvs">modules/oracle/Makefile.in</filename> 539prior to running <command>./configure</command>.</para></note> 540 541 542</section> 543 544</section> 545