作者共發了64篇帖子。 內容轉換:不轉換▼
 
點擊 回復
3843 66
今天我來系統地學習一下PDO
一派護法 十九級
32樓 發表于:2015-5-30 21:22

回復:31樓

非變量可以直接寫入SQL語句

一派護法 十九級
33樓 發表于:2015-5-30 21:28
不過這樣的話,就無法得到生成的SQL字符串了。。。
一派護法 十九級
34樓 發表于:2015-5-30 21:30
$address = "Delaware St";

$sql = "SELECT * FROM WiFiHotSpots WHERE ItemName = ? AND ItemID < 15 AND ItemAddress = ?";
$stmt = $dbh->prepare($sql);
$stmt->execute(array($name, $address));
$row = $stmt->fetch();
echo "(" . $row["ItemLatitude"] . ", " . $row["ItemLongitude"] . ")";
一派護法 十九級
35樓 發表于:2015-5-30 21:38
判斷記錄集是否為空:
if (!$stmt->rowCount()) {
  echo "記錄集為空";
}
一派護法 十九級
36樓 發表于:2015-5-30 21:39
$stmt->rowCount()可以直接當布爾值用。
一派護法 十九級
37樓 發表于:2015-5-30 21:41
原始方法:
if (mysql_num_rows($rs) == 0) {
echo "記錄集為空";
}
一派護法 十九級
38樓 發表于:2015-5-30 21:46
回復:33樓
http://php.net/manual/en/pdostatement.debugdumpparams.php
debugDumpParams可以用來輸出SQL及其參數,但是無法產生目標SQL。

一派護法 十九級
39樓 發表于:2015-5-30 21:49
Error SQL query:

SELECT * FROM WiFiHotSpots WHERE ItemName = ? AND ItemID < 15 AND ItemAddress = ? LIMIT 0, 25
MySQL said:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '? AND ItemID < 15 AND ItemAddress = ?
LIMIT 0, 25' at line 1
一派護法 十九級
40樓 發表于:2015-5-30 22:07
bindColumn的用法:
<?php
include_once("conn.php");

$sql = "SELECT * FROM WiFiHotSpots";
$stmt = $dbh->prepare($sql);
$stmt->execute();

$stmt->bindColumn("ItemSuburb", $suburb);
foreach ($stmt as $row) {
    echo $suburb . "<br>";
    // $suburb is equivalent to $row["ItemSuburb"]
}
?>
一派護法 十九級
41樓 發表于:2015-5-30 22:08
bindColumn將一個字段綁定到一個php變量中,也就是每次循環自動執行:
$suburb = $row["ItemSuburb"]
一派護法 十九級
42樓 發表于:2015-5-30 22:12
$stmt->bindColumn("ItemSuburb", $suburb, PDO::PARAM_STR);
相當於$suburb = (string)$row["ItemSuburb"];
一派護法 十九級
43樓 發表于:2015-5-30 22:21
回復:33樓
為了排查SQL的錯誤,可以使用errorInfo直接獲取MySQL輸出的錯誤信息,不用再把輸出的SQL語句複製到PMA中執行了。
比如:
$sql = "SELECT * AFROM WiFiHotSpots";
$dbh->query($sql);
$error = $dbh->errorInfo();
echo $error[2];
輸出:
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'AFROM WiFiHotSpots' at line 1

一派護法 十九級
44樓 發表于:2015-5-30 22:22
回復:43樓
這樣我們就可以直接看出這個SQL語句中的AFROM出問題了
一派護法 十九級
45樓 發表于:2015-5-30 22:25
bindParam用於給SQL語句中帶有冒號或問號的佔位符賦值。
http://php.net/manual/en/pdostatement.bindparam.php
一派護法 十九級
46樓 發表于:2015-5-30 22:27
方法 bindParam() 和 bindValue() 非常相似。
 唯一的区别就是前者使用一个PHP变量绑定参数,而后者使用一个值。
所以使用bindParam是第二个参数只能用变量名,而不能用变量值,而bindValue至可以使用具体值。
http://www.360doc.com/content/12/0703/16/10337467_222033042.shtml
一派護法 十九級
48樓 發表于:2015-5-30 22:29
fetch();和mysql_fetch_array();一樣
但fetchAll();返回一個二維數組,可以獲取所有行。
一派護法 十九級
49樓 發表于:2015-5-30 22:31
以後要排查sql的錯誤直接用errorInfo,不要再把SQL語句複製到PMA里執行了。而且也沒有辦法獲得最終的SQL語句。
一派護法 十九級
51樓 發表于:2015-5-31 08:15
我還是要硬着頭皮看英文版的PHP文檔,雖然閱讀速度比中文慢了很多,但這是一個適應的過程。
一派護法 十九級
52樓 發表于:2015-5-31 08:16
PDO — The PDO class

PDO::beginTransaction — Initiates a transaction
PDO::commit — Commits a transaction
PDO::__construct — Creates a PDO instance representing a connection to a database
PDO::errorCode — Fetch the SQLSTATE associated with the last operation on the database handle
PDO::errorInfo — Fetch extended error information associated with the last operation on the database handle
PDO::exec — Execute an SQL statement and return the number of affected rows
PDO::getAttribute — Retrieve a database connection attribute
PDO::getAvailableDrivers — Return an array of available PDO drivers
PDO::inTransaction — Checks if inside a transaction
PDO::lastInsertId — Returns the ID of the last inserted row or sequence value
PDO::prepare — Prepares a statement for execution and returns a statement object
PDO::query — Executes an SQL statement, returning a result set as a PDOStatement object
PDO::quote — Quotes a string for use in a query.
PDO::rollBack — Rolls back a transaction
PDO::setAttribute — Set an attribute
PDOStatement — The PDOStatement class

PDOStatement::bindColumn — Bind a column to a PHP variable
PDOStatement::bindParam — Binds a parameter to the specified variable name
PDOStatement::bindValue — Binds a value to a parameter
PDOStatement::closeCursor — Closes the cursor, enabling the statement to be executed again.
PDOStatement::columnCount — Returns the number of columns in the result set
PDOStatement::debugDumpParams — Dump an SQL prepared command
PDOStatement::errorCode — Fetch the SQLSTATE associated with the last operation on the statement handle
PDOStatement::errorInfo — Fetch extended error information associated with the last operation on the statement handle
PDOStatement::execute — Executes a prepared statement
PDOStatement::fetch — Fetches the next row from a result set
PDOStatement::fetchAll — Returns an array containing all of the result set rows
PDOStatement::fetchColumn — Returns a single column from the next row of a result set
PDOStatement::fetchObject — Fetches the next row and returns it as an object.
PDOStatement::getAttribute — Retrieve a statement attribute
PDOStatement::getColumnMeta — Returns metadata for a column in a result set
PDOStatement::nextRowset — Advances to the next rowset in a multi-rowset statement handle
PDOStatement::rowCount — Returns the number of rows affected by the last SQL statement
PDOStatement::setAttribute — Set a statement attribute
PDOStatement::setFetchMode — Set the default fetch mode for this statement
一派護法 十九級
53樓 發表于:2015-5-31 08:56
exec的用法:
$sql = "INSERT INTO `timetest` VALUES (null, NOW())";
$num = $dbh->exec($sql);
echo "影響了{$num}行。";

輸出:影響了1行。
一派護法 十九級
54樓 發表于:2015-5-31 08:58
$sql = "INSERT INTO `timetest` VALUES (null, NOW())";
$successful = $dbh->exec($sql);
if ($successful) {
    echo "插入記錄成功";
}
一派護法 十九級
55樓 發表于:2015-5-31 08:59
回復:54樓
這段代碼如果改寫成mysql原來的代碼,就很複雜,除了執行mysql_query($sql),還需要執行mysql_affected_rows()
因為對於插入、刪除、修改的SQL語句,mysql_query始終返回true
一派護法 十九級
56樓 發表于:2015-5-31 09:03
PDO::query() returns a PDOStatement object, or FALSE on failure.
query主要用於SELECT語句,返回PDOStatement對象
一派護法 十九級
57樓 發表于:2015-5-31 09:14
$content = join(", ", PDO::getAvailableDrivers());
if (!empty($content)) {
    $sql = "INSERT INTO Contents (Content, TimeCreated) VALUES (:content, NOW())";
    $stmt = $dbh->prepare($sql);
    $stmt->bindParam(":content", $content);
    $successful = $stmt->execute();
    if ($successful) {
        $num = $stmt->rowCount();
        echo "插入了{$num}條記錄。";
    } else {
        echo "插入記錄失敗!";
    }
} else {
    echo "沒有內容";
}
一派護法 十九級
58樓 發表于:2015-5-31 09:17
$content = join(", ", PDO::getAvailableDrivers());
if (!empty($content)) {
    $sql = "SELECT * FROM Contents WHERE Content = ?";
    $stmt = $dbh->prepare($sql);
    $stmt->execute(array($content));
    if ($stmt->rowCount()){
        echo "數據表中已經有相同的內容了。";
    } else {
        $sql = "INSERT INTO Contents (Content, TimeCreated) VALUES (:content, NOW())";
        $stmt = $dbh->prepare($sql);
        $stmt->bindParam(":content", $content);
        $successful = $stmt->execute();
        if ($successful) {
            $num = $stmt->rowCount();
            echo "插入了{$num}條記錄。";
        } else {
            echo "插入記錄失敗!";
        }
    }
} else {
    echo "沒有內容";
}
一派護法 十九級
59樓 發表于:2015-5-31 09:19
bindValue的用法
$sql = "SELECT * FROM Contents WHERE Content = ?";
    $stmt = $dbh->prepare($sql);
    $stmt->bindValue(1, $content);
    $stmt->execute();
一派護法 十九級
60樓 發表于:2015-5-31 09:24
對於$stmt->queryString這個屬性,輸出內容如下:
INSERT INTO Contents (Content, TimeCreated) VALUES (:content, NOW())
也就是語句中仍然沒有包含具體的值。

if ($successful) {
            $num = $stmt->rowCount();
            echo "插入了{$num}條記錄。<br>";
            echo $stmt->queryString;
        } else {
            echo "插入記錄失敗!";
        }
一派護法 十九級
61樓 發表于:2015-5-31 09:28
$dbh->beginTransaction();
$content = "數據表中已經有相同的內容了。";
if (!empty($content)) {
    $sql = "SELECT * FROM Contents WHERE Content = ?";
    $stmt = $dbh->prepare($sql);
    $stmt->execute(array($content));
    /*$stmt->bindValue(1, $content);
    $stmt->execute();*/
    if ($stmt->rowCount()){
        echo "數據表中已經有相同的內容了。";
    } else {
        $sql = "INSERT INTO Contents (Content, TimeCreated) VALUES (:content, NOW())";
        $stmt = $dbh->prepare($sql);
        $stmt->bindParam(":content", $content);
        $successful = $stmt->execute();
        
        $dbh->rollBack();
        echo "rollback";
        
        /*if ($successful) {
            $num = $stmt->rowCount();
            echo "插入了{$num}條記錄。";
            //echo $stmt->queryString;
        } else {
            echo "插入記錄失敗!";
        }*/
    }
} else {
    echo "沒有內容";
}
一派護法 十九級
62樓 發表于:2015-5-31 09:30
發現一個嚴重的問題,雖然rollback了,但是AUTO_INCREMENT卻增加了!!!!
一派護法 十九級
63樓 發表于:2015-5-31 09:31

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
(快捷鍵:Ctrl+Enter)
 

本帖信息

點擊數:3843 回複數:66
評論數: ?
作者:巨大八爪鱼
最後回復:巨大八爪鱼
最後回復時間:2015-5-31 12:24
 
©2010-2024 Arslanbar Ver2.0
除非另有聲明,本站採用創用CC姓名標示-相同方式分享 3.0 Unported許可協議進行許可。