【问题标题】:From PDO to SQLSRV从 PDO 到 SQLSRV
【发布时间】:2012-10-18 00:32:49
【问题描述】:

我之前在 MYSql 上使用过 PDO,但现在我需要为 PHP 使用 Microsoft SQL Server Driver。

我找到了手册。 http://php.net/manual/en/book.sqlsrv.php

我使用示例 #2 连接到新的 SQL 数据库: http://www.php.net/manual/en/function.sqlsrv-connect.php

如何“转换”以下(PDO mysql)以使用 sqlsrv:

$username = 'test';

try {
$conn = new PDO('mysql:host=$host;dbname=$database', $username, password);
$stmt = $conn->prepare('SELECT username users WHERE username = :username LIMIT 1');
$stmt->execute(array('username' => $username));

if ($stmt->rowCount() > 0) {
$result = $stmt->fetch();

    echo $result['username'];

} else {
    echo 'Nothing found.';
die();
}
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}

【问题讨论】:

  • 为什么不使用php.net/manual/en/ref.pdo-sqlsrv.php,这样它只需要对您的代码进行最少的更改?
  • 所以我只需要更改:new PDO to new PDO_SQLSRV ?
  • 不,您将需要更改 DSN(连接字符串),以通知 PDO 您需要使用 sqlsrv 驱动程序,并将正确的命名参数传递给它,例如 new PDO("sqlsrv:Server=localhost;Database=$database",$username, $password);
  • 然后它说:错误:找不到驱动程序。
  • 我认为没有 sqlsrv_connect 是不可能的

标签: php sql-server database sqlsrv


【解决方案1】:

来自 php.net

PHP 数据对象 (PDO) 扩展定义了一个轻量级的、一致的 PHP中访问数据库的接口。

既然你已经使用了 PDO for MySQL,你可以考虑像 dev-null-dweller 说的那样为 MS SQL 使用 PDO 驱动。 SQLSRV 驱动程序是访问 MS SQL 的另一种选择。但这需要彻底检查您当前的 PHP 代码。

Microsoft为MS SQL提供两种PHP驱动:

php_sqlsrv.dll 为 MS SQL 提供了一组独特的 SQLSRV API。

php_pdo_sqlsrv.dll 为 MS SQL 提供了一组大部分 PDO 兼容的 API。

下载驱动时注意你的PHP版本:

Version 4.0 supports PHP 7.0+ on Windows and Linux
Version 3.2 supports PHP 5.6, 5.5, and 5.4 on Windows
Version 3.1 supports PHP 5.5 and 5.4 on Windows
Version 3.0 supports PHP 5.4 on Windows

对于 PHP5.6,微软只提供 x86 版本的驱动程序。非官方 X64 驱动可以在 http://robsphp.blogspot.tw/2012/06/unofficial-microsoft-sql-server-driver.html

下载驱动程序后。将您需要的版本复制到您的 PHP ext 文件夹。 并将驱动名称添加到 php.ini 配置中,例如:

extension=php_pdo_sqlsrv_56_ts.dll

然后重新启动网络服务器。 如果 phpinfo() 函数显示 pdo_sqlsrv 部分,则可以确认 PDO 驱动程序安装正确。

请注意,MS 在 PDO 构造函数中使用了不同的 DSN。线

$conn = new PDO('mysql:host=$host;dbname=$database', $username, password);

应该改为

$conn = new PDO('sqlsrv:Server=$host;Database=$database', $username, password);

那么您应该不会再次遇到“错误:找不到驱动程序”。希望对您有所帮助。

【讨论】:

    【解决方案2】:

    解决连接问题后,必须将使用 MySQL SQL 方言编写的 SQL 语句转换为 T-SQL 方言(供 SQL Server 使用)。

    [1] SQL Server 没有LIMIT 子句。而且,SQL 标准中不包含该子句。相反,您可以使用ROW_NUMBER() function。但是,在这种情况下,您不必使用此功能,因为 ...

    [2] ...来自users 表的username 列应该只接受唯一值(当然,它应该是强制性的)。因此,您必须确保在 username 列上有唯一约束或唯一索引。此脚本将检查您是否在 username 列上有唯一索引:

    DECLARE @TableName SYSNAME=N'dbo.users';
    DECLARE @ColumnName SYSNAME=N'username';
    SELECT  *
    FROM    sys.indexes i
    WHERE   i.object_id=OBJECT_ID(@TableName)
    AND     i.is_unique=1
    AND     EXISTS (
        SELECT  *
        FROM    sys.index_columns ic 
        INNER JOIN sys.columns c ON c.object_id=ic.object_id
        AND     c.column_id=ic.column_id
        WHERE   i.object_id=ic.object_id
        AND     i.index_id=ic.index_id
        AND     ic.is_included_column=0
        AND     c.name=@ColumnName
    )
    AND (
        SELECT  COUNT(*)
        FROM    sys.index_columns ic 
        INNER JOIN sys.columns c ON c.object_id=ic.object_id
        AND     c.column_id=ic.column_id
        WHERE   i.object_id=ic.object_id
        AND     i.index_id=ic.index_id
        AND     ic.is_included_column=0
    )=1;
    

    [3] 如果username 列上有唯一索引,则不需要使用LIMIT 1 子句(或ROW_NUMBER() 函数),因为SQL 语句将返回总是零(最小)或一个(最大)记录。

    [4] SQL 语句应为SELECT username FROM users WHERE username = :param

    【讨论】:

    • 但是我该如何准备好声明呢?
    • @Stefan:我的回答仅涉及您问题的 SQL 方面。我不是 PHP 开发人员。检查这个link
    猜你喜欢
    • 2017-09-15
    • 1970-01-01
    • 2022-05-18
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 2013-07-06
    • 2015-10-08
    相关资源
    最近更新 更多