PHP Conference Japan 2024

mysql_query

(PHP 4, PHP 5)

mysql_query发送 MySQL 查询

警告

此扩展在 PHP 5.5.0 中已弃用,并在 PHP 7.0.0 中移除。应改用 MySQLiPDO_MySQL 扩展。另请参阅 MySQL:选择 API 指南。此函数的替代方案包括

描述

mysql_query(字符串 $query, 资源 $link_identifier = NULL): 混合

mysql_query() 将唯一查询(不支持多个查询)发送到与指定 link_identifier 关联的服务器上当前活动的数据库。

参数

query

SQL 查询

查询字符串不应以分号结尾。查询中的数据应 正确转义

link_identifier

MySQL 连接。如果未指定链接标识符,则假定为 mysql_connect() 最近打开的链接。如果找不到此类链接,它将尝试创建一个链接,就像 mysql_connect() 未带任何参数调用一样。如果找不到或建立连接,则会生成 E_WARNING 级别错误。

返回值

对于返回结果集的 SELECT、SHOW、DESCRIBE、EXPLAIN 和其他语句,mysql_query() 在成功时返回一个 资源,在错误时返回 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() 返回一个 资源

<?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 条注释

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 会注意到这一点并且不会更新它。"

当然,如果所有应用程序进程都同意锁定算法,那么所有这些都是可能的。

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);

}
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";
}
?>
fbraz3 at gmail dot com
6 年前
此项目实现了 PHP7.0+ 中 mysql 函数的包装器。

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

测试正常工作=)
Mr. Tim
16 年前
需要注意的是,mysql_query 可能会生成 E_WARNING(未记录)。我遇到的警告是当数据库用户没有执行 UDF 的权限时。

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

Warning: mysql_query() [function.mysql-query]: Unable to save result set in filename.php

mysql_errno 为 1370,mysql_error 为

execute command denied to user 'username'@'%' for routine 'database_name.MyUDF'
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']);
?>
nikhil-php at nols dot com
24 年前
当尝试插入或更新并尝试将大量文本或数据(blob)放入 MySQL 表中时,您可能会遇到问题。

在 mysql.err 中您可能会看到
Packet too large (73904)

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

您只需将 maxsize 替换为您要插入的最大大小,默认值为 65536。
masteracc0 at aol dot com
17 年前
在处理 PHP 和 MySQL 时请记住,如果在 PHP 中使用 echo($sql),将以 null 结尾的字符串发送到 MySQL 查询可能会产生误导,因为 null 终止符可能不可见。

例如(这假设已建立连接),
$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);

不知道这一点可能会导致在处理任何带有 null 终止符的字符串时遇到一些令人头疼的故障排除。所以现在你知道啦! :)
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',
));
?>
davidc at edeca dot net
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) 如果字段不是枚举,您将获得垃圾数据!

这只是一个快速示例,用于演示如何执行此操作,在完美之前需要进行一些整理(即检查字段是否确实是枚举)。
Anonymous
21 年前
在该函数禁止之前,请注意输入中的 SQL 注释 (--)。
rob desbois
18 年前
请注意,mysql 客户端程序中使用的“source”命令*不是*服务器的功能,而是客户端的功能。
这意味着你不能执行
mysql_query('source myfile.sql');
你将会得到一个语法错误。请使用 LOAD DATA INFILE 作为替代方案。
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
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);
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