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(
'Invalid query: ' . 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 = 'Invalid query: ' . mysql_error() . "\n";
$message .= 'Whole query: ' . $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);
?>

参见

添加注释

用户贡献的注释 26 个注释

12
jack dot whoami at gmail dot com
17 年前
使用 mysql 模拟用于应用程序锁的原子操作。

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

// 使 foo 成为当前数据库
$db_selected = mysql_select_db('foo', $link);
if (!$db_selected) {
die ('Can\'t use 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。对该函数的调用非常简单,易于阅读等。
----------

类 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
匿名
18 年前
如果您像我一样,来自 perl,您可能不喜欢使用 sprintf 来“模拟”perl 中 DBI 包提供的占位符。我为 mysql_query() 创建了以下包装器函数,允许您使用“?”字符来替换 DB 查询中的值。请注意,这不是 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
"以 '{$row[0]}' 登录!\n";
}

// 哎呀,错误的用户名或密码
else {
echo
"无效的用户名和密码组合。\n";
}
?>
-1
[email protected]
6 年前
该项目实现了 PHP7.0+ 中 mysql 函数的包装器。

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

测试良好,工作正常 =)
-1
Tim 先生
15 年前
需要注意的是,mysql_query 可以生成 E_WARNING(未记录)。我遇到的警告是当数据库用户没有权限执行 UDF 时。

预期行为应该类似于无效的 SQL 语句,其中 mysql_query 不会生成 E_WARNING。

警告:mysql_query() [function.mysql-query]:无法将结果集保存到 filename.php 中

mysql_errno 为 1370,mysql_error 为

对用户 'username'@'%' 执行命令被拒绝,因为例程 'database_name.MyUDF'
-1
[email protected]
24 年前
在尝试 INSERT 或 UPDATE 并尝试将大量文本或数据(blob)放入 mysql 表时,您可能会遇到问题。

在 mysql.err 中,您可能会看到
数据包太大 (73904)

要解决此问题,您只需使用选项 -O max_allowed_packet=maxsize 启动 mysql

您只需用您要插入的最大大小替换 maxsize,默认值为 65536
-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']);
?>
-4
[email protected]
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
[email protected]
16 年前
在处理 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);

不知道这一点会导致在处理任何包含空终止符的字符串时进行一些令人头疼的故障排除。所以现在你知道啦!:)
-3
[email protected]
21 年前
关于返回枚举字段所有可能值的思路,mySQL 手册说应该使用“SHOW COLUMNS FROM table LIKE column”来完成此操作。

下面的函数(假设数据库连接)将返回一个枚举可能值的数组。

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 匹配多个列,您将获得第一个列的枚举,因此请谨慎使用 $Column 参数
2) 您不能将 ',' 作为枚举的一部分(我想 mySQL 会转义它,但我还没有尝试过)
3) 如果该字段不是枚举,您将获得垃圾数据!

这只是一个快速示例,用于展示如何执行此操作,在它变得完美之前,需要进行一些整理(即检查该字段是否实际上是枚举)。
-3
匿名
21 年前
在该函数禁止它们之前,请注意输入中的 SQL 注释 (--)。
-4
rob desbois
18 年前
请注意,mysql 客户端程序中使用的“source”命令*不是*服务器的功能,而是客户端的功能。
这意味着您不能执行
mysql_query('source myfile.sql');
您将收到语法错误。使用 LOAD DATA INFILE 作为替代方法。
-4
[email protected]
18 年前
我相信 [email protected] 版本中有一个错字

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
17 年前
这可能是一种使用外键从两个表中打印值的好方法。我还没有正确测试过,但它应该可以正常工作。

$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);
-6
rogier
16 年前
对于所有遇到执行存储过程调用时出现“Command out of synch”错误的程序员

此问题存在已知的错误,避免此错误的最佳解决方法似乎是切换到 mysqli。

但是,我仍然需要 mysql 正确处理这些调用。
此错误通常与错误的函数调用顺序有关,尽管 http://bugs.php.net/bug.php?id=39727 上的错误报告表明并非如此。

对我来说,在注释掉数百行代码和几个用于解析过程信息(使用 information_schema 和 'SHOW' 扩展)的内省调用后,我仍然遇到相同的错误。
返回第一个结果,因为我使用 MYSQL_MULTI_RESULTS 值 131072 初始化了连接(忘记这一点,您将永远不会获得任何输出,而只会收到一条错误消息,指出 mysql 在此上下文中无法返回结果)

在使用此代码进行测试后(sproc2 仅调用 'SELECT * FROM sometable'),我发现错误必须出在 mysql 库/扩展中。不知何故,mysql 无法正确处理多个结果集,或者至少缺少一些与处理多个结果相关的功能。

<?php
//...
$rs = mysql_query('CALL sproc2(500)');
while ((
$row=mysql_fetch_assoc($rs))!==false) {
print_r($row);
}
mysql_free_result($rs);

$rs = mysql_query('CALL sproc2(500)');
print
mysql_error(); //臭名昭著的“command out of synch”消息 :(
while (($row=mysql_fetch_assoc($rs))!==false) {
print_r($row);
}
mysql_free_result($rs);
?>

在花费数小时调试我的代码(完整的库已经超过 MB)之后,唯一的解决方案似乎是在第一次调用后关闭连接,并在第二次调用之前重新打开连接。

因此,如果您要创建统一的数据库访问接口并实现存储过程/预处理语句(或用于此的类),如果确实希望启用存储过程,这可能是一种解决方案。

但是,请注意,这实际上是您设计(以及 IMHO 中的 mysql 扩展)中的一个严重缺陷。

另请参阅 mysqli_query 上的 mysqli 文档,它似乎工作正常。
-6
fernandoleal at loytek dot com
16 年前
不知道是否是 bug,但当您使用复制服务器并使用多个数据库查询时,如果您没有选择数据库,它只会将数据插入、更新、删除到主服务器,并绕过从服务器。我认为这是因为没有将 sql 插入二进制日志,所以解决方法是只需调用 mysql_select_db
MYSQL:5.0.51a-log
PHP:5.2.6
示例
<?php
#仅插入主服务器
$link=mysql_connect('host','user','pass');
$sql ="INSERT INTO mysql.host (host) VALUES ('localhost');"
var_dump(mysql_query($sql,$link));

#主服务器-从服务器工作方式
$link2=mysql_connect('host','user','pass');
$select_db = mysql_select_db('mysql', $link2);
var_dump(mysql_query($sql,$link2));
?>
-6
cc+php at c2se dot com
17 年前
以下是一个类似于 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 );

}
}

?>
-9
ix at nivelzero dot ro
19 年前
以下是一个用于解析 *.sql 文件的脚本(仅在使用 phpMyAdmin 创建的转储中测试过),它简短而简单(为什么人们会说“以下是一个简短而简单的脚本”,但它却有 100 行?)。该脚本跳过注释,允许在查询中出现 ;

<?php
function parse_mysql_dump($url){
$file_content = file($url);
$query = "";
foreach(
$file_content as $sql_line){
if(
trim($sql_line) != "" && strpos($sql_line, "--") === false){
$query .= $sql_line;
if(
preg_match("/;[\040]*\$/", $sql_line)){
$result = mysql_query($query)or die(mysql_error());
$query = "";
}
}
}
}
?>
-11
mwwaygoo at hotmail dot com
12 年前
我更喜欢对单个 INSERT、REPLACE 和 UPDATE 查询使用相同的语法,因为它更容易阅读,并且可以使我的代码更短(没有单独构建插入和更新值)

INSERT INTO table SET x='1', y=3
UPDATE table SET x='2' WHERE y=3

因此,如果您使用函数构建查询,您只需要为任何查询编写“field=value, field2=value2”部分。
-8
Predrag Supurovic
20 年前
如果您需要使用 PHP 连续执行多个 SQL 命令(通常称为 batcg SQL),则不能使用 mysql_query(),因为它只能执行单个命令。

以下是一个简单但有效的函数,可以运行批量 SQL 命令。小心,如果字符串中包含分号(;),除了作为命令分隔符之外(例如在字符串表达式中),则该函数将无法正常工作。

function mysql_exec_batch ($p_query, $p_transaction_safe = true) {
if ($p_transaction_safe) {
$p_query = 'START TRANSACTION;' . $p_query . '; COMMIT;';
};
$query_split = preg_split ("/[;]+/", $p_query);
foreach ($query_split as $command_line) {
$command_line = trim($command_line);
if ($command_line != '') {
$query_result = mysql_query($command_line);
if ($query_result == 0) {
break;
};
};
};
return $query_result;
}
-8
jon at websandbox dot net
19 年前
我认为需要特别注意的是(尤其是对于像我这样的新手),空结果与错误并不相同。
<?php
/* 'bar' 是数据库中的空表 */
$rs = mysql_query("SELECT `foo` FROM `bar`")
if(
$rs) {
echo
mysql_num_rows($rs); //输出:0
}

/* 格式错误的查询 /*
$rs = mysql_query("SELECT `foo` FRO `bar`");
if($rs) {
echo "这永远不会被回显";
}
?>
-9
allen a brooker gb net
21 年前
一种减少像上面删除整个数据库的delete命令这样的查询风险的方法是尽可能使用限制。

例如,如果你有一个只设计用于删除一条记录的例程,在命令末尾添加 'LIMIT 1'。这样,如果有人做了愚蠢的事情,你只会丢失一条记录。

你应该检查所有输入,特别是通过 GET 发送的输入。例如,确保 $_GET['id'] 不为空或等于 "",是一个正数,不等于 0(一般情况下,我知道这并不适用于某些表类型,但它适用于默认情况),并且在该字段的有效范围内。

不要信任发送到你的脚本的任何数据。

希望对你有帮助
艾伦
-12
Anonymous
15 年前
处理 RENAME TABLE 查询时,PHP 似乎总是返回 false,无论查询是否成功处理。
-13
Richie (at) RichieBartlett.com
14 年前
对于那些花了几个小时对着键盘猛敲,想知道为什么非英语字符输出为问号的你们... 请尝试以下操作。

<?php

$db
= mysql_connect('YOUR_DB_ADDRESS','YOUR_DB_USER','YOUR_DB_PASS') or die("数据库错误");
mysql_select_db('YOUR_DB', $db);

//解决方案:: 在你的第一个查询之前添加此注释 - 强制多语言支持
$result = mysql_query("set names 'utf8'");

$query = "select * from YOUR_DB_TABLE";
$result = mysql_query($query);

//-剩下的就由你来做-

?>

只需对 MySQL 数据库运行 "set names 'utf8'" 查询,你的输出应该显示正确。
-11
chris at hotmail dot com
21 年前
Windows 程序员,请记住,虽然 Windows 查询中的表名不区分大小写,但许多 *NIX 版本的 Mysql 要求使用正确的表名大小写(也许其他版本也一样)。所以最好从一开始就使用正确的大小写,以防你将来决定使用 *NIX 服务器。
-17
wjyong at sh163 dot net
19 年前
以下查询并非如预期的那样有效。
<?php
$username
= 'dicteworld';
$username{4} = '';
$sql = "SELECT * FROM `user` WHERE `User` = '$username'";
print(
$sql); // 结果:SELECT * FROM `user` WHERE `User` = 'dictworld'
$res = mysql_query($query);
$row = mysql_fetch_array($res);
print_r($row);// 结果:仍然返回 Array(),假设用户 'dictworld' 存在。
?>
请注意,空字符串 '' 等同于 '\0',因此上面的 SQL 语句等同于 SELECT * FROM `user` WHERE `User` = 'dict\0world',尽管打印的字符串是正确的。
To Top