使用 PHP 和 MSSQL 准备好的语句

Posted

技术标签:

【中文标题】使用 PHP 和 MSSQL 准备好的语句【英文标题】:Prepared statement with PHP and MSSQL 【发布时间】:2018-08-13 15:17:33 【问题描述】:

我有一个关于 pdos 的奇怪场景。使用准备好的语句,我从数据库中得到 0 个结果。但是硬编码我得到了正常的结果。这是对 mssql (

Prepared 语句(只是不要怀疑 top 和 offset 变量。我在函数中设置它们只是为了测试目的。还为 *** 编辑了 $conn。prepare 函数可以从函数中访问,所以有没问题):

public function myFunction($top, $offset) 
    try 
        $top = 20;
        $offset = 1;

        $sql = "SELECT TOP :top * FROM (
            SELECT *, ROW_NUMBER() OVER (ORDER BY id) AS t1
            FROM myTable) AS nU WHERE t1 >= :offset";

        $statement = $conn->prepare($sql);
        $statement->execute(array(':top' => $top, ':offset' => $offset));

        return $statement->fetchAll();

     catch (Exception $e) 
        echo $e->getMessage();
    

结果是一个包含 0 个元素的数组。

但是有了这个,它就可以完美地工作了:

public function myFunction($top, $offset) 
    try 
        $top = 20;
        $offset = 1;

        $sql = "SELECT TOP 20 * FROM (
            SELECT *, ROW_NUMBER() OVER (ORDER BY id) AS t1
            FROM myTable) AS nU WHERE t1 >= 1";

        $statement = $conn->prepare($sql);
        $statement->execute();

        return $statement->fetchAll();

     catch (Exception $e) 
        echo $e->getMessage();
    

这样我得到了正确的结果。

这怎么可能?准备好的陈述有什么问题?我有很多准备好的语句,之前效果很好。

感谢您的回答。

@EDIT - 更新代码 - 仍然工作:

public function myFunction($top, $offset) 
    try 
        $top = 20;
        $offset = 1;

        $sql = "SELECT TOP :top * FROM (
            SELECT *, ROW_NUMBER() OVER (ORDER BY id) AS t1
            FROM myTable) AS nU WHERE t1 >= :offset";

        $statement = $conn->prepare($sql);

        $statement->bindParam(':top', $top, PDO::PARAM_INT);
        $statement->bindParam(':offset', $offset, PDO::PARAM_INT);

        $statement->execute();
        return $statement->fetchAll();
     catch (Exception $e) 
        echo $e->getMessage();
    

【问题讨论】:

我认为TOP 需要一个 int 并且您正在向它传递一个字符串(使用准备好的语句)。 var_dump($statement->execute()); prolly 输出错误 尝试打印sql查询。 This link 可能会有所帮助。 @bassxzero:是的,它输出错误。但是 $statement->bindValue(':top', (int) $top, PDO::PARAM_INT); $statement->bindValue(':offset', (int) $offset, PDO::PARAM_INT);也不行 '.$top.' 替换:top 在这里没有帮助吗?还是我很傻 【参考方案1】:

不允许在 PDO 中将参数绑定用于 sql 查询的 SELECT 和 FROM 部分。

我用另一个不需要设置 TOP 的查询替换了整个查询

【讨论】:

以上是关于使用 PHP 和 MSSQL 准备好的语句的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在没有准备好的语句(Node.js 和 MSSQL)的情况下防止 SQL 注入

将 MSSQL 准备好的语句迁移到 MariaDB

mssql-jdbc MS SQL Server JDBC 驱动程序准备好的语句缓存性能问题与 Hikari CP

在 PHP 中到处使用准备好的语句? (PDO)

在 SQLite3 和 PHP 中使用准备好的语句

什么时候在 PHP Mysqli 中使用准备好的语句? - 用户表单搜索输入与选择查询