php-doc-en/functions/sesam.xml
Hartmut Holzgraefe 4c31e191c5 en Upgrade to DocBook4
git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@69281 c90b9560-bf6c-de11-be94-00142212c4b1
2002-02-02 15:36:11 +00:00

2010 lines
65 KiB
XML

<?xml version="1.0" encoding="iso-8859-1"?>
<!-- $Revision: 1.22 $ -->
<reference id="ref.sesam">
<title>SESAM database functions</title>
<titleabbrev>SESAM</titleabbrev>
<partintro>
<para>
SESAM/SQL-Server is a mainframe database system, developed by
Fujitsu Siemens Computers, Germany. It runs on high-end mainframe
servers using the operating system BS2000/OSD.
</para>
<para>
In numerous productive BS2000 installations, SESAM/SQL-Server has
proven ...
<itemizedlist>
<listitem>
<simpara>
the ease of use of Java-, Web- and client/server connectivity,
</simpara>
</listitem>
<listitem>
<simpara>
the capability to work with an availability of more than
99.99%,
</simpara>
</listitem>
<listitem>
<simpara>
the ability to manage tens and even hundreds of thousands of
users.
</simpara>
</listitem>
</itemizedlist>
</para>
<para>
Now there is a PHP3 SESAM interface available which allows
database operations via PHP-scripts.
</para>
<note>
<title>Configuration notes</title>
<para>
There is no standalone support for the PHP SESAM interface, it
works only as an integrated Apache module. In the Apache PHP
module, this <link linkend="ini.sect.sesam">SESAM interface is
configured</link> using Apache directives.
<table>
<title>SESAM Configuration directives</title>
<tgroup cols="2">
<thead>
<row>
<entry>Directive</entry>
<entry>Meaning</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>php3_sesam_oml</literal></entry>
<entry>
Name of BS2000 PLAM library containing the loadable SESAM
driver modules. Required for using SESAM functions.
<para>
Example:
<informalexample>
<programlisting role="apache">
<![CDATA[
php3_sesam_oml $.SYSLNK.SESAM-SQL.030
]]>
</programlisting>
</informalexample>
</para>
</entry>
</row>
<row>
<entry><literal>php3_sesam_configfile</literal></entry>
<entry>
Name of SESAM application configuration file. Required for
using SESAM functions.
<para>
Example:
<informalexample>
<programlisting role="apache">
<![CDATA[
php3_sesam_configfile $SESAM.SESAM.CONF.AW
]]>
</programlisting>
</informalexample>
It will usually contain a configuration like (see SESAM
reference manual):
<informalexample>
<programlisting role="bs2000">
<![CDATA[
CNF=B
NAM=K
NOTYPE
]]>
</programlisting>
</informalexample>
</para>
</entry>
</row>
<row>
<entry><literal>php3_sesam_messagecatalog</literal></entry>
<entry>
Name of SESAM message catalog file. In most cases, this
directive is not neccessary. Only if the SESAM message file
is not installed in the system's BS2000 message file table,
it can be set with this directive.
<para>
Example:
<informalexample>
<programlisting role="apache">
<![CDATA[
php3_sesam_messagecatalog $.SYSMES.SESAM-SQL.030
]]>
</programlisting>
</informalexample>
</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
In addition to the configuration of the PHP/SESAM interface, you
have to configure the SESAM-Database server itself on your
mainframe as usual. That means:
<itemizedlist>
<listitem>
<simpara>
starting the SESAM database handler (DBH), and
</simpara>
</listitem>
<listitem>
<simpara>
connecting the databases with the SESAM database handler
</simpara>
</listitem>
</itemizedlist>
</para>
<para>
To get a connection between a PHP script and the database
handler, the <literal>CNF</literal> and <literal>NAM</literal>
parameters of the selected SESAM configuration file must match
the id of the started database handler.
</para>
<para>
In case of distributed databases you have to start a
SESAM/SQL-DCN agent with the distribution table including the
host and database names.
</para>
<para>
The communication between PHP (running in the POSIX subsystem)
and the database handler (running outside the POSIX subsystem) is
realized by a special driver module called SQLSCI and SESAM
connection modules using common memory. Because of the common
memory access, and because PHP is a static part of the web
server, database accesses are very fast, as they do not require
remote accesses via ODBC, JDBC or UTM.
</para>
<para>
Only a small stub loader (SESMOD) is linked with PHP, and the
SESAM connection modules are pulled in from SESAM's OML PLAM
library. In the <link
linkend="ini.sect.sesam">configuration</link>, you must tell PHP
the name of this PLAM library, and the file link to use for the
SESAM configuration file (As of SESAM V3.0, SQLSCI is available
in the SESAM Tool Library, which is part of the standard
distribution).
</para>
<para>
Because the SQL command quoting for single quotes uses duplicated
single quotes (as opposed to a single quote preceded by a
backslash, used in some other databases), it is advisable to set
the PHP configuration directives <link
linkend="ini.magic-quotes-gpc"><literal>php3_magic_quotes_gpc</literal></link>
and <link
linkend="ini.magic-quotes-sybase"><literal>php3_magic_quotes_sybase</literal></link>
to <literal>On</literal> for all PHP scripts using the SESAM
interface.
</para>
</note>
<note>
<title>Runtime considerations</title>
<para>
Because of limitations of the BS2000 process model, the driver
can be loaded only after the Apache server has forked off its
server child processes. This will slightly slow down the initial
SESAM request of each child, but subsequent accesses will respond
at full speed.
</para>
<para>
When explicitly defining a Message Catalog for SESAM, that
catalog will be loaded each time the driver is loaded (i.e., at
the initial SESAM request). The BS2000 operating system prints a
message after successful load of the message catalog, which will
be sent to Apache's error_log file. BS2000 currently does not
allow suppression of this message, it will slowly fill up the
log.
</para>
<para>
Make sure that the SESAM OML PLAM library and SESAM configuration
file are readable by the user id running the web server.
Otherwise, the server will be unable to load the driver, and will
not allow to call any SESAM functions. Also, access to the
database must be granted to the user id under which the Apache
server is running. Otherwise, connections to the SESAM database
handler will fail.
</para>
</note>
<note>
<title>Cursor Types</title>
<para>
The result cursors which are allocated for SQL "select type"
queries can be either "sequential" or "scrollable". Because of
the larger memory overhead needed by "scrollable" cursors, the
default is "sequential".
</para>
<para>
When using "scrollable" cursors, the cursor can be freely
positioned on the result set. For each "scrollable" query, there
are global default values for the scrolling type (initialized to:
<literal>SESAM_SEEK_NEXT</literal>) and the scrolling offset
which can either be set once by
<function>sesam_seek_row</function> or each time when fetching a
row using <function>sesam_fetch_row</function>. When fetching a
row using a "scrollable" cursor, the following post-processing is
done for the global default values for the scrolling type and
scrolling offset:
<table>
<title>Scrolled Cursor Post-Processing</title>
<tgroup cols="2">
<thead>
<row>
<entry>Scroll Type</entry>
<entry>Action</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>SESAM_SEEK_NEXT</literal></entry>
<entry>none</entry>
</row>
<row>
<entry><literal>SESAM_SEEK_PRIOR</literal></entry>
<entry>none</entry>
</row>
<row>
<entry><literal>SESAM_SEEK_FIRST</literal></entry>
<entry>
set scroll type to <literal>SESAM_SEEK_NEXT</literal>
</entry>
</row>
<row>
<entry><literal>SESAM_SEEK_LAST</literal></entry>
<entry>
set scroll type to <literal>SESAM_SEEK_PRIOR</literal>
</entry>
</row>
<row>
<entry><literal>SESAM_SEEK_ABSOLUTE</literal></entry>
<entry>Auto-Increment internal offset value</entry>
</row>
<row>
<entry><literal>SESAM_SEEK_RELATIVE</literal></entry>
<entry>none. (maintain global default
<parameter>
offset</parameter> value, which allows for, e.g., fetching
each 10th row backwards)
</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
</note>
<note>
<title>
Porting note
</title>
<para>
Because in the PHP world it is natural to start indexes at zero
(rather than 1), some adaptions have been made to the SESAM
interface: whenever an indexed array is starting with index 1 in
the native SESAM interface, the PHP interface uses index 0 as a
starting point. E.g., when retrieving columns with
<function>sesam_fetch_row</function>, the first column has the
index 0, and the subsequent columns have indexes up to (but not
including) the column count ($array["count"]). When porting
SESAM applications from other high level languages to PHP, be
aware of this changed interface. Where appropriate, the
description of the respective php sesam functions include a note
that the index is zero based.
</para>
</note>
<note>
<title>Security concerns</title>
<para>
When allowing access to the SESAM databases, the web server user
should only have as little privileges as possible. For most
databases, only read access privilege should be granted.
Depending on your usage scenario, add more access rights as you
see fit. Never allow full control to any database for any user
from the 'net! Restrict access to php scripts which must
administer the database by using password control and/or SSL
security.
</para>
</note>
<note>
<title>Migration from other SQL databases</title>
<para>
No two SQL dialects are ever 100% compatible. When porting
SQL applications from other database interfaces to SESAM,
some adaption may be required. The following typical
differences should be noted:
<itemizedlist>
<listitem>
<simpara>Vendor specific data types</simpara>
<simpara>
Some vendor specific data types may have to be replaced by
standard SQL data types (e.g., <literal>TEXT</literal> could
be replaced by <literal>VARCHAR(max. size)</literal>).
</simpara>
</listitem>
<listitem>
<simpara>Keywords as SQL identifiers</simpara>
<simpara>
In SESAM (as in standard SQL), such identifiers must be
enclosed in double quotes (or renamed).
</simpara>
</listitem>
<listitem>
<simpara>
Display length in data types
</simpara>
<simpara>
SESAM data types have a precision, not a display
length. Instead of <literal>int(4)</literal> (intended use:
integers up to '9999'), SESAM requires simply
<literal>int</literal> for an implied size of 31 bits. Also,
the only datetime data types available in SESAM are:
<literal>DATE</literal>, <literal>TIME(3)</literal> and
<literal>TIMESTAMP(3)</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
SQL types with vendor-specific <literal>unsigned</literal>,
<literal>zerofill</literal>, or
<literal>auto_increment</literal> attributes
</simpara>
<simpara>
<literal>Unsigned</literal> and<literal> zerofill</literal>
are not supported. <literal>Auto_increment</literal> is
automatic (use <literal>"INSERT ... VALUES(*, ...)"</literal>
instead of <literal>"... VALUES(0, ...)"</literal> to take
advantage of SESAM-implied auto-increment.
</simpara>
</listitem>
<listitem>
<simpara>
<command>int ... DEFAULT '0000'</command>
</simpara>
<simpara>
Numeric variables must not be initialized with string
constants. Use <command>DEFAULT 0</command> instead. To
initialize variables of the datetime SQL data types, the
initialization string must be prefixed with the respective
type keyword, as in: <literal> CREATE TABLE exmpl ( xtime
timestamp(3) DEFAULT TIMESTAMP '1970-01-01 00:00:00.000' NOT
&null; ); </literal>
</simpara>
</listitem>
<listitem>
<simpara>
<command>$count = xxxx_num_rows();</command>
</simpara>
<simpara>
Some databases promise to guess/estimate the number of the
rows in a query result, even though the returned value is
grossly incorrect. SESAM does not know the number of rows in
a query result before actually fetching them. If you REALLY
need the count, try <command>SELECT COUNT(...) WHERE
...</command>, it will tell you the number of hits. A second
query will (hopefully) return the results.
</simpara>
</listitem>
<listitem>
<simpara>
<command>DROP TABLE thename;</command>
</simpara>
<simpara>
In SESAM, in the <command>DROP TABLE</command> command, the
table name must be either followed by the keyword
<literal>RESTRICT</literal> or
<literal>CASCADE</literal>. When specifying
<literal>RESTRICT</literal>, an error is returned if there are
dependent objects (e.g., VIEWs), while with
<literal>CASCADE</literal>, dependent objects will be deleted
along with the specified table.
</simpara>
</listitem>
</itemizedlist>
</para>
</note>
<note>
<title>
Notes on the use of various SQL types
</title>
<para>
SESAM does not currently support the BLOB type. A future version
of SESAM will have support for BLOB.
</para>
<para>
At the PHP interface, the following type conversions are
automatically applied when retrieving SQL fields:
<table>
<title>SQL to PHP Type Conversions</title>
<tgroup cols="2">
<thead>
<row>
<entry>SQL Type</entry>
<entry>PHP Type</entry>
</row>
</thead>
<tbody>
<row>
<entry>SMALLINT, INTEGER</entry>
<entry><type>integer</type></entry>
</row>
<row>
<entry>NUMERIC, DECIMAL, FLOAT, REAL, DOUBLE</entry>
<entry><type>float</type></entry>
</row>
<row>
<entry>DATE, TIME, TIMESTAMP</entry>
<entry><type>string</type></entry>
</row>
<row>
<entry>VARCHAR, CHARACTER</entry>
<entry><type>string</type></entry>
</row>
</tbody>
</tgroup>
</table>
When retrieving a complete row, the result is returned as an
array. Empty fields are not filled in, so you will have to check
for the existence of the individual fields yourself (use
<function>isset</function> or <function>empty</function> to test
for empty fields). That allows more user control over the
appearance of empty fields (than in the case of an empty string
as the representation of an empty field).
</para>
</note>
<note>
<title>Support of SESAM's "multiple fields" feature</title>
<para>
The special "multiple fields" feature of SESAM allows a column to
consist of an array of fields. Such a "multiple field" column can
be created like this:
<example>
<title>Creating a "multiple field" column</title>
<programlisting role="sesam">
<![CDATA[
CREATE TABLE multi_field_test (
pkey CHAR(20) PRIMARY KEY,
multi(3) CHAR(12)
)
]]>
</programlisting>
</example>
and can be filled in using:
<example>
<title>Filling a "multiple field" column</title>
<programlisting role="sesam">
<![CDATA[
INSERT INTO multi_field_test (pkey, multi(2..3) )
VALUES ('Second', <'first_val', 'second_val'>)
]]>
</programlisting>
</example>
Note that (like in this case) leading empty sub-fields are
ignored, and the filled-in values are collapsed, so that in the
above example the result will appear as multi(1..2) instead of
multi(2..3).
</para>
<para>
When retrieving a result row, "multiple columns" are accessed
like "inlined" additional columns. In the example above, "pkey"
will have the index 0, and the three "multi(1..3)" columns will
be accessible as indices 1 through 3.
</para>
</note>
<para>
For specific SESAM details, please refer to <ulink
url="&url.sesam.en;">the SESAM/SQL-Server documentation
(english)</ulink> or <ulink url="&url.sesam.de;">the
SESAM/SQL-Server documentation (german)</ulink>, both available
online, or use the respective manuals.
</para>
</partintro>
<refentry id="function.sesam-connect">
<refnamediv>
<refname>sesam_connect</refname>
<refpurpose>Open SESAM database connection</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<methodsynopsis>
<type>bool</type><methodname>sesam_connect</methodname>
<methodparam><type>string</type><parameter>catalog</parameter></methodparam>
<methodparam><type>string</type><parameter>schema</parameter></methodparam>
<methodparam><type>string</type><parameter>user</parameter></methodparam>
</methodsynopsis>
<para>
Returns &true; if a connection to the SESAM
database was made, or &false; on error.
</para>
<para>
<function>sesam_connect</function> establishes a connection to an
SESAM database handler task. The connection is always
"persistent" in the sense that only the very first invocation
will actually load the driver from the configured SESAM OML PLAM
library. Subsequent calls will reuse the driver and will
immediately use the given catalog, schema, and user.
</para>
<para>
When creating a database, the <parameter>"catalog"</parameter>
name is specified in the SESAM configuration directive
<command>//ADD-SQL-DATABASE-CATALOG-LIST ENTRY-1 =
*CATALOG(CATALOG-NAME = catalogname,...)</command>
</para>
<para>
The <parameter>"schema"</parameter> references the desired
database schema (see SESAM handbook).
</para>
<para>
The <parameter>"user"</parameter> argument references one of the
users which are allowed to access this
<parameter>"catalog"</parameter> /
<parameter>"schema"</parameter> combination. Note that
<parameter>"user"</parameter> is completely independent from both
the system's user id's and from HTTP user/password protection. It
appears in the SESAM configuration only.
</para>
<para>
See also <function>sesam_disconnect</function>.
<example>
<title>Connect to a SESAM database</title>
<programlisting role="php">
<![CDATA[
<?php
if (!sesam_connect ("mycatalog", "myschema", "otto")
die("Unable to connect to SESAM");
?>
]]>
</programlisting>
</example>
</para>
</refsect1>
</refentry>
<refentry id="function.sesam-disconnect">
<refnamediv>
<refname>sesam_disconnect</refname>
<refpurpose>Detach from SESAM connection</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<methodsynopsis>
<type>bool</type><methodname>sesam_disconnect</methodname>
<void/>
</methodsynopsis>
<para>
Returns: always &true;.
</para>
<para>
<function>sesam_disconnect</function> closes the logical link to
a SESAM database (without actually disconnecting and unloading
the driver).
</para>
<para>
Note that this isn't usually necessary, as the open connection is
automatically closed at the end of the script's execution.
Uncommitted data will be discarded, because an implicit
<function>sesam_rollback</function> is executed.
</para>
<para>
<function>sesam_disconnect</function> will not close the
persistent link, it will only invalidate the currently defined
<parameter>"catalog"</parameter>, <parameter>"schema"</parameter>
and <parameter>"user"</parameter> triple, so that any sesam
function called after <function>sesam_disconnect</function> will
fail.
</para>
<para>
See also: <function>sesam_connect</function>.
<example>
<title>Closing a SESAM connection</title>
<programlisting role="php">
<![CDATA[
if (sesam_connect ("mycatalog", "myschema", "otto")) {
... some queries and stuff ...
sesam_disconnect();
}
]]>
</programlisting>
</example>
</para>
</refsect1>
</refentry>
<refentry id="function.sesam-settransaction">
<refnamediv>
<refname>sesam_settransaction</refname>
<refpurpose>Set SESAM transaction parameters</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<methodsynopsis>
<type>bool</type><methodname>sesam_settransaction</methodname>
<methodparam><type>int</type><parameter>isolation_level</parameter></methodparam>
<methodparam><type>int</type><parameter>read_only</parameter></methodparam>
</methodsynopsis>
<para>
Returns: &true; if the values are valid, and the
<function>settransaction</function> operation was successful,
&false; otherwise.
</para>
<para>
<function>sesam_settransaction</function> overrides the default
values for the "isolation level" and "read-only" transaction
parameters (which are set in the SESAM configuration file), in
order to optimize subsequent queries and guarantee database
consistency. The overridden values are used for the next
transaction only.
</para>
<para>
<function>sesam_settransaction</function> can only be called
before starting a transaction, not after the transaction has been
started already.
</para>
<para>
To simplify the use in php scripts, the following constants have
been predefined in php (see SESAM handbook for detailed
explanation of the semantics):
<table>
<title>
Valid values for <parameter>"Isolation_Level"</parameter>
parameter
</title>
<tgroup cols="3">
<thead>
<row>
<entry>Value</entry>
<entry>Constant</entry>
<entry>Meaning</entry>
</row>
</thead>
<tbody>
<row>
<entry>1</entry>
<entry><literal>SESAM_TXISOL_READ_UNCOMMITTED</literal></entry>
<entry>Read Uncommitted</entry>
</row>
<row>
<entry>2</entry>
<entry><literal>SESAM_TXISOL_READ_COMMITTED</literal></entry>
<entry>Read Committed</entry>
</row>
<row>
<entry>3</entry>
<entry><literal>SESAM_TXISOL_REPEATABLE_READ</literal></entry>
<entry>Repeatable Read</entry>
</row>
<row>
<entry>4</entry>
<entry><literal>SESAM_TXISOL_SERIALIZABLE</literal></entry>
<entry>Serializable</entry>
</row>
</tbody>
</tgroup>
</table>
<table>
<title>
Valid values for <parameter>"Read_Only"</parameter> parameter
</title>
<tgroup cols="3">
<thead>
<row>
<entry>Value</entry>
<entry>Constant</entry>
<entry>Meaning</entry>
</row>
</thead>
<tbody>
<row>
<entry>0</entry>
<entry><literal>SESAM_TXREAD_READWRITE</literal></entry>
<entry>Read/Write</entry>
</row>
<row>
<entry>1</entry>
<entry><literal>SESAM_TXREAD_READONLY</literal></entry>
<entry>Read-Only</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
The values set by <function>sesam_settransaction</function> will
override the default setting specified in the <link
linkend="ini.sesam-configfile">SESAM configuration file</link>.
</para>
<para>
<example>
<title>Setting SESAM transaction parameters</title>
<programlisting role="php">
<![CDATA[
<?php
sesam_settransaction (SESAM_TXISOL_REPEATABLE_READ,
SESAM_TXREAD_READONLY);
?>
]]>
</programlisting>
</example>
</para>
</refsect1>
</refentry>
<refentry id="function.sesam-commit">
<refnamediv>
<refname>sesam_commit</refname>
<refpurpose>
Commit pending updates to the SESAM database
</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<methodsynopsis>
<type>bool</type><methodname>sesam_commit</methodname>
<void/>
</methodsynopsis>
<para>
Returns: &true; on success,
&false; on errors
</para>
<para>
<function>sesam_commit</function> commits any pending updates to
the database.
</para>
<para>
Note that there is no "auto-commit" feature as in other
databases, as it could lead to accidental data loss. Uncommitted
data at the end of the current script (or when calling
<function>sesam_disconnect</function>) will be discarded by an
implied <function>sesam_rollback</function> call.
</para>
<para>
</para>
<para>
See also: <function>sesam_rollback</function>.
<example>
<title>Committing an update to the SESAM database</title>
<programlisting role="php">
<![CDATA[
<?php
if (sesam_connect ("mycatalog", "myschema", "otto")) {
if (!sesam_execimm ("INSERT INTO mytable VALUES (*, 'Small Test', <0, 8, 15>)"))
die("insert failed");
if (!sesam_commit())
die("commit failed");
}
?>
]]>
</programlisting>
</example>
</para>
</refsect1>
</refentry>
<refentry id="function.sesam-rollback">
<refnamediv>
<refname>sesam_rollback</refname>
<refpurpose>
Discard any pending updates to the SESAM database
</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<methodsynopsis>
<type>bool</type><methodname>sesam_rollback</methodname>
<void/>
</methodsynopsis>
<para>
Returns: &true; on success,
&false; on errors
</para>
<para>
<function>sesam_rollback</function> discards any pending updates
to the database. Also affected are result cursors and result
descriptors.
</para>
<para>
At the end of each script, and as part of the
<function>sesam_disconnect</function> function, an implied
<function>sesam_rollback</function> is executed, discarding any
pending changes to the database.
</para>
<para>
See also: <function>sesam_commit</function>.
<example>
<title>Discarding an update to the SESAM database</title>
<programlisting role="php">
<![CDATA[
<?php
if (sesam_connect ("mycatalog", "myschema", "otto")) {
if (sesam_execimm ("INSERT INTO mytable VALUES (*, 'Small Test', <0, 8, 15>)")
&& sesam_execimm ("INSERT INTO othertable VALUES (*, 'Another Test', 1)"))
sesam_commit();
else
sesam_rollback();
}
?>
]]>
</programlisting>
</example>
</para>
</refsect1>
</refentry>
<refentry id="function.sesam-execimm">
<refnamediv>
<refname>sesam_execimm</refname>
<refpurpose>Execute an "immediate" SQL-statement</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<methodsynopsis>
<type>string</type><methodname>sesam_execimm</methodname>
<methodparam><type>string</type><parameter>query</parameter></methodparam>
</methodsynopsis>
<para>
Returns: A SESAM "result identifier" on success, or
&false; on error.
</para>
<para>
<function>sesam_execimm</function> executes an "immediate"
statement (i.e., a statement like UPDATE, INSERT or DELETE which
returns no result, and has no INPUT or OUTPUT variables).
"select type" queries can not be used with
<function>sesam_execimm</function>. Sets the
<parameter>affected_rows</parameter> value for retrieval by the
<function>sesam_affected_rows</function> function.
</para>
<para>
Note that <function>sesam_query</function> can handle both
"immediate" and "select-type" queries. Use
<function>sesam_execimm</function> only if you know beforehand
what type of statement will be executed. An attempt to use
SELECT type queries with <function>sesam_execimm</function> will
return <literal>$err["sqlstate"] == "42SBW"</literal>.
</para>
<para>
The returned "result identifier" can not be used for retrieving
anything but the <function>sesam_affected_rows</function>; it is
only returned for symmetry with the
<function>sesam_query</function> function.
</para>
<para>
<informalexample>
<programlisting role="php">
<![CDATA[
$stmt = "INSERT INTO mytable VALUES ('one', 'two')";
$result = sesam_execimm ($stmt);
$err = sesam_diagnostic();
print ("sqlstate = ".$err["sqlstate"]."\n".
"Affected rows = ".$err["rowcount"]." == ".
sesam_affected_rows($result)."\n");
]]>
</programlisting>
</informalexample>
See also: <function>sesam_query</function> and
<function>sesam_affected_rows</function>.
</para>
</refsect1>
</refentry>
<refentry id="function.sesam-query">
<refnamediv>
<refname>sesam_query</refname>
<refpurpose>Perform a SESAM SQL query and prepare the result</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<methodsynopsis>
<type>string</type><methodname>sesam_query</methodname>
<methodparam><type>string</type><parameter>query</parameter></methodparam>
<methodparam choice="opt"><type>bool</type><parameter>scrollable</parameter></methodparam>
</methodsynopsis>
<para>
Returns: A SESAM "result identifier" on success, or
&false; on error.
</para>
<para>
A "result_id" resource is used by other functions to retrieve the
query results.
</para>
<para>
<function>sesam_query</function> sends a query to the currently
active database on the server. It can execute both "immediate"
SQL statements and "select type" queries. If an "immediate"
statement is executed, then no cursor is allocated, and any
subsequent <function>sesam_fetch_row</function> or
<function>sesam_fetch_result</function> call will return an empty
result (zero columns, indicating end-of-result). For "select
type" statements, a result descriptor and a (scrollable or
sequential, depending on the optional boolean
<parameter>scrollable</parameter> parameter) cursor will be
allocated. If <parameter>scrollable</parameter> is omitted, the
cursor will be sequential.
</para>
<para>
When using "scrollable" cursors, the cursor can be freely
positioned on the result set. For each "scrollable" query, there
are global default values for the scrolling type (initialized to:
<literal>SESAM_SEEK_NEXT</literal>) and the scrolling offset
which can either be set once by
<function>sesam_seek_row</function> or each time when fetching a
row using <function>sesam_fetch_row</function>.
</para>
<para>
For "immediate" statements, the number of affected rows is saved
for retrieval by the <function>sesam_affected_rows</function>
function.
</para>
<para>
See also: <function>sesam_fetch_row</function> and
<function>sesam_fetch_result</function>.
<example>
<title>
Show all rows of the "phone" table as a html table
</title>
<programlisting role="php">
<![CDATA[
<?php
if (!sesam_connect ("phonedb", "demo", "otto"))
die ("cannot connect");
$result = sesam_query ("select * from phone");
if (!$result) {
$err = sesam_diagnostic();
die ($err["errmsg"]);
}
echo "<TABLE BORDER>\n";
// Add title header with column names above the result:
if ($cols = sesam_field_array ($result)) {
echo " <TR><TH COLSPAN=".$cols["count"].">Result:</TH></TR>\n";
echo " <TR>\n";
for ($col = 0; $col < $cols["count"]; ++$col) {
$colattr = $cols[$col];
/* Span the table head over SESAM's "Multiple Fields": */
if ($colattr["count"] > 1) {
echo " <TH COLSPAN=".$colattr["count"].">".$colattr["name"].
"(1..".$colattr["count"].")</TH>\n";
$col += $colattr["count"] - 1;
} else
echo " <TH>" . $colattr["name"] . "</TH>\n";
}
echo " </TR>\n";
}
do {
// Fetch the result in chunks of 100 rows max.
$ok = sesam_fetch_result ($result, 100);
for ($row=0; $row < $ok["rows"]; ++$row) {
echo " <TR>\n";
for ($col = 0; $col < $ok["cols"]; ++$col) {
if (isset($ok[$col][$row]))
echo " <TD>" . $ok[$col][$row] . "</TD>\n";
} else {
echo " <TD>-empty-</TD>\n";
}
}
echo " </TR>\n";
}
}
while ($ok["truncated"]) { // while there may be more data
echo "</TABLE>\n";
}
// free result id
sesam_free_result($result);
?>
]]>
</programlisting>
</example>
</para>
</refsect1>
</refentry>
<refentry id="function.sesam-num-fields">
<refnamediv>
<refname>sesam_num_fields</refname>
<refpurpose>
Return the number of fields/columns in a result set
</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<methodsynopsis>
<type>int</type><methodname>sesam_num_fields</methodname>
<methodparam><type>string</type><parameter>result_id</parameter></methodparam>
</methodsynopsis>
<para>
After calling <function>sesam_query</function> with a "select
type" query, this function gives you the number of columns in the
result. Returns an integer describing the total number of
columns (aka. fields) in the current
<parameter>result_id</parameter> result set or
&false; on error.
</para>
<para>
For "immediate" statements, the value zero is returned. The SESAM
"multiple field" columns count as their respective dimension,
i.e., a three-column "multiple field" counts as three columns.
</para>
<para>
See also: <function>sesam_query</function> and
<function>sesam_field_array</function> for a way to distinguish
between "multiple field" columns and regular columns.
</para>
</refsect1>
</refentry>
<refentry id="function.sesam-field-name">
<refnamediv>
<refname>sesam_field_name</refname>
<refpurpose>
Return one column name of the result set
</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<methodsynopsis>
<type>int</type><methodname>sesam_field_name</methodname>
<methodparam><type>string</type><parameter>result_id</parameter></methodparam>
<methodparam><type>int</type><parameter>index</parameter></methodparam>
</methodsynopsis>
<para>
Returns the name of a field (i.e., the column name) in the result
set, or &false; on error.
</para>
<para>
For "immediate" queries, or for dynamic columns, an empty string
is returned.
</para>
<note>
<para>
The column index is zero-based, not one-based as in SESAM.
</para>
</note>
<para>
See also: <function>sesam_field_array</function>. It provides an
easier interface to access the column names and types, and allows
for detection of "multiple fields".
</para>
</refsect1>
</refentry>
<refentry id="function.sesam-diagnostic">
<refnamediv>
<refname>sesam_diagnostic</refname>
<refpurpose>
Return status information for last SESAM call
</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<methodsynopsis>
<type>array</type><methodname>sesam_diagnostic</methodname>
<void/>
</methodsynopsis>
<para>
Returns an associative array of status and return codes for the
last SQL query/statement/command. Elements of the array are:
<table>
<title>
Status information returned by <function>sesam_diagnostic</function>
</title>
<tgroup cols="2">
<thead>
<row>
<entry>Element</entry>
<entry>Contents</entry>
</row>
</thead>
<tbody>
<row>
<entry>$array["sqlstate"]</entry>
<entry>
5 digit SQL return code (see the SESAM manual for the
description of the possible values of SQLSTATE)
</entry>
</row>
<row>
<entry>$array["rowcount"]</entry>
<entry>
number of affected rows in last update/insert/delete (set
after "immediate" statements only)
</entry>
</row>
<row>
<entry>$array["errmsg"]</entry>
<entry>
"human readable" error message string (set after errors
only)
</entry>
</row>
<row>
<entry>$array["errcol"]</entry>
<entry>
error column number of previous error (0-based; or -1 if
undefined. Set after errors only)
</entry>
</row>
<row>
<entry>$array["errlin"]</entry>
<entry>
error line number of previous error (0-based; or -1 if
undefined. Set after errors only)
</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
In the following example, a syntax error (E SEW42AE ILLEGAL
CHARACTER) is displayed by including the offending SQL statement
and pointing to the error location:
<example>
<title>Displaying SESAM error messages with error position</title>
<programlisting role="php">
<![CDATA[
<?php
// Function which prints a formatted error message,
// displaying a pointer to the syntax error in the
// SQL statement
function PrintReturncode ($exec_str) {
$err = Sesam_Diagnostic();
$colspan=4; // 4 cols for: sqlstate, errlin, errcol, rowcount
if ($err["errlin"] == -1)
--$colspan;
if ($err["errcol"] == -1)
--$colspan;
if ($err["rowcount"] == 0)
--$colspan;
echo "<TABLE BORDER>\n";
echo "<TR><TH COLSPAN=".$colspan."><FONT COLOR=red>ERROR:</FONT> ".
htmlspecialchars($err["errmsg"])."</TH></TR>\n";
if ($err["errcol"] >= 0) {
echo "<TR><TD COLSPAN=".$colspan."><PRE>\n";
$errstmt = $exec_str."\n";
for ($lin=0; $errstmt != ""; ++$lin) {
if ($lin != $err["errlin"]) { // $lin is less or greater than errlin
if (!($i = strchr ($errstmt, "\n")))
$i = "";
$line = substr ($errstmt, 0, strlen($errstmt)-strlen($i)+1);
$errstmt = substr($i, 1);
if ($line != "\n")
print htmlspecialchars ($line);
} else {
if (! ($i = strchr ($errstmt, "\n")))
$i = "";
$line = substr ($errstmt, 0, strlen ($errstmt)-strlen($i)+1);
$errstmt = substr($i, 1);
for ($col=0; $col < $err["errcol"]; ++$col)
echo (substr($line, $col, 1) == "\t") ? "\t" : ".";
echo "<FONT COLOR=RED><BLINK>\\</BLINK></FONT>\n";
print "<FONT COLOR=\"#880000\">".htmlspecialchars($line)."</FONT>";
for ($col=0; $col < $err["errcol"]; ++$col)
echo (substr ($line, $col, 1) == "\t") ? "\t" : ".";
echo "<FONT COLOR=RED><BLINK>/</BLINK></FONT>\n";
}
}
echo "</PRE></TD></TR>\n";
}
echo "<TR>\n";
echo " <TD>sqlstate=" . $err["sqlstate"] . "</TD>\n";
if ($err["errlin"] != -1)
echo " <TD>errlin=" . $err["errlin"] . "</TD>\n";
if ($err["errcol"] != -1)
echo " <TD>errcol=" . $err["errcol"] . "</TD>\n";
if ($err["rowcount"] != 0)
echo " <TD>rowcount=" . $err["rowcount"] . "</TD>\n";
echo "</TR>\n";
echo "</TABLE>\n";
}
if (!sesam_connect ("mycatalog", "phoneno", "otto"))
die ("cannot connect");
$stmt = "SELECT * FROM phone\n".
" WHERE@ LASTNAME='KRAEMER'\n".
" ORDER BY FIRSTNAME";
if (!($result = sesam_query ($stmt)))
PrintReturncode ($stmt);
?>
]]>
</programlisting>
</example>
</para>
<para>
See also: <function>sesam_errormsg</function> for simple access
to the error string only
</para>
</refsect1>
</refentry>
<refentry id="function.sesam-fetch-result">
<refnamediv>
<refname>sesam_fetch_result</refname>
<refpurpose>Return all or part of a query result</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<methodsynopsis>
<type>mixed</type><methodname>sesam_fetch_result</methodname>
<methodparam><type>string</type><parameter>result_id</parameter></methodparam>
<methodparam choice="opt"><type>int</type><parameter>max_rows</parameter></methodparam>
</methodsynopsis>
<para>
Returns a mixed array with the query result entries, optionally
limited to a maximum of <parameter>max_rows</parameter> rows.
Note that both row and column indexes are zero-based.
<table>
<title>
Mixed result set returned by <function>sesam_fetch_result</function>
</title>
<tgroup cols="2">
<thead>
<row>
<entry>Array Element</entry>
<entry>Contents</entry>
</row>
</thead>
<tbody>
<row>
<entry>int $arr["count"]</entry>
<entry>
number of columns in result set (or zero if this was an
"immediate" query)
</entry>
</row>
<row>
<entry>int $arr["rows"]</entry>
<entry>
number of rows in result set (between zero and
<parameter>max_rows</parameter>)
</entry>
</row>
<row>
<entry>bool $arr["truncated"]</entry>
<entry>
&true; if the number of rows was at least
<parameter>max_rows</parameter>, &false;
otherwise. Note that even when this is
&true;, the next
<function>sesam_fetch_result</function> call may return zero
rows because there are no more result entries.
</entry>
</row>
<row>
<entry>mixed $arr[col][row]</entry>
<entry>
result data for all the fields at
row(<literal>row</literal>) and
column(<literal>col</literal>), (where the integer index
<literal>row</literal> is between 0 and
<literal>$arr["rows"]-1</literal>, and
<literal>col</literal> is between 0 and
<literal>$arr["count"]-1</literal>). Fields may be empty, so
you must check for the existence of a field by using the php
<function>isset</function> function. The type of the
returned fields depend on the respective SQL type declared
for its column (see <link linkend="ref.sesam">SESAM
overview</link> for the conversions applied). SESAM
"multiple fields" are "inlined" and treated like a sequence
of columns.
</entry>
</row>
</tbody>
</tgroup>
</table>
Note that the amount of memory used up by a large query may be
gigantic. Use the <parameter>max_rows</parameter> parameter to
limit the maximum number of rows returned, unless you are
absolutely sure that your result will not use up all available
memory.
</para>
<para>
See also: <function>sesam_fetch_row</function>, and
<function>sesam_field_array</function> to check for "multiple
fields". See the description of the
<function>sesam_query</function> function for a complete example
using <function>sesam_fetch_result</function>.
</para>
</refsect1>
</refentry>
<refentry id="function.sesam-affected-rows">
<refnamediv>
<refname>sesam_affected_rows</refname>
<refpurpose>
Get number of rows affected by an immediate query
</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<methodsynopsis>
<type>int</type><methodname>sesam_affected_rows</methodname>
<methodparam><type>string</type><parameter>result_id</parameter></methodparam>
</methodsynopsis>
<para>
<parameter>result_id</parameter> is a valid result id returned by
<function>sesam_query</function>.
</para>
<para>
Returns the number of rows affected by a query associated with
<parameter>result_id</parameter>.
</para>
<para>
The <function>sesam_affected_rows</function> function can only
return useful values when used in combination with "immediate"
SQL statements (updating operations like
<literal>INSERT</literal>, <literal>UPDATE</literal> and
<literal>DELETE</literal>) because SESAM does not deliver any
"affected rows" information for "select type" queries. The
number returned is the number of affected rows.
</para>
<para>
See also: <function>sesam_query</function> and
<function>sesam_execimm</function>
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
$result = sesam_execimm ("DELETE FROM PHONE WHERE LASTNAME = '".strtoupper ($name)."'");
if (!$result) {
... error ...
}
print sesam_affected_rows ($result).
" entries with last name ".$name." deleted.\n"
]]>
</programlisting>
</informalexample>
</refsect1>
</refentry>
<refentry id="function.sesam-errormsg">
<refnamediv>
<refname>sesam_errormsg</refname>
<refpurpose>Returns error message of last SESAM call</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<methodsynopsis>
<type>string</type><methodname>sesam_errormsg</methodname>
<void/>
</methodsynopsis>
<para>
Returns the SESAM error message associated with the most recent
SESAM error.
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
if (!sesam_execimm ($stmt))
printf ("%s<br>\n", sesam_errormsg());
]]>
</programlisting>
</informalexample>
<para>
See also: <function>sesam_diagnostic</function> for the full set
of SESAM SQL status information
</para>
</refsect1>
</refentry>
<refentry id="function.sesam-field-array">
<refnamediv>
<refname>sesam_field_array</refname>
<refpurpose>
Return meta information about individual columns in a result
</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<methodsynopsis>
<type>array</type><methodname>sesam_field_array</methodname>
<methodparam><type>string</type><parameter>result_id</parameter></methodparam>
</methodsynopsis>
<para>
<parameter>result_id</parameter> is a valid result id returned by
<function>sesam_query</function>.
</para>
<para>
Returns a mixed associative/indexed array with meta information
(column name, type, precision, ...) about individual columns of
the result after the query associated with
<parameter>result_id</parameter>.
</para>
<para>
<table>
<title>
Mixed result set returned by <function>sesam_field_array</function>
</title>
<tgroup cols="2">
<thead>
<row>
<entry>Array Element</entry>
<entry>Contents</entry>
</row>
</thead>
<tbody>
<row>
<entry>int $arr["count"]</entry>
<entry>
Total number of columns in result set (or zero if this was
an "immediate" query). SESAM "multiple fields" are
"inlined" and treated like the respective number of columns.
</entry>
</row>
<row>
<entry>string $arr[col]["name"]</entry>
<entry>
column name for column(<literal>col</literal>), where
<literal>col</literal> is between 0 and
<literal>$arr["count"]-1</literal>. The returned value can
be the empty string (for dynamically computed
columns). SESAM "multiple fields" are "inlined" and treated
like the respective number of columns, each with the same
column name.
</entry>
</row>
<row>
<entry>string $arr[col]["count"]</entry>
<entry>
The "count" attribute describes the repetition factor when
the column has been declared as a "multiple field". Usually,
the "count" attribute is 1. The first column of a "multiple
field" column however contains the number of repetitions
(the second and following column of the "multiple field"
contain a "count" attribute of 1). This can be used to
detect "multiple fields" in the result set. See the example
shown in the <function>sesam_query</function> description
for a sample use of the "count" attribute.
</entry>
</row>
<row>
<entry>string $arr[col]["type"]</entry>
<entry>
php variable type of the data for
column(<literal>col</literal>), where <literal>col</literal>
is between 0 and <literal>$arr["count"]-1</literal>. The
returned value can be one of
<itemizedlist>
<listitem>
<simpara><type>integer</type></simpara>
</listitem>
<listitem>
<simpara><type>float</type></simpara>
</listitem>
<listitem>
<simpara><type>string</type></simpara>
</listitem>
</itemizedlist>
depending on the SQL type of the result. SESAM "multiple
fields" are "inlined" and treated like the respective number
of columns, each with the same php type.
</entry>
</row>
<row>
<entry>string $arr[col]["sqltype"]</entry>
<entry>
SQL variable type of the column data for
column(<literal>col</literal>), where <literal>col</literal>
is between 0 and <literal>$arr["count"]-1</literal>. The
returned value can be one of
<itemizedlist>
<listitem>
<simpara>"CHARACTER"</simpara>
</listitem>
<listitem>
<simpara>"VARCHAR"</simpara>
</listitem>
<listitem>
<simpara>"NUMERIC"</simpara>
</listitem>
<listitem>
<simpara>"DECIMAL"</simpara>
</listitem>
<listitem>
<simpara>"INTEGER"</simpara>
</listitem>
<listitem>
<simpara>"SMALLINT"</simpara>
</listitem>
<listitem>
<simpara>"FLOAT"</simpara>
</listitem>
<listitem>
<simpara>"REAL"</simpara>
</listitem>
<listitem>
<simpara>"DOUBLE"</simpara>
</listitem>
<listitem>
<simpara>"DATE"</simpara>
</listitem>
<listitem>
<simpara>"TIME"</simpara>
</listitem>
<listitem>
<simpara>"TIMESTAMP"</simpara>
</listitem>
</itemizedlist>
describing the SQL type of the result. SESAM "multiple
fields" are "inlined" and treated like the respective number
of columns, each with the same SQL type.
</entry>
</row>
<row>
<entry>string $arr[col]["length"]</entry>
<entry>
The SQL "length" attribute of the SQL variable in
column(<literal>col</literal>), where <literal>col</literal>
is between 0 and <literal>$arr["count"]-1</literal>. The
"length" attribute is used with "CHARACTER" and "VARCHAR"
SQL types to specify the (maximum) length of the string
variable. SESAM "multiple fields" are "inlined" and treated
like the respective number of columns, each with the same
length attribute.
</entry>
</row>
<row>
<entry>string $arr[col]["precision"]</entry>
<entry>
The "precision" attribute of the SQL variable in
column(<literal>col</literal>), where <literal>col</literal>
is between 0 and <literal>$arr["count"]-1</literal>. The
"precision" attribute is used with numeric and time data
types. SESAM "multiple fields" are "inlined" and treated
like the respective number of columns, each with the same
precision attribute.
</entry>
</row>
<row>
<entry>string $arr[col]["scale"]</entry>
<entry>
The "scale" attribute of the SQL variable in
column(<literal>col</literal>), where <literal>col</literal>
is between 0 and <literal>$arr["count"]-1</literal>. The
"scale" attribute is used with numeric data types. SESAM
"multiple fields" are "inlined" and treated like the
respective number of columns, each with the same scale
attribute.
</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
See the <function>sesam_query</function> function for an example
of the <function>sesam_field_array</function> use.
</para>
</refsect1>
</refentry>
<refentry id="function.sesam-fetch-row">
<refnamediv>
<refname>sesam_fetch_row</refname>
<refpurpose>Fetch one row as an array</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<methodsynopsis>
<type>array</type><methodname>sesam_fetch_row</methodname>
<methodparam><type>string</type><parameter>result_id</parameter></methodparam>
<methodparam choice="opt"><type>int</type><parameter>whence</parameter></methodparam>
<methodparam choice="opt"><type>int</type><parameter>offset</parameter></methodparam>
</methodsynopsis>
<para>
Returns an array that corresponds to the fetched row, or
&false; if there are no more rows.
</para>
<para>
The number of columns in the result set is returned in an
associative array element $array["count"]. Because some of the
result columns may be empty, the <function>count</function>
function can not be used on the result row returned by
<function>sesam_fetch_row</function>.
</para>
<para>
<parameter>result_id</parameter> is a valid result id returned by
<function>sesam_query</function> (select type queries only!).
</para>
<para>
<parameter>whence</parameter> is an optional
parameter for a fetch operation on "scrollable" cursors, which
can be set to the following predefined constants:
<table>
<title>Valid values for <parameter>"whence"</parameter> parameter</title>
<tgroup cols="3">
<thead>
<row>
<entry>Value</entry>
<entry>Constant</entry>
<entry>Meaning</entry>
</row>
</thead>
<tbody>
<row>
<entry>0</entry>
<entry><literal>SESAM_SEEK_NEXT</literal></entry>
<entry>
read sequentially (after fetch, the internal default is set
to <literal>SESAM_SEEK_NEXT</literal>)
</entry>
</row>
<row>
<entry>1</entry>
<entry><literal>SESAM_SEEK_PRIOR</literal></entry>
<entry>
read sequentially backwards (after fetch, the internal
default is set to <literal>SESAM_SEEK_PRIOR</literal>)
</entry>
</row>
<row>
<entry>2</entry>
<entry><literal>SESAM_SEEK_FIRST</literal></entry>
<entry>
rewind to first row (after fetch, the default is set to
<literal>SESAM_SEEK_NEXT</literal>)
</entry>
</row>
<row>
<entry>3</entry>
<entry><literal>SESAM_SEEK_LAST</literal></entry>
<entry>
seek to last row (after fetch, the default is set to
<literal>SESAM_SEEK_PRIOR</literal>)
</entry>
</row>
<row>
<entry>4</entry>
<entry><literal>SESAM_SEEK_ABSOLUTE</literal></entry>
<entry>
seek to absolute row number given as
<parameter>offset</parameter> (Zero-based. After fetch, the
internal default is set to
<literal>SESAM_SEEK_ABSOLUTE</literal>, and the internal
offset value is auto-incremented)
</entry>
</row>
<row>
<entry>5</entry>
<entry><literal>SESAM_SEEK_RELATIVE</literal></entry>
<entry>
seek relative to current scroll position, where
<parameter>offset</parameter> can be a positive or negative
offset value.
</entry>
</row>
</tbody>
</tgroup>
</table>
This parameter is only valid for "scrollable" cursors.
</para>
<para>
When using "scrollable" cursors, the cursor can be freely
positioned on the result set. If the
<parameter>whence</parameter> parameter is
omitted, the global default values for the scrolling type
(initialized to: <literal>SESAM_SEEK_NEXT</literal>, and settable
by <function>sesam_seek_row</function>) are used. If
<parameter>whence</parameter> is supplied,
its value replaces the global default.
</para>
<para>
<parameter>offset</parameter> is an optional
parameter which is only evaluated (and required) if
<parameter>whence</parameter> is either
<literal>SESAM_SEEK_RELATIVE</literal> or
<literal>SESAM_SEEK_ABSOLUTE</literal>. This parameter is only
valid for "scrollable" cursors.
</para>
<para>
<function>sesam_fetch_row</function> fetches one row of data from
the result associated with the specified result identifier. The
row is returned as an array (indexed by values between
<literal>0</literal> and <literal>$array["count"]-1</literal>).
Fields may be empty, so you must check for the existence of a
field by using the php <function>isset</function> function. The
type of the returned fields depend on the respective SQL type
declared for its column (see <link linkend="ref.sesam">SESAM
overview</link> for the conversions applied). SESAM "multiple
fields" are "inlined" and treated like a sequence of columns.
</para>
<para>
Subsequent calls to <function>sesam_fetch_row</function> would
return the next (or prior, or n'th next/prior, depending on the
scroll attributes) row in the result set, or
&false; if there are no more rows.
</para>
<example>
<title>SESAM fetch rows</title>
<programlisting role="php">
<![CDATA[
<?php
$result = sesam_query ("SELECT * FROM phone\n".
" WHERE LASTNAME='".strtoupper($name)."'\n".
" ORDER BY FIRSTNAME", 1);
if (!$result) {
... error ...
}
// print the table in backward order
print "<TABLE BORDER>\n";
$row = sesam_fetch_row ($result, SESAM_SEEK_LAST);
while (is_array ($row)) {
print " <TR>\n";
for ($col = 0; $col < $row["count"]; ++$col) {
print " <TD>".htmlspecialchars ($row[$col])."</TD>\n";
}
print " </TR>\n";
// use implied SESAM_SEEK_PRIOR
$row = sesam_fetch_row ($result);
}
print "</TABLE>\n";
sesam_free_result ($result);
?>
]]>
</programlisting>
</example>
<para>
See also: <function>sesam_fetch_array</function> which returns an
associative array, and <function>sesam_fetch_result</function>
which returns many rows per invocation.
</para>
</refsect1>
</refentry>
<refentry id="function.sesam-fetch-array">
<refnamediv>
<refname>sesam_fetch_array</refname>
<refpurpose>Fetch one row as an associative array</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<methodsynopsis>
<type>array</type><methodname>sesam_fetch_array</methodname>
<methodparam><type>string</type><parameter>result_id</parameter></methodparam>
<methodparam choice="opt"><type>int</type><parameter>whence</parameter></methodparam>
<methodparam choice="opt"><type>int</type><parameter>offset</parameter></methodparam>
</methodsynopsis>
<para>
Returns an array that corresponds to the fetched row, or
&false; if there are no more rows.
</para>
<para>
<function>sesam_fetch_array</function> is an alternative version
of <function>sesam_fetch_row</function>. Instead of storing the
data in the numeric indices of the result array, it stores the
data in associative indices, using the field names as keys.
</para>
<para>
<parameter>result_id</parameter> is a valid result id returned by
<function>sesam_query</function> (select type queries only!).
</para>
<para>
For the valid values of the optional
<parameter>whence</parameter>and
<parameter>offset</parameter> parameters,
see the <function>sesam_fetch_row</function> function for
details.
</para>
<para>
<function>sesam_fetch_array</function> fetches one row of data
from the result associated with the specified result identifier.
The row is returned as an associative array. Each result column
is stored with an associative index equal to its column
(aka. field) name. The column names are converted to lower case.
</para>
<para>
Columns without a field name (e.g., results of arithmetic
operations) and empty fields are not stored in the array. Also,
if two or more columns of the result have the same column names,
the later column will take precedence. In this situation, either
call <function>sesam_fetch_row</function> or make an alias for
the column.
<informalexample>
<programlisting role="sesam">
<![CDATA[
SELECT TBL1.COL AS FOO, TBL2.COL AS BAR FROM TBL1, TBL2
]]>
</programlisting>
</informalexample>
</para>
<para>
A special handling allows fetching "multiple field" columns
(which would otherwise all have the same column names). For each
column of a "multiple field", the index name is constructed by
appending the string "(n)" where n is the sub-index of the
multiple field column, ranging from 1 to its declared repetition
factor. The indices are NOT zero based, in order to match the
nomenclature used in the respective query syntax. For a column
declared as:
<informalexample>
<programlisting role="sesam">
<![CDATA[
CREATE TABLE ... ( ... MULTI(3) INT )
]]>
</programlisting>
</informalexample>
the associative indices used for the individual "multiple field"
columns would be <literal>"multi(1)"</literal>,
<literal>"multi(2)"</literal>, and <literal>"multi(3)"</literal>
respectively.
</para>
<para>
Subsequent calls to <function>sesam_fetch_array</function> would
return the next (or prior, or n'th next/prior, depending on the
scroll attributes) row in the result set, or
&false; if there are no more rows.
</para>
<example>
<title>SESAM fetch array</title>
<programlisting role="php">
<![CDATA[
<?php
$result = sesam_query ("SELECT * FROM phone\n".
" WHERE LASTNAME='".strtoupper($name)."'\n".
" ORDER BY FIRSTNAME", 1);
if (!$result) {
... error ...
}
// print the table:
print "<TABLE BORDER>\n";
while (($row = sesam_fetch_array ($result)) && count ($row) > 0) {
print " <TR>\n";
print " <TD>".htmlspecialchars ($row["firstname"])."</TD>\n";
print " <TD>".htmlspecialchars ($row["lastname"])."</TD>\n";
print " <TD>".htmlspecialchars ($row["phoneno"])."</TD>\n";
print " </TR>\n";
}
print "</TABLE>\n";
sesam_free_result ($result);
?>
]]>
</programlisting>
</example>
<para>
See also: <function>sesam_fetch_row</function> which returns an
indexed array.
</para>
</refsect1>
</refentry>
<refentry id="function.sesam-seek-row">
<refnamediv>
<refname>sesam_seek_row</refname>
<refpurpose>
Set scrollable cursor mode for subsequent fetches
</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<methodsynopsis>
<type>bool</type><methodname>sesam_seek_row</methodname>
<methodparam><type>string</type><parameter>result_id</parameter></methodparam>
<methodparam><type>int</type><parameter>whence</parameter></methodparam>
<methodparam choice="opt"><type>int</type><parameter>offset</parameter></methodparam>
</methodsynopsis>
<para>
<parameter>result_id</parameter> is a valid result id (select
type queries only, and only if a "scrollable" cursor was
requested when calling <function>sesam_query</function>).
</para>
<para>
<parameter>whence</parameter> sets the global default value for
the scrolling type, it specifies the scroll type to use in
subsequent fetch operations on "scrollable" cursors, which can be
set to the following predefined constants:
<table>
<title>Valid values for <parameter>"whence"</parameter> parameter</title>
<tgroup cols="3">
<thead>
<row>
<entry>Value</entry>
<entry>Constant</entry>
<entry>Meaning</entry>
</row>
</thead>
<tbody>
<row>
<entry>0</entry>
<entry><literal>SESAM_SEEK_NEXT</literal></entry>
<entry>read sequentially
</entry>
</row>
<row>
<entry>1</entry>
<entry><literal>SESAM_SEEK_PRIOR</literal></entry>
<entry>read sequentially backwards
</entry>
</row>
<row>
<entry>2</entry>
<entry><literal>SESAM_SEEK_FIRST</literal></entry>
<entry>
fetch first row (after fetch, the default is set to
<literal>SESAM_SEEK_NEXT</literal>)
</entry>
</row>
<row>
<entry>3</entry>
<entry><literal>SESAM_SEEK_LAST</literal></entry>
<entry>
fetch last row (after fetch, the default is set to
<literal>SESAM_SEEK_PRIOR</literal>)
</entry>
</row>
<row>
<entry>4</entry>
<entry><literal>SESAM_SEEK_ABSOLUTE</literal></entry>
<entry>
fetch absolute row number given as
<parameter>offset</parameter> (Zero-based. After fetch, the
default is set to <literal>SESAM_SEEK_ABSOLUTE</literal>,
and the offset value is auto-incremented)
</entry>
</row>
<row>
<entry>5</entry>
<entry><literal>SESAM_SEEK_RELATIVE</literal></entry>
<entry>
fetch relative to current scroll position, where
<parameter>offset</parameter> can be a positive or negative
offset value (this also sets the default "offset" value for
subsequent fetches).
</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<parameter>offset</parameter> is an optional
parameter which is only evaluated (and required) if
<parameter>whence</parameter> is either
<literal>SESAM_SEEK_RELATIVE</literal> or
<literal>SESAM_SEEK_ABSOLUTE</literal>.
</para>
</refsect1>
</refentry>
<refentry id="function.sesam-free-result">
<refnamediv>
<refname>sesam_free_result</refname>
<refpurpose>Releases resources for the query</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<methodsynopsis>
<type>int</type><methodname>sesam_free_result</methodname>
<methodparam><type>string</type><parameter>result_id</parameter></methodparam>
</methodsynopsis>
<para>
Releases resources for the query associated with
<parameter>result_id</parameter>. Returns
&false; on error.
</para>
</refsect1>
</refentry>
</reference>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"../../manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->