PHP 日本研討會 2024

mysql_query

(PHP 4, PHP 5)

mysql_query傳送 MySQL 查詢

警告

這個擴展在 PHP 5.5.0 中已被棄用,並在 PHP 7.0.0 中被移除。應該改用 MySQLiPDO_MySQL 擴展。另請參閱 MySQL:選擇 API 指南。此函數的替代方案包括

描述

mysql_query(string $query, resource $link_identifier = NULL): mixed

mysql_query() 會將唯一的查詢(不支援多個查詢)傳送到與指定的 link_identifier 相關聯的伺服器上目前活動的資料庫。

參數

query

SQL 查詢

查詢字串不應以分號結尾。查詢中的資料應適當逸出

link_identifier

MySQL 連線。如果未指定連線識別符號,則會假設為上次由 mysql_connect() 開啟的連線。如果找不到此類連線,它會嘗試建立一個,如同已呼叫不帶參數的 mysql_connect() 一樣。如果找不到或建立連線,則會產生 E_WARNING 層級的錯誤。

回傳值

對於 SELECT、SHOW、DESCRIBE、EXPLAIN 和其他傳回結果集的語句,mysql_query() 在成功時會傳回 resource,在錯誤時則傳回 false

對於其他類型的 SQL 語句,INSERT、UPDATE、DELETE、DROP 等,mysql_query() 在成功時會傳回 true,在錯誤時則傳回 false

傳回的結果資源應傳遞給 mysql_fetch_array() 和其他處理結果表的函數,以存取傳回的資料。

使用 mysql_num_rows() 找出 SELECT 語句傳回的列數,或使用 mysql_affected_rows() 找出 DELETE、INSERT、REPLACE 或 UPDATE 語句影響的列數。

如果使用者沒有權限存取查詢引用的表,mysql_query() 也會失敗並傳回 false

範例

範例 1:無效查詢

以下查詢在語法上無效,因此 mysql_query() 會失敗並傳回 false

<?php
$result
= mysql_query('SELECT * WHERE 1=1');
if (!
$result) {
die(
'無效查詢:' . mysql_error());
}

?>

範例 2:有效查詢

以下查詢有效,因此 mysql_query() 會傳回 resource

<?php
// 這可以由使用者提供,例如
$firstname = 'fred';
$lastname = 'fox';

// 擬定查詢
// 這是執行 SQL 查詢的最佳方式
// 如需更多範例,請參閱 mysql_real_escape_string()
$query = sprintf("SELECT firstname, lastname, address, age FROM friends
WHERE firstname='%s' AND lastname='%s'"
,
mysql_real_escape_string($firstname),
mysql_real_escape_string($lastname));

// 執行查詢
$result = mysql_query($query);

// 檢查結果
// 這會顯示傳送至 MySQL 的實際查詢和錯誤。對除錯很有用。
if (!$result) {
$message = '無效查詢:' . mysql_error() . "\n";
$message .= '完整查詢:' . $query;
die(
$message);
}

// 使用結果
// 嘗試列印 $result 無法存取資源中的資訊
// 必須使用其中一個 mysql 結果函數
// 另請參閱 mysql_result()、mysql_fetch_array()、mysql_fetch_row() 等。
while ($row = mysql_fetch_assoc($result)) {
echo
$row['firstname'];
echo
$row['lastname'];
echo
$row['address'];
echo
$row['age'];
}

// 釋放與結果集相關聯的資源
// 這會在腳本結束時自動完成
mysql_free_result($result);
?>

參見

新增筆記

使用者貢獻的筆記 15 則筆記

12
jack dot whoami at gmail dot com
17 年前
使用 mysql 模擬應用程式鎖的原子操作。

$link = mysql_connect('localhost', 'user', 'pass');
if (!$link) {
die('未連線:' . mysql_error());
}

// 將 foo 作為目前的資料庫
$db_selected = mysql_select_db('foo', $link);
if (!$db_selected) {
die ('無法使用 foo:' . mysql_error());
}

$q = "update `table` set `LOCK`='F' where `ID`='1'";
$lock = mysql_affected_rows();

如果我們假設
未鎖定 = "" (空字串)
已鎖定 = 'F'

接著,如果 LOCK 欄位的值不是 F(通常應該是空字串),更新語句會將其設為 F,並將受影響的列數設為 1。這表示我們取得了鎖。
如果受影響的列數回傳 0,則表示該欄位的值已經是 F,且其他人已持有鎖。

祕訣在於以下取自 MySQL 手冊的敘述:
「如果您將一個欄位設定為它目前的值,MySQL 會注意到這一點,並且不會更新它。」

當然,如果所有應用程式程序都同意鎖定演算法,這一切才有可能實現。
7
halion at gmail dot com
17 年前
mysql_query 不支援多個查詢,一個解決方法是使用 InnoDB 和交易。

這個資料庫類別/函式會接受一個查詢陣列的陣列,它會自動檢查資料庫中每一行的受影響列數,如果其中一個是 0,它將會回滾並返回 false,否則它將提交並返回 true。該函式的呼叫很簡單且易於閱讀等等。
----------

class MySQLDB
{
private $connection; // MySQL 資料庫連線

/* 類別建構子 */
function MySQLDB(){
/* 建立資料庫連線 */
$this->connection = mysql_connect(DB_SERVER, DB_USER, DB_PASS) or die(mysql_error());
mysql_select_db(DB_NAME, $this->connection) or die(mysql_error());
}

/* 交易函式 */

function begin(){
$null = mysql_query("START TRANSACTION", $this->connection);
return mysql_query("BEGIN", $this->connection);
}

function commit(){
return mysql_query("COMMIT", $this->connection);
}

function rollback(){
return mysql_query("ROLLBACK", $this->connection);
}

function transaction($q_array){
$retval = 1;

$this->begin();

foreach($q_array as $qa){
$result = mysql_query($qa['query'], $this->connection);
if(mysql_affected_rows() == 0){ $retval = 0; }
}

if($retval == 0){
$this->rollback();
return false;
}else{
$this->commit();
return true;
}
}

};

/* 建立資料庫連線物件 */
$database = new MySQLDB;

// 然後從其他任何地方,只需將交易查詢放在一個或多個陣列中,如下所示

function function(){
global $database;

$q = array (
array("query" => "UPDATE table WHERE something = 'something'"),
array("query" => "UPDATE table WHERE something_else = 'something_else'"),
array("query" => "DELETE FROM table WHERE something_else2 = 'something_else2'"),
);

$database->transaction($q);

}
2
Anonymous
18 年前
如果您像我一樣來自 Perl,您可能不喜歡使用 sprintf 來「模擬」Perl 的 DBI 套件提供的佔位符。我為 mysql_query() 建立以下包裝函式,允許您使用 '?' 字元來替換資料庫查詢中的值。請注意,這不是 Perl 中 DBI 處理佔位符的方式,但它非常相似。

<?php
// mysql_query() 包裝函式。接受兩個參數。第一個
// 是帶有 '?' 佔位符的查詢。第二個參數
// 是一個陣列,包含要替換佔位符的值(當然是有順序的)。
function mysql_prepare ($query, $phs = array()) {
foreach (
$phs as $ph) {
$ph = "'" . mysql_real_escape_string($ph) . "'";
$query = substr_replace(
$query, $ph, strpos($query, '?'), 1
);
}

return
mysql_query($query);
}

// 使用範例
list($user, $passwd) = array('myuser', 'mypass');

$sth = mysql_prepare(
'select userid from users where userid=? and passwd=?',
array(
$user, sha1($passwd))
);
$row = mysql_fetch_row($sth);

// 成功的使用者名稱和密碼驗證
if ($row !== false) {
echo
"logging in as '{$row[0]}'!\n";
}

// 喔喔,錯誤的使用者 ID 或密碼
else {
echo
"Invalid username and password combination.\n";
}
?>
-1
fbraz3 at gmail dot com
6 年前
這個專案實作了 PHP7.0+ 中 mysql 函式的包裝器。

https://github.com/OOPS-ORG-PHP/mysql-extension-wrapper

測試過且運作正常 =)
-1
Mr. Tim
16 年前
應該注意的是,mysql_query 可以產生 E_WARNING(未記錄)。我遇到的警告是當資料庫使用者沒有執行 UDF 的權限時。

預期的行為會像無效的 SQL 語句一樣,其中 mysql_query 不會產生 E_WARNING。

Warning: mysql_query() [function.mysql-query]: 無法儲存結果集在 filename.php 中

mysql_errno 是 1370,而 mysql_error 是

execute command denied to user 'username'@'%' for routine 'database_name.MyUDF'
-2
ialsoagree
15 年前
當您執行 select 語句並收到回應時,無論欄位的資料類型為何,回應的資料類型都會是字串。

<?php
// 查詢以選取 int 欄位
$query = 'SELECT user_id FROM users WHERE user_id = 1';
$result = mysql_query($query);
$array = mysql_fetch_assoc($result);

// 輸出:string
echo gettype($array['user_id']);
?>
-2
nikhil-php at nols dot com
24 年前
當嘗試 INSERT 或 UPDATE 並嘗試將大量的文字或資料 (blob) 放入 mysql 資料表時,您可能會遇到問題。

在 mysql.err 中,您可能會看到
封包過大 (73904)

若要修正此問題,您只需使用選項 -O max_allowed_packet=maxsize 來啟動 mysql

您只需將 maxsize 替換為您要插入的最大大小,預設值為 65536
-3
masteracc0 at aol dot com
17 年前
請記住,在處理 PHP 和 MySQL 時,如果使用 PHP 中的 echo($sql),將空值終止字串傳送到 MySQL 查詢可能會產生誤導,因為空值終止符可能不可見。

例如(這假設已建立連線),
$string1 = "mystring\0";
$string2 = "mystring";

$query1 = "SELECT * FROM table WHERE mystring='".$string1."'";
$query2 = "SELECT * FROM table WHERE mystring='".$string2."'";

$result1 = mysql_query($query1);

$result2 = mysql_query($query2);

//$result1 不等於 $result2 但不會提供錯誤

//但是將這些查詢列印到螢幕上會提供相同的結果
echo($result1);
echo($result2);

不了解這一點可能會導致在處理任何帶有空值終止符的字串時出現令人頭痛的疑難排解。所以現在您知道了!:)
-4
ddlshack [at] gmail.dot.com
13 年前
使用此方法可將資料整潔地插入 mysql 資料表

<?php
function mysql_insert($table, $inserts) {
$values = array_map('mysql_real_escape_string', array_values($inserts));
$keys = array_keys($inserts);

return
mysql_query('INSERT INTO `'.$table.'` (`'.implode('`,`', $keys).'`) VALUES (\''.implode('\',\'', $values).'\')');
}
?>

例如

<?php

mysql_insert
('cars', array(
'make' => 'Aston Martin',
'model' => 'DB9',
'year' => '2009',
));
?>
-3
davidc at edeca dot net
21 年前
關於傳回 enum 欄位所有可能值的想法,MySQL 手冊說明應該使用「SHOW COLUMNS FROM table LIKE column」來執行此操作。

以下函式(假設已建立資料庫連線)將傳回 enum 的可能值陣列。

function GetEnumValues($Table,$Column)
{
$dbSQL = "SHOW COLUMNS FROM ".$Table." LIKE '".$Column."'";
$dbQuery = mysql_query($dbSQL);

$dbRow = mysql_fetch_assoc($dbQuery);
$EnumValues = $dbRow["Type"];

$EnumValues = substr($EnumValues, 6, strlen($EnumValues)-8);
$EnumValues = str_replace("','",",",$EnumValues);

return explode(",",$EnumValues);
}

注意事項

1) 如果 LIKE 比對到一個以上的欄位,您會從第一個取得 enum,因此請小心 $Column 參數
2) 您不能將 ',' 作為其中一個 enum 的一部分(我猜 MySQL 會逸出它,但我沒有嘗試過)
3) 如果欄位不是 enum,您會得到垃圾資料!

這只是一個快速範例,說明如何執行此操作,在它變得完美之前,需要進行一些整理(例如檢查欄位是否實際為 enum)。
-3
Anonymous
21 年前
在該函式禁止它們之前,請注意輸入中的 SQL 註解 (--)。
-4
rob desbois
18 年前
請注意,mysql 客戶端程式中使用的 'source' 命令並*不是*伺服器的功能,而是客戶端的功能。
這表示您無法執行
mysql_query('source myfile.sql');
您會收到語法錯誤。請改用 LOAD DATA INFILE 作為替代方案。
-4
php at arcannon dot com
19 年前
我認為 celtic at raven-blue dot com 版本中有一個錯字,應該是

if (($sql != "") && (substr($tsl, 0, 2) != "--") && (substr($tsl, 0, 1) != "#")) {

我認為您真正的意思是

if (($tsl != "") && (substr($tsl, 0, 2) != "--") && (substr($tsl, 0, 1) != "#")) {

我將 $sql 改為 $tsl
-5
veyita_angi at hotmail dot com
18 年前
這可能是一個不錯的方法,可以從具有外鍵的兩個表格中印出值。我尚未正確測試,但它應該可以正常運作。

$buscar = mysql_query("SELECT k.*, e.Clasificacion FROM cat_plan_k k, cat_equipo e WHERE Tipo='$tipo' AND k.ID_Eq=a.ID_Eq");
while ($row=mysql_fetch_array($buscar))
{
$nombre = "e.Clasificacion";
$row[$nombre] = $Clasific; echo $row[$nombre].'convertido en '.$Clasific;
}
mysql_free_result($buscar);
-5
cc+php at c2se dot com
18 年前
這是一個類似於 pg_query_params 的 MySQL 參數化查詢函數。我已經使用類似的方法一段時間了,雖然速度略有下降,但它遠比在查詢中錯誤地跳脫參數並允許對您的伺服器進行 SQL 注入攻擊要好得多。

<?php # MySQL 的參數化查詢實作 (類似於 PostgreSQL 的 PHP 函數 pg_query_params)
# 範例:mysql_query_params( "SELECT * FROM my_table WHERE col1=$1 AND col2=$2", array( 42, "It's ok" ) );

if( !function_exists( 'mysql_query_params' ) ) {

function
mysql_query_params__callback( $at ) {
global
$mysql_query_params__parameters;
return
$mysql_query_params__parameters[ $at[1]-1 ];
}

function
mysql_query_params( $query, $parameters=array(), $database=false ) {

// 根據需要跳脫參數,並為回呼函式建立參數
global $mysql_query_params__parameters;
foreach(
$parameters as $k=>$v )
$parameters[$k] = ( is_int( $v ) ? $v : ( NULL===$v ? 'NULL' : "'".mysql_real_escape_string( $v )."'" ) );
$mysql_query_params__parameters = $parameters;

// 使用 mysql_query 呼叫
if( false===$database )
return
mysql_query( preg_replace_callback( '/\$([0-9]+)/', 'mysql_query_params__callback', $query ) );
else return
mysql_query( preg_replace_callback( '/\$([0-9]+)/', 'mysql_query_params__callback', $query ), $database );

}
}

?>
To Top