1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010
|
<?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
-->
|