【问题标题】:DSN-less connection with PHP ODBC using MDBTools Driver使用 MDBTools 驱动程序与 PHP ODBC 的无 DSN 连接
【发布时间】:2012-04-22 19:51:25
【问题描述】:

我正在尝试使用 MDBTools 驱动程序从 Access 数据库中读取以在 Ubuntu 11.10 上执行 odbc_connect。使用/etc/odbc.ini中的DSN设置时,它工作正常。

以下是/etc/odbc.ini的内容:

[logindb]
Description = Microsoft Access Try DB
Driver = MDBToolsODBC
Database = /home/folder1/TestDb.mdb
Servername = localhost

odbc.ini 中的 Driver 属性引用了MDBToolsODBC,所以,这是我在/etc/odbcinst.ini 中的 odbc 设置:

[MDBToolsODBC]
Description = MDB Tools ODBC
Driver = /usr/lib/libmdbodbc.so.0
Setup =
FileUsage =
CPTimeout =
CPReuse =

我的问题是,当使用$conn = odbc_connect('logindb','',''); 时,我必须使用数据库位置的硬编码值。理想情况下,我想使用无 DSN 连接指定odbc_connect 的第一个参数,以便我的数据库文件可以是一个变量(将从不同的数据库读取)。比如:

if ($cond1) {
  $db = "/home/folder1/TestDb.mdb";
} else {
  $db = "/home/folder1/TestDb2.mdb";
}

$conn = odbc_connect("odbc:Driver={MDBToolsODBC};Dbq=$db",'','');

我也试过不带 odbc: 前缀,但没用。谁能告诉我为什么指定 DSN 有效,但是当尝试使用看起来相同的属性动态指定它时,它不起作用?我认为这与无 DSN 连接中第一个参数的参数和内容有关。与往常一样,非常感谢任何帮助。

【问题讨论】:

  • @Rocket:跟在/etc/odbc.ini里的变量名后面,不应该是Database=$db吗?
  • @eggyal:这也没有帮助。它仍然说:SQL error: [unixODBC][Driver Manager]Data source name not found, and no default driver specified.
  • @Rocket:如果你明确指定Driver=/usr/lib/libmdbodbc.so.0?
  • @eggyal:是的。 $conn = odbc_connect('logindb','',''); 工作正常。
  • @Rocket:对不起,我的意思是如果你在 DSN 中指定它:odbc_connect("Driver=/usr/lib/libmdbodbc.so.0;Database=$db",'','')?

标签: php ms-access ubuntu odbc mdbtools


【解决方案1】:
$driver = "MDBTools"; -- Driver name from /etc/odbcinst.ini
$dbName = "/path/to/database.mdb"; -- Full path of your MDB file
$db = new PDO("odbc:Driver=$driver;DBQ=$dbName", "", "");

【讨论】:

    【解决方案2】:

    在 0.7.1 中受支持。可以从 github 获取:

    https://github.com/brianb/mdbtools

    关于连接字符串,这对我有用:

    "Driver=Microsoft Access Driver (*.mdb);DBQ=///file.mdb;UID=;PWD=;"
    

    【讨论】:

    【解决方案3】:

    我认为它可能不支持它。从实际驱动程序的源代码中,您会看到它加载了需要检查的参数,检查是否已获得 DNS 字符串,接下来检查 ini 文件,如果没有出错则设置参数。

    供参考来自odbc.c最新mdb-tools (mdbtools-0.6pre1)

    SQLRETURN SQL_API SQLDriverConnect(
    SQLHDBC            hdbc,
    SQLHWND            hwnd,
    SQLCHAR FAR       *szConnStrIn,
    SQLSMALLINT        cbConnStrIn,
    SQLCHAR FAR       *szConnStrOut,
    SQLSMALLINT        cbConnStrOutMax,
    SQLSMALLINT FAR   *pcbConnStrOut,
    SQLUSMALLINT       fDriverCompletion)
    {
    SQLCHAR FAR* dsn = NULL;
    SQLCHAR FAR* database = NULL;
    ConnectParams* params;
    SQLRETURN ret;
    
    TRACE("DriverConnect");
    
    strcpy (lastError, "");
    
    params = ((ODBCConnection*) hdbc)->params;
    
    if (!(dsn = ExtractDSN (params, szConnStrIn)))
    {
      LogError ("Could not find DSN in connect string");
      return SQL_ERROR;
    }
    else if (!LookupDSN (params, dsn))
    {
      LogError ("Could not find DSN in odbc.ini");
      return SQL_ERROR;
    }
    else 
    {
      SetConnectString (params, szConnStrIn);
    
      if (!(database = GetConnectParam (params, "Database")))
      {
     LogError ("Could not find Database parameter");
     return SQL_ERROR;
      }
    }
    ret = do_connect (hdbc, database);
    return ret;
    

    那么当您在 connectparams.c 中进行验证时,ExtractDSN 会专门查找 DSN= 字符串

     gchar* ExtractDSN (ConnectParams* params, const gchar* connectString)
     {
      char *p, *q, *s;
    
      if (!params)
      return NULL;
      /*
       * Position ourselves to the beginning of "DSN"
      */
      p = strstr (connectString, "DSN");
     if (!p) return NULL;
     /*
      * Position ourselves to the "="
      */
     q = strchr (p, '=');
     if (!q) return NULL;
    

    LookupDSN 查找 inifile 或立即返回 TRUE,具体取决于 HAVE_SQLGETPRIVATEPROFILESTRING 预编译器设置。

    既然如此

    SetConnectString (params, szConnStrIn);
    

    仅适用于从前两个函数中获得的数据,我认为它不支持 DSN-less。只有正确的 DSN= 字符串或 ini 文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-11
      • 2020-10-11
      • 2014-02-21
      • 1970-01-01
      相关资源
      最近更新 更多