我有一个运行php的系统,我最近需要添加到MSSQL数据库的连接。我正确安装/配置了FreeTDS和UnixODBC,我可以在python中成功查询,并通过tsql和isql等实用程序。看了phpinfo()
我发现我没有'sqlsrv'部分,并且我的php扩展目录中没有mssql.so
文件。
我想将此添加到我的系统而无需重新编译/安装php。我是否能够找到并下载mssql.so
文件,将其放入我的扩展目录,将extension=/path/to/mssql.so
添加到我的php.ini
文件中,然后重新加载apache以使其正常工作?或者我需要采取更多步骤吗?
修改
系统正在使用PHP 5.2运行SLES11
编辑2:
我设法安装了php5-mssql扩展程序。我抓住了源代码,将其解压缩并复制了这些文件:
ext/mssql/config.m4
ext/mssql/php_mssql.c
ext/mssql/php_mssql.h
然后,在我将文件复制到的目录中,我运行了phpize
(您需要安装php5-devel
才能获得此工具),并按如下方式编译扩展名:
./configure --with-mssql=/usr/local/freetds
make
我还必须在php_mssql.c
中添加一行并注释掉一行才能真正正确编译(不是每个人都需要这样做):
{NULL,NULL,NULL}
/*PHP_FE_END*/
这创建了/ php_mssql / modules /中的mssql.so文件(相对于我编译代码的地方),我可以将其移动到我的扩展目录(你可以用php -i | grep extensions
找到它)。我在我的php.ini文件中添加了extension=mssql.so
;但是,phpinfo()
中仍然没有'sqlsrv部分。
某些连接方法似乎部分有效:
从shell运行以下代码时,会显示<h1>Connection Success</h1>
;但是在浏览器中打开时,mssql_connect
行之后没有显示任何内容:
<?php
//*************************************************************************
//Open Database Connection
//*************************************************************************
//phpinfo();
$dbserver="MyServer";
$dbusername="user";
$dbpassword="pass";
$defaultdb="DBName";
$cn = mssql_connect($dbserver,$dbusername,$dbpassword) or die("Connection Error");
$db = mssql_select_db($defaultdb,$cn) or die("Database Error");
echo "<h1>Connection Success</h1>";
?>
所以看起来我部分地获得连接?当我尝试使用PDO对象时,我收到另一个错误:
代码:
<?php
$con = new PDO('odbc:host=MyServer;dbname=DBName','user','pass');
?>
错误:
PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[IM002] SQLDriverConnect: 0 [unixODBC][Driver Manager]Data source name not found, and no default driver specified' in /path/to/php/file/test3.php:3
Stack trace:
#0 /path/to/php/file/test3.php(3): PDO->__construct('odbc:host=MySer...', 'user', 'pass')
#1 {main}
thrown in /path/to/php/file/test3.php on line 3
我也尝试了以下内容(假设上一代码中的PDO语句/ DSN不正确):
<?php
try {
$db = new PDO("odbc:Driver=FreeTDS; Server=MyServer; Port=1433; Database=DBName; UID=user; PWD=pass;");
} catch (PDOException $exception) {
die("$exception");
}
echo "<h1>Success!</h1>";
?>
这显示了来自shell的<h1>Success!</h1>
,但在我的网络浏览器中显示以下错误:
exception 'PDOException' with message 'SQLSTATE[08001] SQLDriverConnect: 0 [unixODBC][FreeTDS][SQL Server]Unable to connect to data source' in /path/to/php/file/test4.php:3 Stack trace: #0 /path/to/php/file/test4.php(3): PDO->__construct('odbc:Driver=Fre...') #1 {main}
答案 0 :(得分:1)
在ODBC中,错误消息包含消息开头的[]中的元素,最右边的元素是报告错误的链的一部分(请参阅ODBC Diagnostics & Error Status Codes。所以,“[unixODBC] [驱动程序管理器]未找到数据源名称,并且unixODBC未报告任何默认驱动程序.UnixODBC所说的是传递给ODBC API的字符串SQLConnect或SQLDriverConnect不识别DSN(数据源名称)或ODBC驱动程序,并且没有默认DSN已定义。您可以通过运行odbcinst -j例如
来查找数据源的定义位置$ odbcinst -j
unixODBC 2.2.14
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /home/martin/.odbc.ini
SQLULEN Size.......: 4
SQLLEN Size........: 4
SQLSETPOSIROW Size.: 2
此处,驱动程序在/etc/odbcinst.ini中定义,/ etc / odbc.ini中的系统数据源和/home/martin/.odbc.ini中的用户数据源。因为你可能在网络服务器下运行PHP,如果我是你,我会坚持使用系统数据源。您可以使用odbcinst -q -l -s列出系统数据源。您可以在Linux/UNIX ODBC找到关于Linux / ODBC的非常好的解释。
您的第二个错误“[unixODBC] [FreeTDS] [SQL Server]无法连接到数据源”由FreeTDS的SQL Server驱动程序报告,因此在这种情况下,您必须已将足够的信息传递给unixODBC以至少允许它识别驱动程序,加载它并在其中调用SQLConnect / SQLDriverConnect。您可以通过在unixODBC中启用跟踪来查看传递给unixODBC的SQLConnect / SQLDriverConnect的内容。您可以通过编辑odbcinst.ini文件(使用上面的odbcinst -j命令找到)并在其顶部添加以下内容来启用对unixODBC的跟踪:
[ODBC]
Trace = yes
TraceFile = /tmp/unixodbc.log
现在,当您运行php示例时,它将记录到/tmp/unixodbc.log所有ODBC API调用,您要查找的是SQLConnect或SQLDriverConnect。例如,当我使用用户名和密码XXX和YYY连接到名为mydsn的DSN时,我看到:
[ODBC][31521][1374740062.012973][SQLDriverConnect.c][687]
Entry:
Connection = 0x9d7d430
Window Hdl = (nil)
Str In = [DSN=mydsn;UID=XXX;PWD=********][length = 29]
Str Out = 0xbfdeb83c
Str Out Max = 512
Str Out Ptr = 0xbfdeb638
Completion = 0
UNICODE Using encoding ASCII 'ISO8859-1' and UNICODE 'UCS-2LE'
DIAG [01000] [Easysoft][SQL Server Driver][SQL Server]Changed database context to 'master'.
DIAG [01000] [Easysoft][SQL Server Driver][SQL Server]Changed language setting to us_english.
注意,此连接成功,它清楚地显示连接字符串的一部分是DSN = mydsn,而mydsn在我的/etc/odbcinst.ini中作为DSN存在。
isql可以与某些启用ODBC的应用程序不同,因为isql调用ODBC API SQLConnect,而现在大多数ODBC应用程序都支持ODBC 3并使用SQLDriverConnect。主要区别在于SQLConnect仅提供3个参数,DSN名称,用户名和密码,其中SQLDriverConnect被赋予定义连接的单个属性/值对字符串。我只告诉你这个,所以你知道isql如何工作以及其他不可能的工作。
然而,在第二种情况下,当你检查你的跟踪时,你会看到unixODBC有足够的东西来识别驱动程序,加载它并调用freeTDS的ODBC驱动程序,错误“无法连接到数据源”来自freeTDS 。所以,我建议您的DSN可能正常,并且您的freetds.conf在某种程度上是不正确的。由于我自己不使用freeTDS,我不确定,但我听说你可以使用ODBC与freeTDS,而无需参考freetds.conf文件和基于你是否使用Server或ServerName的交换机。我确信freeTDS网站上有很多例子。
答案 1 :(得分:0)
以下是我从LAMP(Ubuntu)堆栈连接到MS SQL服务器的方法:
/etc/odbc.ini
# Define a connection to a Microsoft SQL server
# The Description can be whatever we want it to be.
# The Driver value must match what we have defined in /etc/odbcinst.ini
# The Database name must be the name of the database this connection will connect to.
# The ServerName is the name we defined in /etc/freetds/freetds.conf
# The TDS_Version should match what we defined in /etc/freetds/freetds.conf
[mssql]
Description = MSSQL Server
Driver = freetds
Database = XXXXXX
ServerName = MSSQL
TDS_Version = 8.0
/etc/odbcinst.ini
# Define where to find the driver for the Free TDS connections.
[freetds]
Description = MS SQL database access with Free TDS
Driver = /usr/lib/i386-linux-gnu/odbc/libtdsodbc.so
Setup = /usr/lib/i386-linux-gnu/odbc/libtdsS.so
UsageCount = 1
/etc/freetds/freetds.conf
# The basics for defining a DSN (Data Source Name)
# [data_source_name]
# host = <hostname or IP address>
# port = <port number to connect to - probably 1433>
# tds version = <TDS version to use - probably 8.0>
# Define a connection to the Microsoft SQL Server
[mssql]
host = XXXXXX
port = 1433
tds version = 8.0
这是PHP代码:
$con = new PDO('dblib:host=mssql;dbname=MyDB', 'domain\username', 'password');
您可能需要为您的操作系统稍微调整一下。要在Ubuntu上安装必要的软件,我做了类似的事情:
sudo apt-get install php5-odbc php5-sybase tdsodbc
答案 2 :(得分:-1)
使用PDO并安装此http://www.php.net/manual/en/ref.pdo-sqlsrv.php
我总是使用PDO它可以轻松地与不同的数据库驱动程序和相同的PHP代码进行所需的所有数据库交互。除了查询语言有时有点不同。
对于MSSQL,您只需要添加驱动程序,只需粘贴.dll,将条目添加到conf.ini并重新启动apache。