PDO:在一次执行 SQL INSERT 和 SELECT 多个语句后 FetchAll



我需要知道如何获取在插入语句之后执行的select语句的结果,就像在PDO中执行一样。

我的PDO连接参数如下:

$opt  = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => true];
$conn = new PDO($dsn, $user, $pass, $opt);

我有以下用于PDO语句执行的帮助程序函数:

function databaseExecute($SQL, $BIND_P, &$BIND_R) {
    global $conn;
    $stmt = $conn->prepare($SQL);
    if ($stmt->execute($BIND_P)) {
        if ($BIND_R !== false) {
            //Type testing is important here
            $tmp = $stmt->fetchAll(PDO::FETCH_ASSOC);
            $stmt->closeCursor();
            if (!$tmp || count($tmp) == 0) {
                return false;
            }
            $BIND_R = $tmp;
        } else {
            $stmt->closeCursor();
        }
        return true;
    }
    $stmt->closeCursor();
    return false;
}

我的函数本身是:

/**
 * Adds the current purchase object to the database table
 * @return true if success
 */
public function pushToDB() {
    global $tbl_purchases;
    //We don't push purchaseID since that field is auto handled by the database
    $sql    = "INSERT INTO " . $tbl_purchases . " (ProductID, UID, TID, GenDate, KeyIDs, Total, Assigned) VALUES (?, ?, ?, ?, ?, ?, ?); SELECT LAST_INSERT_ID();";
    $result = array();
    if (databaseExecute($sql, array(
        $this->getProductID(),
        $this->getUID(),
        $this->getTID(),
        $this->getGenDate(),
        $this->getKeyIDsJSON(),
        $this->getTotal(),
        $this->getAssigned(),
    ), $r)) {
        var_dump($result);
        $this->_setPurchaseID($result[0]);
        return true;
    }
    trigger_error("Purchase::pushToDB - Could not push purchase to database", E_USER_ERROR);
    return false;
}

但这会引发一个普遍的错误致命错误:未捕获的PDOException:SQLSTATE[HY000]:尝试fetchAll时出现一般错误

在这种情况下,如何获取 SQL 执行的结果?

PS:在这里使用两个执行是不可接受的。

此处不接受使用两个执行。

这只是一种错觉。

使用第二个查询或 - 更好的 - 专用函数 PDO::LastInsertId((。但是由于您的功能设计得相当糟糕,这可能是一个问题。所以是 2 个查询。

因此,请将您的函数更改为

function databaseExecute($SQL, $BIND_P = array();) {
    global $conn;
    if (!$BIND_P)
    {
        return $conn->query($SQL);
    }
    $stmt = $conn->prepare($SQL);
    $stmt->execute($BIND_P);
    return $stmt;
}

public function pushToDB() {
    global $tbl_purchases;
    //We don't push purchaseID since that field is auto handled by the database
    $sql = "INSERT INTO $tbl_purchases 
            (ProductID, UID, TID, GenDate, KeyIDs, Total, Assigned) 
            VALUES (?, ?, ?, ?, ?, ?, ?)";
    databaseExecute($sql, array(
        $this->getProductID(),
        $this->getUID(),
        $this->getTID(),
        $this->getGenDate(),
        $this->getKeyIDsJSON(),
        $this->getTotal(),
        $this->getAssigned(),
    ));
        $id = databaseExecute("SELECT LAST_INSERT_ID()")->fetchColumn();
        $this->_setPurchaseID($db);
        return true;
    }
}

您可以更改 databaseExectute 函数以采用额外的参数 'SecondResult' (例如(,然后将其更改为类似...

function databaseExecute($SQL, $BIND_P, &$BIND_R,$SecondResult) {
    global $conn;
    $stmt = $conn->prepare($SQL);
    if ($stmt->execute($BIND_P)) {
        if ($BIND_R !== false) {
            //Type testing is important here
            if ($SecondResult) $stmt->nextRowSet(); // this will ensure that the fetchAll will return the data from the 2nd query
            $tmp = $stmt->fetchAll(PDO::FETCH_ASSOC);
            $stmt->closeCursor();
            if (!$tmp || count($tmp) == 0) {
                return false;
            }
            $BIND_R = $tmp;
        } else {
            $stmt->closeCursor();
        }
        return true;
    }
    $stmt->closeCursor();
    return false;
}

只是直接在这里输入了这个,我还没有测试过它,但它应该可以工作。

另外,我并不是说其他评论是错误的,并且可能有更好的方法来做到这一点,但是您可以在同一"语句"中运行两个查询。

相关内容

  • 没有找到相关文章

最新更新