412 12
发新话题
打印

关于DFP与Access的连接的方法总结

本主题由 phpres 于 2007-11-27 08:54 加入精华

关于DFP与Access的连接的方法总结

终于成功弄好了Access的连接,Sybase的连接也搞定了,但Sybase的连接出现中文乱码,我在想如何解决字符集的问题。

DFP与Access的连接主要是Database的设置问题,其它的按正常的连接就可以了。
Database属性中的DatabaseName很多人以为是数据库的名字,其实就是access或者是Microsoft.Jet.OLEDB.4.0

那么有人要问了,数据库名称在什么地方写,告诉你,是在hostname中,还要注意格式和内容,我写的是(DATA SOURCE="d:/My Documents/Delphi for PHP Projects/DelphiForPHP_Test/oil_new.mdb")不含括号!!!里面的数据库名称记得要改,至于用户名和密码,如果没有设置可以不填写。

DriverName的值就是ado_access,这个要写死。
整个分析的过程如下(分析过程就是通过对IE浏览器错误的输出中涉及的文件进行跟踪。因为是数据库的问题,所以分析与数据库相关的文件类):

下面的方法就是数据库的连接方法(adodb.inc.php文件的419行)
复制内容到剪贴板
代码:
function Connect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "", $forceNew = false)
{
        if ($argHostname != "") $this->host = $argHostname;
        if ($argUsername != "") $this->user = $argUsername;
        if ($argPassword != "") $this->password = $argPassword; // not stored for security reasons
        if ($argDatabaseName != "") $this->database = $argDatabaseName;

        $this->_isPersistentConnection = false;
       
        if ($forceNew) {
                if ($rez=$this->_nconnect($this->host, $this->user, $this->password, $this->database)) return true;
        } else {
                 if ($rez=$this->_connect($this->host, $this->user, $this->password, $this->database)) return true;
   
    /*注意:这里要调用另一个文件中的方法,断点设在这里,注意参数的值,可以使用watches窗口Add watcher来看。
     *先将设置的值写在纸上,等分析完后面的方法后,就知道该填写什么内容了
     */
        }
        if (isset($rez)) {
                $err = $this->ErrorMsg();
                if (empty($err)) $err = "Connection error to server '$argHostname' with user '$argUsername'";
                $ret = false;
        } else {
                $err = "Missing extension for ".$this->dataProvider;
                $ret = 0;
        }
        if ($fn = $this->raiseErrorFn)
                $fn($this->databaseType,'CONNECT',$this->ErrorNo(),$err,$this->host,$this->database,$this);


        $this->_connectionID = false;
       
        if ($this->debug) ADOConnection::outp( $this->host.': '.$err);
        return $ret;
}
上面的方法调用了下面的方法:(adodb-ado5.inc.php文件的第65行开始)
复制内容到剪贴板
代码:
function _connect($argHostname, $argUsername, $argPassword,$argDBorProvider, $argProvider= '')
{
// two modes
//  - if $argProvider is empty, we assume that $argDBorProvider holds provider -- this is for backward compat
//  - if $argProvider is not empty, then $argDBorProvider holds db
/*
  *我们使用access的时候,我们是无法设置$argProvider,设置界面没有为它赋值的地方。
  */               
         if ($argProvider) {
                $argDatabasename = $argDBorProvider;
         } else {
                $argDatabasename = '';
   /*注意下面这句就是对$argProvider赋值,那么$argDBorProvider又是谁赋的值呢,仔细看它的值就是$databasename
    *的值。这下你该知道如何设置databasename了吧,如果还不知道,往下看
    *到这里,连接access应该是没有问题了,有问题的大家跟踪一下。
    *跟踪过程中,比较容易犯的错是下断点后,一定要回到你写的单元按F9运行,否则你的程序会出现莫名其妙的问题。
    *注意一定要回到你自己的单元,才按F9运行。
    */
        if ($argDBorProvider) $argProvider = $argDBorProvider;
        else $argProvider = 'MSDASQL';
        }


        try {
        $u = 'UID';
        $p = 'PWD';

        if (!empty($this->charPage))
                $dbc = new COM('ADODB.Connection',null,$this->charPage);
        else
                $dbc = new COM('ADODB.Connection');

        if (! $dbc) return false;

        /* special support if provider is mssql or access */
        if ($argProvider=='mssql') {
                $u = 'User Id';  //User parameter name for OLEDB
                $p = 'Password';
                $argProvider = "SQLOLEDB"; // SQL Server Provider

                // not yet
                //if ($argDatabasename) $argHostname .= ";Initial Catalog=$argDatabasename";

                //use trusted conection for SQL if username not specified
       /**如果对上面的赋值还不清楚的,看到这句该明白了,databasename的内容。。。。。**/
                if (!$argUsername) $argHostname .= ";Trusted_Connection=Yes";
        } else if ($argProvider=='access')
                $argProvider = "Microsoft.Jet.OLEDB.4.0"; // Microsoft Jet Provider

        if ($argProvider) $dbc->Provider = $argProvider;
        
        /**$argDatabasename这个值也没法在界面上赋值,所以大家干脆直接把
         *DATA SOURCE="d:/My Documents/Delphi for PHP Projects/DelphiForPHP_Test/oil_new.mdb"
         *这句写到&argHostName中就可以了,而要写入这句,只需要对界面上的host赋值就可以了。
         *目前我还没有查到为什么要这样设置,估计是为了兼容mssql而牺牲了access,毕竟用mssql的比较多,大家查查看,
         *有时间真得要对全部的源码进行分析,这个地方的赋值很容易造成误会。
         */
        if ($argDatabasename) $argHostname .= ";DATABASE=$argDatabasename";
        if ($argUsername) $argHostname .= ";$u=$argUsername";
        if ($argPassword)$argHostname .= ";$p=$argPassword";

        if ($this->debug) ADOConnection::outp( "Host=".$argHostname."<BR>\n version=$dbc->version");
        // @ added below for php 4.0.1 and earlier
        @$dbc->Open((string) $argHostname);

        $this->_connectionID = $dbc;

        $dbc->CursorLocation = $this->_cursor_location;
        return  $dbc->State > 0;
        } catch (exception $e) {
        }

        return false;
}

TOP

按照lisa888方法,将DatabaseName值设为access或者是Microsoft.Jet.OLEDB.4.0,host值设为DATA SOURCE="E:\zj\ZJProgram\DelphiForPHP\oil_new.mdb",DriverName的值设为ado_access,运行到adodb-ado5.inc.php第104行:
if ($argProvider) $argHostname="ROVIDER=$argProvider;DRIVER={SQL Server};SERVER=$argHostname";
生成$argHostname值为
PROVIDER=Microsoft.Jet.OLEDB.4.0;DRIVER={SQL Server};SERVER=DATA SOURCE="E:\zj\ZJProgram\DelphiForPHP\oil_new.mdb"

再到第13行:
@$dbc->Open((string) $argHostname);  
运行仍然会出错。

而经测试,以下语句能正常连接access。
<?php
$conn = new com("ADODB.Connection");
$connstr = "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" . realpath("netBook.mdb");
$conn->Open($connstr);
$rs = new com("ADODB.RecordSet");
$rs->Open("select * from data",$conn,1,1);
while(! $rs->eof) {
// $f = $rs->Fields(0);
// echo $f->value;
echo $rs->Fields["content"]->value."<br>";
$rs->MoveNext();
}
?>

这里的$connstr 相当于上面的 $argHostname;比较两者,还是有区别的。$argHostname中的DRIVER固定为{SQL Server},而$connstr 中的DRIVER为{Microsoft Access Driver (*.mdb)}

难道我还有哪个地方没设置对?

[ 本帖最后由 winner 于 2007-11-29 22:46 编辑 ]
附件: 您所在的用户组无法下载或查看附件

TOP

我测试你的Demo是正确的

我把你的源代码直接下下来,而且建立了一个跟你一模一样的目录,结果正常连接,数据都显示出来了。我把我的浏览器的显示结果附在后面了。
   要不把你的DFP目录里面的php.ini.template文件贴出来,或者你对一下我的php.ini.template文件。

[ 本帖最后由 lisa888 于 2007-12-3 13:58 编辑 ]
附件: 您所在的用户组无法下载或查看附件

TOP

我还有一点奇怪,我运行你的Demo会出现下面的几行文字
Host=DATA SOURCE="E:\zj\ZJProgram\DelphiForPHP\oil_new.mdb"
version=2.8

--------------------------------------------------------------------------------
(ado_access): select top 10 * from sb   

我自己写的就不会出现这个问题,感觉你的版本是不是和我的不一样啊,我用得的版本和文件已经在论坛中发了。

TOP

哦,原来是将database里面的debug设置为非零时就会显示

TOP

谢谢lisa888 !

我用的版本信息:Delphi for PHP Version  1.0.2.539 Update 2 Copyright  2007 CodeGear. All Rights Reserved.

php.ini.template和版本信息文件见附件。麻烦你再帮我看看。

你用得的版本和文件在哪里下载哦?可否给个链接地址。要不,能不能通过Email发给我

[ 本帖最后由 winner 于 2007-12-5 21:50 编辑 ]
附件: 您所在的用户组无法下载或查看附件

TOP

版本和文件都没有什么问题。
我现在也不太清楚是什么原因,但是我的一个建议是你到下面的网址去下个最新版本的ADO源码,直接覆盖DFP里面的ADO。
你的DEMO文件我试过运行是正常的。
其他的配置这截个图你看一下

[ 本帖最后由 lisa888 于 2007-12-4 14:25 编辑 ]
附件: 您所在的用户组无法下载或查看附件
有奋斗,才能有收获

TOP

引用:
原帖由 lisa888 于 2007-12-4 14:23 发表
我的一个建议是你到下面的网址去下个最新版本的ADO源码,直接覆盖DFP里面的ADO。
感谢你花时间解决我的问题。
完全照你附图配置,仍然不行。
到哪里下最新版本的ADO源码?

我的delphiforphp.exe是破解版的,是不是因为这个原因哦?破解的不好?能否把你的Delphi4PHP Email给我一下哦?

TOP

我的在本网站上已经发布了,你查查看看就知道了,ADO源码的网址如下:
http://sourceforge.net/project/showfiles.php?group_id=42718  我下的是495a的版本,直接覆盖VCL目录里面的ADODB就行了
有奋斗,才能有收获

TOP

实在不行的话,建议你装个虚拟机或是重装一下系统再看看,问题的解决因为现在资料太缺少了,所以很多都在摸索中,等过段时间把VCL源码弄弄后,可能会更清楚些。
有奋斗,才能有收获

TOP

 412 12
发新话题