PHP中 ADOdb 类库应用(三):参考手册(2)

ADOConnection 主要函数
ADOConnection( )

建构函数,请不要直接呼叫,使用 ADONewConnection() 来代替。

Connect($host,[$user],[$password],[$database])

对服务器或资料来源 $host 非持续性连结,使用者认证代码为 $user ,密码为 $password ,如果服务器支持多数据库,则指定连结到数据库 $database。

连结成功回传 true , 失败则回传 false 。

注意:如果你使用的是 Microsoft ADO,而非 OLEDB,你可以设定 $database 参数为你正在使用的 OLEDB 资料供应器。

PostgreSQL:另一种选择性的连结方法是将标准的PostgreSQL连结字符串放在 $host 参数里,那么其它的参数都会被呼略。

对于 Oracle 及 Oci8,有两个方法可以连结。第一,使用你定义的区域 tnsnames.ora 里的 TNS 名称,将这个名称放在 $database 参数里,然后将 $host 设为 false。另一种方法,设定 $host 为服务器,而 $database 则设成数据库 SID ,这将会不透过 tnsnames.ora 连结。

范例:

$conn->Connect(false, ‘scott’, ‘tiger’, ‘name_in_tnsnames’); # 使用 tnsnames.ora
$conn->Connect(‘server:1521’, ‘scott’, ‘tiger’, ‘OracleSID’); # 不使用 tnsnames.ora
PConnect($host,[$user],[$password],[$database])

对服务器或资料来源 $host 持续性连结,使用者认证代码为 $user ,密码为 $password ,如果服务器支持多数据库,则指定连结到数据库 $database。

连结成功回传 true , 失败则回传 false 。其它资料请参考 Connect()。

Execute($sql,$inputarr=false)

执行 SQL 指令 $sql ,如果成功,就回传一个对应的 ADORecordSet 对象。要注意的是这个指令如果执行成功时,一定会回传一个数据集,即使是执行 insert 或 update 指令也一样。

回传对应的 ADORecordSet 对象。例如,如果连结的是 mysql ,那么 ADORecordSet_mysql 将会被回传。当SQL指令执行失败时会回传 false 值。

$inputarr 参数则用来做为传入的结合变量。以下是 Oracle 的范例:

$conn->Execute(“SELECT * FROM TABLE WHERE COND=:val”, array(‘val’=> $val));

另一个例子,使用 ODBC ,以 ‘?’ 符号做为协议。

$conn->Execute(“SELECT * FROM TABLE WHERE COND=?”, array($val));
结合变量(Binding variables)
变量的结合可以加速SQL指令编译及快取的速度,产生较佳的效能。目前只有 Oracle 及 ODBC 支持变量结合。 ODBC 类的 ? 结合在不支持的数据库里,是以仿真的方式来做到的。

变量结合在 odbc 及 oci8po 驱动程序里的用法。

$rs = $db->Execute(‘select * from table where val=?’, array(’10’));
变量结合在 oci8 驱动程序里的用法。

$rs = $db->Execute(‘select name from table where val=:key’,array(‘key’ => 10));
CacheExecute($secs2cache,$sql,$inputarr=false)

类似于 Execute 函数,除了将资料集暂存在 $ADODB_CACHE_DIR 指定的目录里 $secs2cache 秒外。如果 CacheExecute() 被相同的参数、数据库、使用者ID及密码,而且快取也没有过期,那么快取中的资料集将会被传回。

include(‘ADOdb.inc.php’);
include(‘tohtml.inc.php’);
$ADODB_CACHE_DIR = ‘/usr/local/ADOdbcache’;
$conn = &ADONewConnection(‘mysql’);
$conn->PConnect(‘localhost’,’userid’,’password’,’database’);
$rs = $conn->CacheExecute(15, ‘select * from table’); # 快取15秒
rs2html($rs); /* recordset to html table */
另外,从ADODB 1.80 版起,$secs2cache 参数成为选择性(也就是可以不加)

       $conn->Connect(…);
        $conn->cacheSecs = 3600*24; // cache 24 hours
        $rs = $conn->CacheExecute(‘select * from table’);
如果 CacheExecute() 被多次呼叫,而且资料集也持续在快取中,$secs2cache 参数不会延长被快取的资料集保留时间(因为会被呼略掉),CacheExecute()只能使用在 SELECT 指令上。

效能备注:我曾经作了一些效能测试,并且发现这些快取的效益极为显著。尤其是在数据库服务器运作效率慢于WEB服务器或数据库的负荷非常重的时候。ADODB的快取好在它减少了数据库服务器的负荷。当然,如果你的数据库服务器负荷不大,而且运作速度也比WEB服务器快,那快取反而会降低效能。

SelectLimit($sql,$numrows=-1,$offset=-1,$inputarr=false)

执行成功会回传一个资料集。完成一个SELECT指令,类似于 PostgreSQL中 SELECT 指令里的LIMIT $numrows OFFSET $offset 宣告。

在 PostgreSQL,SELECT * FROM TABLE LIMIT 3 将会只传回从头开始的三笔记录。相同的,$connection->SelectLimit(‘SELECT * FROM TABLE’,3)也有同样的意思。

而 SELECT * FROM TABLE LIMIT 3 OFFSET 2 将会回传记录 3,4及5三笔(也就是在记录2之后,回传三笔记录)。相同的,在ADODB里是以 $connection->SelectLimit(‘SELECT * FROM TABLE’,3,2) 来做的。

要注意,LIMIT宣告,在MySQL里是相反位置的。你可以设定 $connection->SelectLimit(‘select * from table’,-1,10) 去取得从第11笔起到最后一笔的记录。

最后一个参数 $inputarr 是针对支持变量结合功能的数据库,像 Oracle oci8。这个大大的减少了 SQL 编译的负荷。底下是 Oracle 范例:

$conn->SelectLimit(“SELECT * FROM TABLE WHERE COND=:val”, 100,-1,array(‘val’=> $val));

CacheSelectLimit($secs2cache, $sql, $numrows=-1,$offset=-1,$inputarr=false)
类似于 SelectLimit,除了将资料集暂存在 $ADODB_CACHE_DIR 指定的目录里 $secs2cache 秒外。

自 1.80版起,$secs2cache成为了选择性参数:

$conn->Connect(…);
        $conn->cacheSecs = 3600*24; // 快取24小时
        $rs = $conn->CacheSelectLimit(‘select * from table’,10);
CacheFlush($sql)

更新(删除)以 $sql 指令存放在 $ADODB_CACHE_DIR 指定目录内的全部快取资料集。如果你企图更新所有的快取数据集,请执行如下的PHP指令码(仅针对 Unix 有效):system(“rm -f find “.ADODB_CACH_DIR.” -name ADODB_*.cache”) ;

ErrorMsg()

回传最后状态或是错误讯息。即使没有错误发生,本函数也会回传一个字符串。一般情况下,你不需要呼叫这个函数,除非ADODB函数因为错误状态回传了false值。

注意:如果 debug 旗标被激活了,SQL 错误讯息将会在Execute函数被呼叫时发生错误后出现。

ErrorNo()

回传最后的错误号码。注意一点,旧版本的 PHP(4.0.6以前),不支持ODBC的错误编号。一般情况下,你不需要呼叫这个函数,除非ADODB函数因为错误状态回传了false值。

GenID($seqName = ‘ADOdbseq’,$startID=1)

产生一个顺序号码(在mssql是一个整数值)。对 interbase,mysql,postgresql,oci8,oci8po,ODBC核心类驱动程序(如 access,vfp,db2等等) 都支持。使用 $seqName做为顺序名。如果数据库没有值,那么GenID()将会自动为你产生一个序号(产生使用者 id 时允许如此),换句话说,你必需自行建立序号。

如果你的数据库驱动程序要仿真序号,资料表的名称就是序号名(sequence name),而这个资料表必需有一个字段”id”,而其资料型别为整数,或你需要更大些的 numeric(16)。

对于没有支持序号原生功能的ODBC及数据库(如 mssql,mysql),我们对每一个序号建立一个资料表。如果序号没有被预先定义,那启如的号码值就设定成 $startID。

注意,mssql驱动程序的 GenID()会产生一个16位的GUID。自1.90版起,我们将回传整数。

UpdateBlob($table,$column,$val,$where)

允许你以 $where 条件储存一个BLOB(存在 $val里的)值到 $table 里的 $column 字段。

例:

        # for oracle

        $conn->Execute(‘INSERT INTO blobtable (id, blobcol) VALUES (1, empty_blob())’);
        $conn->UpdateBlob(‘blobtable’,’blobcol’,$blobvalue,’id=1′);
        # non oracle databases
        $conn->Execute(‘INSERT INTO blobtable (id, blobcol) VALUES (1, null)’);
        $conn->UpdateBlob(‘blobtable’,’blobcol’,$blobvalue,’id=1′);
如果成功,会回传 true ,否则回传 false 值。目前有 MySQL, PostgreSQL, Oci8, Oci8po 及 Interbase 支持。其它驱动程序可能有效,仍在持续开发中。

要注意,在PHP 4.1.0 以前的版本,当 Interbase的 blob 值被 SELECT 取回值时,它仍需要被译码,请使用 $connection->DecodeBlob($blob); 以还原它的内容。

UpdateClob($table,$column,$val,$where)

允许你以 $where 条件储存一个BLOB(存在 $val里的)值到 $table 里的 $column 字段。类似于 UpdateBlog,但主要针对文字大型档案对象。

例:

        # for oracle

        $conn->Execute(‘INSERT INTO clobtable (id, clobcol) VALUES (1, empty_clob())’);
        $conn->UpdateBlob(‘clobtable’,’clobcol’,$clobvalue,’id=1′);

        # non oracle databases
        $conn->Execute(‘INSERT INTO clobtable (id, clobcol) VALUES (1, null)’);
        $conn->UpdateBlob(‘clobtable’,’clobcol’,$clobvalue,’id=1′);
UpdateBlobFile($table,$column,$path,$where,$blobtype=’BLOB’)

如同 UpdateBlob ,但我们将值改成一个档案路径,将整个档案存入。

成功回传 true 否则为 false。

GetUpdateSQL(&$rs, $arrFields, $forceUpdate=false,$magicq=false)

建立一个 SQL 以更新一个被给予的资料集 $rs ,被修改的字段存放在数组 $arrFields中(这个数组必需是具名数组,字段名为索引,值为修正值),会与原来的资料集做一个比较,如果 $forceUpdate被设为 true,那么即使 $arrFields与 $rs->fields完全相同,也会产生出更新的SQL指令。资料集必需在连结状态。$magicq 被用于指出魔术引号功能是否被激活。

GetInsertSQL(&$rs, $arrFields,$magicq=false)

建立一个 SQL 以新增一笔记录到被给予的资料集 $rs。这个查询必需是在连结状态。$magicq 被用于指出魔术引号功能是否被激活。

PageExecute($sql, $nrows, $page, $inputarr=false)

使用资料集的页码功能,参数 $page 是以 1 为启使值,请参考范例 8.

CachePageExecute($secs2cache, $sql, $nrows, $page, $inputarr=false)

使用资料集的页码功能,参数 $page 是以 1 为启使值,请参考范例 8.PageExecute 的快取版。

Close( )

关闭数据库的连结。PHP4 以数据库连结结束时不需要特别去清除而享有盛名,因为其参考计数机制会自动帮我们清除掉。

BeginTrans( )

启始一笔交易。会关闭自动结案功能。执行成功会回传 true 。如果不支持交易功能,部份数据库会一直传回 false 值。Interbase,Oracle 及 MSSQL 支持交易机制。请注意,因为 PHP 4.02 版的臭虫,交易支持在微软的 ADO 上是无效的。你必需使用你关连式数据库的原生交易支持功能。当连结结束时,任何开启的交易都会被还原。

CommitTrans( )

成功的结束一次交易。如果成功,回传 true。如果数据库并不支持交易功能,那么就只会传回 true ,以表示资料总是交易成功的。

RollbackTrans( )

结束一次交易,恢复所有改变。执行成功会回传 true 。如果数据库并不支持交易功能,那么就只会传回 false ,以表示资料总是不能恢复。

GetOne($sql)

Executes the SQL and returns the first field of the first row as an array. The recordset and remaining rows are discarded for you automatically. If an error occur, false is returned.

执行SQL指令,并且以数组的方式回传第一笔记录的第一个字段。资料集及其余的记录将会被自动清除,如果发生错误,就回传 false 值。

译者注:这个功能在验证某笔记录在不在特别有用,可以减少系统内存及资源的用量。

GetRow($sql)

执行SQL指令,并且以数组的方式回传第一笔记录。资料集及其余的记录将会被自动清除,如果发生错误,就回传 false 值。

Prepare($sql )

预先编译一个SQL查询,以便于重复执行。如果有任何语法错误,Prepare()不会显示任合错误,但允许 Execute() 去取得及显示错误。内部实作支持 interbase ,oci8 及选择性的 ODBC-based 驱动程序。其余的都是以仿真的方式支持。在仿真的情况下,使用 Prepare() 对效能的增进没有任何效果。

回传一个包含了原始描述为第一个数组元素的数组,其余的元素内容则视驱动程序而定。如果有错误或是仿真方式的 Prepare(),会回传原来的 $sql 字符串。那是因为所有的错误处理都被集中到 Execute() 里去了。

范例 :

$stmt = $DB->Prepare(‘insert into table (col1,col2) values (?,?)’);
for ($i=0; $i < $max; $i++)
$DB->Execute($stmt,array((string) rand(), $i));
PrepareSP($sql)

在 mssql 驱动程序里,预编译预储程序必需要透过一个特别的函数来呼叫 mssql_init(),这个动作目前由本函数来处理了。PrepareSP() 可以在所有的驱动程序由被呼叫,而且以呼叫 Prepare() 的方式来仿真。使用范例请参考以下的 Parameter() 说明。

和上面的 Prepare() 回传一样的数组或 $sql 字符串。

Parameter($stmt, $var, $name, $isOutput=false, $maxLen = 4000, $type = false )

在运作中增加一个结合参数。目前兼容于 Microsoft SQL 及 Oracle oci8。以下是参数说明:
$stmt 由 Prepare() 或 PrepareSP() 回传的指令。
$var 要结合的 PHP 变量。
$name 要结合的预储程序的变量名。
[$isOutput] 设定参数传导的方向,0/false = IN 1=OUT 2= IN/OUT 。 在 oci8 中这个参数会被忽略,因为驱动程序会自动侦测。
[$maxLen] 参数变量的最大长度。
[$type] 参考 mssql_bind 及 ocibindbyname 在 PHP.NET 的文件说明以取得更多正确值的信息。

在 mssql,$opt 可以被下列的元素所影响:mssql_bind and ocibindbyname 。 例如 ;

# @RETVAL = SP_RUNSOMETHING @myid,@group
$stmt = $db->PrepareSP(‘SP_RUNSOMETHING’);
# note that the parameter name does not have @ in front!
$db->Parameter($stmt,$id,’myid’);
$db->Parameter($stmt,$group,’group’,false,64);
# return value in mssql – RETVAL is hard-coded name
$db->Parameter($stmt,$ret,’RETVAL’,true);
$db->Execute($stmt);
一个 oci8 的例子:

# 对于 oracle, Prepare 及 PrepareSP 是相同的
$stmt = $db->PrepareSP(
        “declare ret integer;
     begin
                :RETVAL := SP_RUNSOMETHING(:myid,:group);
     end;”);
$db->Parameter($stmt,$id,’myid’);
$db->Parameter($stmt,$group,’group’,false,64);
$db->Parameter($stmt,$ret,’RETVAL’,true);
$db->Execute($stmt);
请注意,在 oci8 及 mssql 间只有语法上的不同,那是各数据库实作 SQL 语法问题,ADODB 对于这一部份无能为力。

如果 $type 参数被设定成 false 。在 mssql ,$type 将会动态的由 PHP 变量传来的型别决定(string => SQLCHAR, boolean =>SQLINT1, integer =>SQLINT4 或 float/double=>SQLFLT8),在 oci8,$type 可以被设成 OCI_B_FILE (Binary-File), OCI_B_CFILE (Character-File), OCI_B_CLOB (Character-LOB), OCI_B_BLOB (Binary-LOB) 及 OCI_B_ROWID (ROWID)。如果要传入空值,使用 $db->Parameter($stmt, $null=null, ‘param’)。

最后,在 oci8,结合参数可以重复被使用,而无需再一次呼叫 PrepareSP() 或 Parameters。但这对 mssql 是不行的。一个 oci8 的范例如下:

$id = 0; $i = 0;
$stmt = $db->PrepareSP( “update table set val=:i where id=:id”);
$db->Parameter($stmt,$id,’id’);
$db->Parameter($stmt,$i, ‘i’);
for ($cnt=0; $cnt < 1000; $cnt++) {
        $id = $cnt;
        $i = $cnt * $cnt; # oci8 下可以运作
        $db->Execute($stmt);
}
Bind($stmt, $var, $size=4001, $type=false, $name=false)

这是一个低阶函数,只有 oci8 驱动程序支持。只有你确定系统仅支持 Oracle 否则请避免使用它。Parameter() 函数是使用结合变量的另一个建议方式。

Bind() 允许你使用结合变量在你的 sql 叙述中。这里结合一个PHP变量给一个在之前被 Prepare() 预先编译的 Oracle sql 叙述里定义的名称。Oracle 以一个冒号为开头来命名一个变量,而且 ADODB 需要一个被命名的变量去对应 :0,:1,:2,:3,等等。第一次被 Bind() 取得的将会代入 :0,而第二次将会代入 :1,依此类推。对 insert , select 及 update 指令,结合可以提供 100% 的效能提升。

在其余的参数里,$size 设定资料储存的暂存区大小,$type 是 OCI_B_FILE (Binary-File), OCI_B_CFILE (Character-File), OCI_B_CLOB (Character-LOB), OCI_B_BLOB (Binary-LOB) 及 OCI_B_ROWID (ROWID) 的类别选项。最后,代替使用预设的 :0,:1 等等名称,你可以使用 $name 来定义你自己的连结名称。

接下来的例子展示3个连结变量,使用 p1,p2及p3来结合。这些变量将会配到 :0 , :1 及 :2 。

$stmt = $DB->Prepare(“insert into table (col0, col1, col2) values (:0, :1, :2)”);
$DB->Bind($stmt, $p1);
$DB->Bind($stmt, $p2);
$DB->Bind($stmt, $p3);
for ($i = 0; $i < $max; $i++) {
   $p1 = ?; $p2 = ?; $p3 = ?;
   $DB->Execute($stmt);
}
你也可以使用名称变量:

$stmt = $DB->Prepare(“insert into table (col0, col1, col2) values (:name0, :name1, :name2)”);
$DB->Bind($stmt, $p1, “name0”);
$DB->Bind($stmt, $p2, “name1”);
$DB->Bind($stmt, $p3, “name2”);
for ($i = 0; $i < $max; $i++) {
   $p1 = ?; $p2 = ?; $p3 = ?;
   $DB->Execute($stmt);
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注