PHP最大的一个特点就是和数据库结合紧密,多数PHP的应用都是通过数据库实现的。本章主要介绍如何使用PHP来操作MySQL数据库,同时介绍使用PHP操作SQL Server、Access数据库的技术。
9.1 通过PHP操作MYSQL数据库
要进行数据库编程,首先需要连接数据库。在PHP中,提供了大量用于数据库处理的函数,读者可以很方便地进行各种数据库操作。
9.1.1 连接MySQL数据库
要进行数据库操作,首先需要连接数据库。连接数据库,也就是PHP客户端向服务器端的数据库发出连接请求,连接成功后就可以进行其他的数据库操作。如果使用不同的用户连接,会有不同的操作权限。
为了能够连接MySQL数据库,必须修改php.ini文件的设置(在更改文件前首先需要去除该文件的只读属性),将“extension- php_mysql.dll”语句前面的分号删除,如图9.1所示,然后,重新启动Apache服务器。
图9.1 修改php.ini的配置
mssql_connect()函数用于连接MySQL服务器,该函数的语法如下:
resource mysql_connect([string server[,string username[,string password[,bool]]]]
其中,server表示MySQL服务器,可以包括端口号,如果mysql.default_host未定义(默认情况),则默认值为“localhost:3306”;username表示用户名;password表示密码。
例如,用户连接本机MySQL服务器的代码如下:
$link=mssql_connect("localhost","root","root");
如果该函数调用成功,则返回句柄。如果失败,则返回FALSE。
9.1.2 关闭MySQL数据库
通常的情况下,在创建一个连接后,如果不再使用,应该关闭数据库的连接以释放资源,同时又可避免出现各种意外的错误。
mysql_close()函数用于关闭与MySQL数据库服务器的连接。语法如下:
bool mysql_close([resource link_identifier]);
其中,link_identifier为MySQL的连接标识符,若不指定参数link_identifier,则会关闭最后的一次连接。如果成功,则返回TRUE,失败,则返回FALSE。
通常并不强制使用mysql_close(),因为已打开的非持久连接会在脚本执行完毕后自动关闭。但是建议读者养成良好的编程习惯,在使用完毕后关闭连接。
例如,关闭数据库的连接,代码如下:
mysql_close(); //关闭数据库连接
9.1.3 选择数据库
前面已经成功连接了数据库服务器,但是一个数据库服务器可能包含了很多的数据库。通常需要针对某个具体的数据库进行编程,此时就必须选择目标数据库。
mysql_select_db()函数用于选择目标数据库,语法如下:
bool mysql_select_db(string database_name[,resource link_identifier]);
mysql_select_db()函数用来选择MySQL服务器中的数据库。如果成功,则返回TRUE,如果失败,则返回FALSE。
示例:
选择DB_Book数据库,代码如下:
<?php
$link=mysql_connect("localhost","root","root") or die("数据库连接失败!".mysql_error());
if(mysql_select_db("DB_Book",$link))
echo"您选择的数据库为:DB_Book";
else
echo ("数据库选择失败!".mysql_error());
?>
实例位置:mr\sl\09\example01.php
9.1.4 使用Insert语句实现用户注册
对于专门为数据库设计的语言来讲,SQL是一种数据库操作技术,可以对数据库进行添加、修改、删除等一系列操作。
当由记录表示的一个新实体出现时,通常就把一个新的数据记录添加到关系数据库中。实现数据的添加操作可使用Insert语句完成,具体的语法请读者参见本书11.6.1节。
数据添加主要应用到如下几个函数,下面分别进行介绍。
1.mysql_query()函数
mysql_query()函数用来根据连接标识符向指定数据库服务器的当前数据库发送查询。语法如下:
int mysql_query(string query ,int [link_identifier]);
其中,query是查询字符串;link_identifier是数据库连接标识符。
mysql_query()在执行成功时返回一个结果标识符,失败时返回FALSE。
2.mysql_fetch_array()函数
mysql_fetch_array()函数用来从结果集取得的行生成数组。语法如下:
array mysql_fetch_array(int result,int[result_type]);
其中,result_type参数是一个常量,可选项,可以接受以下值(默认值为MYSQL_BOTH):
MYSQL_ASSOC:只得到关联索引。
MYSQL_NUM:只得到数字索引。
MYSQL_BOTH:将得到一个同时包含关联和数字索引的数组。
注意:mysql_fetch_array()函数返回的字段名区分大小写。
mysql_fetch_array()函数先提取出查询结果的第一行的内容,这个函数的参数就是mysql_query()函数返回的整数标志。而mysql_fetch_array()执行成功后,记录集指针会自动下移,这样当再一次执行mysql_fetch_array()时,得到的就是下一行记录的内容了。
下面通过具体的范例来讲解Insert语句在PHP中的应用。
范例09-01 使用Insert语句实现用户注册 |
|
|
数据添加是Web程序或网站最基本的功能之一(基本功能为添加、修改、删除、查询等),任何一个Web程序或网站的后台管理页面都要提供数据添加的功能。向数据表中插入数据可以通过Insert语句实现。本范例通过Insert语句实现了用户注册功能,运行结果如图9.2所示。
本范例的设计思路如下。
(1)本范例在注册用户时,由于不能存在同样的用户名,因此需要首先对用户名进行判断。在“用户名”文本框中输入用户名称,单击“检测用户”超链接,通过window.open打开一个用户检测的用户对话框,对输入的用户进行检测,并对检测结果给出相应的提示。代码如下:
<script language="javascript">
function openwin(x){
if (x==""){
alert("请输入用户名!"); myform.UserName.focus();return false;
}
else{
window.open("submit_checkuser.php?x="+x,"newframe","width=300,height=150");
}
}
</script>
<a href="#" onClick="javascript:openwin(myform.UserName.value)">[检测用户]</a>
图9.2 录入数据
(2)利用$_GET[x]将文本框的值传递到数据处理页(submit_checkuser.php),可检测用户名称是否存在,代码如下:
<?php
include "Conn/conn.php";
$UserName=$_GET[x];
$sql=mysql_query("select * from tb_user where Username = '$UserName'");
$result=mysql_fetch_array($sql);
if ($result!=false){
echo ("[<font color=red>".$UserName."</font>]已被注册!");
}
else{
echo ("恭喜您!用户名[<font color=green>".$UserName."</font>]可以注册!");
}
?>
(3)当用户按要求填写用户信息后,单击【确定保存】按钮将数据提交到数据处理页(register_deal.php)进行数据处理。
(4)在数据处理页register_deal.php中利用include包含文件命令引用数据库配置文件,访问数据库。代码如下:
<? php include "Conn/Conn.php"; ?>
(5)将从表单中提取的数据存储到变量中,使用Insert语句将用户填写的数据作为新记录插入到数据表中,并弹出“用户注册成功”提示框。程序代码如下:
<?php
$UserName=$_POST[UserName];
$TrueName=$_POST[TrueName];
$PWD=$_POST[PWD1];
$ICO=$_POST[ICO];
$Sex=$_POST[Sex];
$birthday=$_POST[Birthday];
$Email=$_POST[Email];
$Tel=$_POST[Tel];
$homepage=$_POST[Homepage];
$OICQ=$_POST[OICQ];
$Address=$_POST[Address];
$INS=mysql_query("Insert Into tb_user (Username,Pwd,TrueName,ICO,Sex,birthday,Email,Tel, homepage,OICQ,Address) Values('$UserName','$PWD','$TrueName','$ICO','$Sex','$birthday','$Email',' $Tel', '$homepage','$OICQ','$Address')");
$result1=mysql_fetch_array($INS);
echo "<script> alert('用户注册成功!');</script>";
echo "<script> window.location='index.php';</script>";
?>
9.1.5 使用Update语句实现批量更新用户状态
批量数据更新在数据库中的应用是比较广泛的,而且通过批量数据更改可以达到省时省力、提高效率的目的。
批量更新数据主要应用到了Update语句和In子句。Update语句的语法请读者参见本书11.6.2节。下面介绍一下In子句的用法。
In子句用于确定给定的值是否与子查询或列表中的值相匹配。语法如下:
test_expression [ NOT ] IN
(
subquery
| expression [ ,...n ]
)
其中,参数test_expression代表所有有效的Microsoft® SQL Server™表达式;参数subquery包含某列结果集的子查询;参数expression [,...n]表示一个表达式列表,用来测试是否匹配。所有的表达式必须与test_expression具有相同的类型。
下面的范例主要应用Update语句实现批量更新用户状态。
范例09-02 使用Update语句实现批量更新用户状态 |
|
|
一般在设计用户权限或是更改工资级别时都会用到批量更新,批量更新的好处是速度快、安全性高。在本范例中,利用批量更新更改用户状态。选择要操作的用户,单击【激活】或【冻结】按钮,即可将用户设为激活或冻结状态。程序运行结果如图9.3、图9.4所示。
图9.3 选中欲更新的用户 图9.4 批量更新用户状态
本范例的实现过程如下。
(1)利用include包含文件命令引用数据库配置文件,访问数据库。代码如下:
<?php include "conn/conn.php"; ?>
(2)利用Do…while循环语句输出用户信息,将每条记录前面加上复选框,并进行相关属性值设置。代码如下:
<form name="form1" method="post" action="index.php" onSubmit="Checker()">
<table width="349" border="1" align="center" cellspacing="0" >
<tr align="center" bgcolor="#efefef">
<td height="36" colspan="3">用户列表
</td>
</tr>
<?php
$sql=mysql_query("select * from tb_member");
$result=mysql_fetch_array($sql);
do {
?>
<tr align="center">
<td width="108"><input name="id" type="checkbox" id="id" value="<?php echo $result[M_ID];
?>"></td>
<td width="131"><?php echo $result[M_Name]; ?></td>
<td width="88"><?php echo $result[Grade]; ?></td>
</tr>
<?php
}while($result=mysql_fetch_array($sql));
?>
<tr align="center">
<input type="hidden" name="items" value="<?php echo $item; ?>">
<td colspan="3"><input type="submit" name="Submit" value="激活" >
<input type="reset" name="Submit" value="重置">
<input type="submit" name="Submit" value="冻结">
</tr>
</table>
<p> </p>
</form>
(3)PHP接收多个同名复选框信息,不像JSP那样可以自动转换成为数组,这给使用者带来了一定的不便。但是还是有解决办法的,即利用JavaScript脚本做一下预处理。当提交表单时,调用cheaker()函数,多个同名复选框在JavaScript脚本中还是以数组的形式存在的,所以在表单提交之前,可以利用JavaScript把复选框中的信息组合成一个字符串赋值给表单中的隐藏元素。代码如下:
<script language="javascript">
function Checker(){
form1.items.value = ""; //设置隐藏域的值为空
if ( !form1.id.length ) { //只有一个复选框,form1.item.length = undefined
if ( form1.id.checked ){
form1.items.value = form1.id.value;
}
}else {
var temp="";
for ( i = 0 ; i < form1.id.length ; i++ ){
if ( form1.id(i).checked ){ //复选框中有选中的框
temp=temp+form1.id(i).value+","; //使用","分隔符将数组元素组合成一个字符串
}
}
temp=temp.substring(0,temp.length-1); //去除字符串末尾多余的","
form1.items.value = temp; //将变量赋值给隐藏域
}
}
</script>
(4)将隐藏域的值赋给变量item,这样就可以实现复选框信息的传递了。再使用Update语句和In子句对选中的用户进行批量更新。代码如下:
<?php
$item = $POST[items];
if( $item<>""){
if ($_POST[Submit]=="激活"){
$sql=mysql_query("update tb_member set Grade='激活' where M_ID in (".$item.")");
$result=mysql_fetch_array($sql);
}
else{
$sql=mysql_query("update tb_member set Grade='冻结' where M_ID in (".$item.")");
$result=mysql_fetch_array($sql);
}
}
else{
echo "<div align='center' style='color:#FF0000; font-size:12px'>请选择一个用户</div>";
}
?>
9.1.6 使用Delete语句实现批量删除用户信息
批量数据的删除在各大中小型网站及管理系统中应用最为广泛。批量删除数据是通过Delete语句实现的。
例如,批量删除图书信息表中图书名称包含“PHP”的数据信息,代码如下:
$sql=mysql_query("Delete from tab_book where bookname like '%".php."%'");
$result=mysql_fetch_array($sql);
下面的范例主要应用复选框实现数据的批量删除。
范例09-03 使用Delete语句实现批量删除图书信息 |
|
|
在对数据进行删除时,有很多种方法。本范例主要通过复选框实现数据的批量删除。运行本范例,选择要删除的数据前的复选框,单击【删除】按钮,此时所有被选中的数据将全部被删除。删除图书信息前及删除图书后的运行结果如图9.5、图9.6所示。
图9.5 批量删除数据前
图9.6 批量删除数据后
本范例主要应用Delete语句和In子句实现批量数据删除操作。Delete语句的语法请读者参见本书11.6.3节。
本范例的实现过程如下。
(1)利用包含文件命令include引用数据库配置文件,即可访问数据库。代码如下:
<?php include "Conn/conn.php"; ?>
(2)利用Do…While语句将数据表中的所有记录显示出来,并将每条记录前面加上复选框。添加Form表单及复选框,并进行相关属性值的设置。代码如下:
<form name="form1" method="post" action="index.php" onSubmit="Checker()">
<table width="770" border="1" align="center" cellpadding="1" cellspacing="1" bordercolor="#73BA08" >
<tr>
<td height="244" colspan="7" background="images/bg.jpg"> </td>
</tr>
<?php
$sql=mysql_query("select * from tab_book");
$info=mysql_fetch_array($sql);
do {
?>
<tr>
<td width="26"><input name="id" type="checkbox" id="id" value="<?php echo $info[id]; ?>"> </td>
<td width="161"><?php echo $info[bookname]; ?></td>
<td width="72"><?php echo $info[issuDate]; ?></td>
<td width="29"><?php echo $info[price]; ?></td>
<td width="170"><?php echo $info[synopsis]; ?></td>
<td width="73"><?php echo $info[Maker]; ?></td>
<td width="89"><?php echo $info[pulisher]; ?></td>
</tr>
<?php
}while($info=mysql_fetch_array($sql));
?>
<tr align="center">
<input type="hidden" name="items" value="<?php echo $item; ?>">
<td colspan="7"><input type="submit" name="Submit" value="删除" >
<input type="reset" name="Submit" value="重置">
</tr>
</table>
</form>
(3)当提交表单时,调用cheaker()函数,利用JavaScript脚本把复选框中的信息组合成一个字符串,赋值给表单中的隐藏元素。代码如下:
<script language="javascript">
function Checker(){
form1.items.value = ""; //设置隐藏域的值为空
if ( !form1.id.length ) { //只有一个复选框,form1.item.length = undefined
if ( form1.id.checked ){
form1.items.value = form1.id.value;
}
}else {
var temp="";
for ( i = 0 ; i < form1.id.length ; i++ ){
if ( form1.id(i).checked ){ //复选框中有选中的框
temp=temp+form1.id(i).value+","; //将数组中的元素使用","分隔
}
}
temp=temp.substring(0,temp.length-1); //去除字符串末尾多余的","
form1.items.value = temp; //将变量赋值给隐藏域
}
}
</script>
(4)将隐藏域的值赋给变量item,这样就可以实现复选框信息的传递了。通过单击【删除】按钮,将复选框选择的任意一条或多条记录删除。代码如下:
<?php
$item = $_POST[items];
if( $item<>""){
if ($_POST[Submit]=="删除"){
$sql=mysql_query("Delete from tab_book where id in (".$item.")");
$result=mysql_fetch_array($sql);
}
}
else{
echo "<div align='center' style='color:#FF0000; font-size:12px'>请选择欲删除的图书项目</div>";
}
?>
9.1.7 通用查询
在数据库中,数据查询是通过Select语句完成的。Select语句可以从数据库中按用户要求提供的限定条件检索数据,并将查询结果以表格的形式返回。
例如,查询图书信息表中图书名称为“PHP数据库系统开发完全手册”的图书信息。代码如下:
$sql=mysql_query("select * from tab_book where bookname='PHP数据库系统开发完全手册'");
$info=mysql_fetch_array($sql);
下面通过具体的范例来讲解数据查询的方法和技巧。
范例09-04 通用查询 |
|
|
通用查询在动态网站开发过程中应用最为广泛,它支持多种查询方式,可按不同字段、不同条件、不同的查询关键字对数据信息进行综合查询,且支持模糊查询。运行本范例,设置查询条件,单击【查询】按钮,即可将符合条件的图书信息检索出来显示在浏览器上。运行结果如图9.7、图9.8所示。
图9.7 设置通用查询条件
图9.8 通用查询结果
本范例的实现过程如下。
(1)利用include包含文件命令引用数据库配置文件,即可访问数据库。代码如下:
<?php include "conn/conn.php"; ?>
(2)创建记录集。首先通过接收表单传递的值赋值给Session变量,然后利用If…Then…Else条件语句判断用户当前选择的操作符,从而执行相对应的SQL语句来检索商品的相关信息,并判断记录集是否为空。如果检索到记录尾,没有找到符合条件的记录,那么将弹出提示信息。主要程序代码如下:
php
$txt_sel=$_POST[txt_sel];
$txt_tj=$_POST[txt_tj];
$txt_book=$_POST[txt_book];
if ($_POST[Submit]=="查询"){
if($_POST[txt_tj]=="like"){ //如果选择的条件为"like",则进行模糊查询
$sql=mysql_query("select * from tab_book where ".$txt_sel." like '%".$txt_book."%'");
$info=mysql_fetch_array($sql);
}
if($_POST[txt_tj]=="="){
$sql=mysql_query("select * from tab_book where ".$txt_sel." = '".$txt_book."'");
$info=mysql_fetch_array($sql);
}
if($_POST[txt_tj]==">"){
$sql=mysql_query("select * from tab_book where ".$txt_sel." > '".$txt_book."'");
$info=mysql_fetch_array($sql);
}
if($_POST[txt_tj]=="<"){
$sql=mysql_query("select * from tab_book where ".$txt_sel." < '".$txt_book."'");
$info=mysql_fetch_array($sql);
}
else{
if($info==false){ //如果检索的信息不存在,则输出相应的提示信息
echo "<div align='center' style='color:#FF0000; font-size:12px'>对不起,您检索的图书信息不存在!</div>";
}
}
}
?>
注意:本范例在实现模糊查询时,使用了通配符“%”。“%”表示任意零个或多个字符。
(3)利用Do…While循环语句以表格形式输出数据信息到浏览器中。代码如下:
<?php
do{
?>
<tr align="left" bgcolor="#FFFFFF">
<td height="20" align="center"><?php echo $info[id]; ?></td>
<td > <?php echo $info[bookname]; ?></td>
<td> <?php echo $info[issuDate]; ?></td>
<td align="center"><?php echo $info[price]; ?></td>
<td> <?php echo $info[synopsis]; ?></td>
<td> <?php echo $info[Maker]; ?></td>
<td> <?php echo $info[publisher]; ?></td>
</tr>
<?php
}
while($info=mysql_fetch_array($sql));
?>
9.1.8 查询指定时间段的数据
在对日期数据进行查询时,经常需要对某一时间段内的数据进行查询。首先介绍一个简单的日期查询。
例如,利用SQL语句查询采购信息表中指定时间的采购信息,代码如下:
$sql=mysql_query("select * from tb_cgdan where cgdate >'2007-01-12'");
$result=mysql_fetch_array($sql);
利用SQL语句中的BETWEEN…AND语句可以实现时间段查询的功能。
BETWEEN…AND语句的语法格式如下:
test_expression [ NOT ] BETWEEN begin_expression AND end_expression
test_expression:用来在由begin_expression和end_expression定义的范围内进行测试的表达式。
NOT:指定谓词的结果被取反。
begin_expression:任何有效的表达式。
begin_expression为时间段的起始日期。
end_expression:任何有效的表达式。
test_expression为时间段的终止日期。
AND:作为一个占位符,表示test_expression应该处于由begin_expression和end_expression指定的范围内。
下面详细介绍对指定时间段内数据记录进行查询的方法。
范例09-05 查询指定时间段的数据 |
|
|
一些中小型网站经常需要对某一时间段内的数据信息进行查询。运行本范例,在“查询日期”文本框中设置要查询的时间段,单击【查询】按钮,即可将该时间段内的商品采购信息输出到浏览器中。运行结果如图9.9所示。
图9.9 查询指定时间段内的数据
本范例的实现过程如下。
(1)利用include包含文件命令引用数据库配置文件访问数据库。代码如下:
<?php include "conn/conn.php"; ?>
(2)利用复合条件BETWEEN…AND语句检索指定时间段内的商品采购信息,主要程序代码如下:
<?php
if($_POST["subb"]<>""){
$_SESSION["sdate"]=$_POST["sdate"];
$_SESSION["edate"]=$_POST["edate"];
$sql=mysql_query("select * from tb_cgdan where cgdate between '".$_SESSION["sdate"]."' and '".$_SESSION ["edate"]."'");
$result=mysql_fetch_array($sql);
if($result==false){
echo "<div align=center><font color=red>Sorry!该时间段内没有采购商品!</font></div>";
}
?>
(3)利用Do…While循环输出语句将符合条件的采购信息输出到浏览器中,代码如下:
<?php
do{
?>
<tr align="center" bgcolor="#FFFFFF">
<td><?php echo $result["id"]; ?></td>
<td align="left"><?php echo $result["spname"]; ?></td>
<td align="left"><?php echo $result["cd"]; ?></td>
<td align="left"><?php echo $result["gg"]; ?></td>
<td><?php echo $result["dw"]; ?></td>
<td align="left"><?php echo $result["dj"]; ?></td>
<td align="left"><?php echo $result["sl"]; ?></td>
<td align="left"><?php echo $result["je"]; ?></td>
<td align="left"><?php echo $result["cgdate"]; ?></td>
</tr>
<?php
}while($result=mysql_fetch_array($sql));
}
mysql_close();
?>
9.1.9 查询畅销的前5种商品
要查询出最畅销的商品,必须利用ORDER BY子句根据一个或一个以上的字段来排序查询结果,然后再使用LIMIT子句限制Select语句返回的行数。LIMIT取1个或2个参数,如果给定2个参数,第一个参数用于指定要返回的第一行的偏移量,第二个参数用于指定返回行的最大数目。初始行的偏移量是0(不是1)。
mysql> select * from table LIMIT 5,10; # Retrieve rows 6-15
如果给定一个参数,它指出返回行的最大数目。
mysql> select * from table LIMIT 5; # Retrieve first 5 rows
即LIMIT n等价于LIMIT 0,n。
数据查询有一项极为重要的功能,那就是它能够查询出最前面的或最后的。下面通过具体的范例进行讲解。
范例09-06 查询畅销的前5种商品 |
|
|
查询时不仅可以查询具有相同字段信息的记录,还可以对某一特定范围内的数据信息进行查询。运行本范例,如图9.10所示,默认页显示tb_stocks数据表中的全部信息。单击【查询】按钮,即可统计出最畅销的前5种商品(本范例按销售总量降序排列,再返回查询结果的前5条记录)并将结果输出到浏览器,运行结果如图9.11所示。
图9.10 显示商品的全部信息
图9.11 查询畅销的前5种商品
本范例的实现过程如下。
(1)利用框架嵌套技术布局范例页面,代码如下:
<frameset rows="80,*" cols="*" framespacing="0" frameborder="NO" border="0">
<frame src="spxxindex.php" name="topFrame" scrolling="NO" noresize >
<frame src="indexdefault.php" name="MainFrame" noresize>
</frameset>
(2)利用include包含文件命令引用数据库配置文件访问数据库。代码如下:
<?php include "conn/conn.php"; ?>
(3)创建记录集。利用LIMIT 5子句返回满足Where子句的前5条记录,代码如下:
<?php
if ($_POST[subb]=="查询"){
$sql=mysql_query("select spname,cd,dw,price,sum(xssl) as sum_xssl,sum(xsje) as sum_xsje from tb_ stocks group by spname,cd,dw,price order by sum_xssl desc LIMIT 5");
$result=mysql_fetch_array($sql);
}
?>
(4)利用Do…While循环语句输出查询结果,代码如下:
<?php
do{
?>
<tr align="center" bgcolor="#FFFFFF">
<td align="left"> <?php echo $result[spname]; ?></td>
<td align="left"> <?php echo $result[cd]; ?></td>
<td align="center"><?php echo $result[dw]; ?></td>
<td align="center"><?php echo $result[price]; ?></td>
<td><?php echo $result[sum_xssl]; ?></td>
<td><?php echo $result[sum_xsje]; ?></td>
</tr>
<?php
}while($result=mysql_fetch_array($sql));
?>
9.1.10 多表分组统计商品的销售情况
在查询统计中经常会遇到对查询结果进行排序、分组的情况。多表分组统计主要应用了SUM聚集函数,该函数主要用于返回表达式中所有值的和,或只返回DISTINCT值。需要说明的是,SUM聚集函数只能用于数据类型是数字的列,且忽略NULL值。
语法如下:
SUM ( [ALL|DISTINCT] expression )
其中,参数ALL表示对所有的值进行聚集函数运算,是默认值;参数DISTINCT用于指定SUM返回惟一值的和;参数expression是常量、列或函数,或者是算术、按位与字符串等运算符的任意组合。expression是精确数字或近似数字数据类型分类(bit数据类型除外)的表达式。其他情况下不允许使用聚集函数和子查询。
说明:SUM函数在对列中数值相加时忽略NULL值。但是,如果列中的所有值均为NULL,则SUM函数返回NULL作为其结果。
下面通过具体的范例详细讲解多表分组统计的应用。
范例09-07 多表分组统计商品的销售情况 |
|
|
本范例实现的是在商品销售信息表和商品库存信息表中查询商品的销售数量和现存数量,并按商品编号进行分组。运行本范例,单击【统计】按钮,即可将符合条件的统计结果输出到浏览器中。运行结果如图9.12、图9.13所示。
图9.12 显示商品的库存信息
图9.13 多表分组统计商品的销售情况
本范例的实现过程如下。
(1)利用include包含文件命令引用数据库配置文件访问数据库。代码如下:
<?php include "Conn/conn.php";?>
(2)创建记录集。在图书销售信息表和图书库存信息表中查询图书的销售数量和现存数量,并按图书编码、图书名称、作者等分组,从而实现从多个表中分组统计数据信息。主要程序代码如下:
<?php
if ($_POST[subb]=="统计"){
$sql=mysql_query("select k.spid,k.spname,k.kcsl,sum(x.xssl) as sum_xssl from tb_stocks as k,tb_market as x where k.spid=x.spid group by k.spid,k.spname,k.kcsl");
$result=mysql_fetch_array($sql);
}
?>
(3)利用Do…While语句循环输出统计后的商品库存信息和销售信息。代码如下:
<?php do{ ?>
<tr align="center" bgcolor="#FFFFFF">
<td align="left"> <?php echo $result[spid]; ?></td>
<td align="left"> <?php echo $result[spname]; ?></td>
<td align="left"> <?php echo $result[kcsl]; ?></td>
<td align="left"> <?php echo $result[sum_xssl]; ?></td>
</tr>
<?php
}while($result=mysql_fetch_array($sql));
mysql_close();
?>
9.1.11 应用存储过程实现登录身份验证
存储过程是数据库编程中最重要的内容。从MySQL 5.0以上版本开始支持存储过程。这样可以大大提高数据的处理速度,同时也可以提高数据编程的灵活性。
使用存储过程时,首先,需要将php_mysqli.dll文件拷贝到php5下的ext文件夹下,然后必须修改php.ini文件的设置(在更改文件前需要去除该文件的只读属性),添加“extension=php_mssqli.dll”命令,如图9.14所示,最后,重新启动Apache服务器。
下面介绍如何创建存储过程。
(1)首先声明一个存储过程,语法如下:
CREATE PROCEDURE proc_name([proc_parameter[,…]])
[characteristic…] routine_body
其中,CREATE PROCEDURE是创建存储过程的关键字;proc_name表示存储过程的名称;proc_parameter表示存储过程的参数。
存储过程的参数有3种类型,即in、out、inout。其中参数in表示输入参数;out表示输出参数;inout表示该参数既可以输入也可以输出。
(2)其次,必须在创建的存储过程的SQL语句中使用BEGIN…END。
(3)最后,利用“Call proc_name(@a);”调用存储过程。其中,@a是传入的参数,用来保存统计结果。
使用存储过程具有以下优点。
(1)存储过程被创建后,可以在程序中被多次调用,而不必重新编写该存储过程的MySQL语句,在对存储过程进行更改时,对程序的源码毫无影响。
(2)存储过程的执行速度要比执行批处理的速度快得多。
(3)系统管理员可以对执行某一存储过程的权限进行限制,从而保证数据的安全。
调用存储过程的语法如下:
{CALL procname (?,?)}
其中,procname表示存储过程的名称;?表示传递的参数。
下面通过具体的范例来讲解存储过程的应用。
范例09-08 应用存储过程实现登录身份验证 |
|
|
目前,验证用户登录身份的方法有多种,而通过调用存储过程来实现用户身份验证是目前最好的解决方案之一。因为存储过程在创建时即在服务器上进行编译,所以执行起来要比单个MySQL语句快得多。运行本范例,在“用户名”和“密码”文本框中输入正确的用户名和密码,单击【登录】按钮即可进行用户身份验证。运行结果如图9.15所示。
本范例的开发过程如下。
(1)在MySQL数据库中建立存储过程user_ login,语句如下:
mysql>delimiter //
mysql>CREATE PROCEDURE user_login(inout name varchar(20),inout pwd varchar(20))
mysql>Begin
mysql>select * from tb_admin username=name and pwd=pwd;
->END
->//
注意:在上面的语句中,"delimiter //"表示将当前的语句结束符号从“:”改成"//",这样就可以在存储过程的内部使用分号";"了;而“//”表示MySQL语句的结束符,即建立存储过程。
(2)建立数据源的连接,使用存储过程时与建立其他的数据源有所区别,需要创建一个MySQL对象,代码如下:
<?php
$link=new mysqli("localhost","root","root","db_admin");
$link->query("set names gb2312",MYSQLI_USE_RESULT);
?>
(3)利用Call语句调用存储过程,对传递的参数进行验证,并对验证结果给出相应的信息提示。关键程序代码如下:
<?php
if($_POST["submit"]<>""){
$result=$link->query("call user_login('".$_POST[username]."','".$_POST[pwd]."')",MYSQLI_USE_RESULT);
$info=mysqli_fetch_array($result);
if($info==true){
echo "<script>alert('恭喜您,登录成功!');</script>";
}
else{
echo "<script>alert('对不起,您输入的用户名或密码错误,请您重新输入!');</script>";
}
}
?>
9.1.12 应用事务添加留言信息
事务是数据库高级编程的一个重要内容。在编程中,经常需要使用事务。所谓事务,就是一系列必须都成功的操作,只要有一步操作失败,所有其他的操作也必须撤销。下面就来讲解事务在MySQL中的应用。
在默认的情况下,MySQL对于普通的SQL语句都是自动提交的,即当SQL语句执行完毕后会立刻在数据库中得到提交。
在MySQL中,如果要关闭自动提交,可以使用以下语句:
set autocommit=0;
自动提交被关闭之后,执行SQL语句则会自动启动事务处理,所有的SQL语句都被当作事务来执行。
在自动提交打开的时候,系统是不会自动进入事务处理阶段的,必须使用如下语句才能启动事务处理:
start transaction;
在执行完事务块的所有语句后,如果要真正提交到数据库,必须调用以下语句:
commit;
如果在事务的执行过程中出现意外或者发生错误,可以取消所有执行的SQL语句,调用以下语句即可:
rollback;
当真正调用commit语句后,执行结果才能够被其他用户看见。
下面通过具体的范例来介绍事务处理在MySQL中的实现。
范例09-09 应用事务添加留言信息 |
|
|
本范例主要应用事务添加留言信息。运行本范例,在留言信息页面添加留言信息,如图9.16所示,单击【提交留言】按钮,提交留言信息到数据处理页应用事务进行处理,如果留言信息正确,则进行输出,运行结果如图9.17所示。
图9.16 应用事务添加留言信息
图9.17 查看留言信息
本范例的实现过程如下。
(1)利用包含文件命令include引用数据库配置文件“conn.php”,代码如下:
<?php include "conn/conn.php"; ?>
(2)首先需要在查询语句前应用“start transaction”命令启动事务,然后利用Insert into语句向数据表中添加用户留言信息(中间的各个操作都按普通顺序书写,而不用考虑数据回滚的问题,在程序最后判断是否有错误)。如果数据有误,则使用“rollback”语句进行事务回滚;如果数据正确,使用“commit”命令提交留言信息,当前事务即结束。再使用“echo”语句输出添加留言信息成功的信息。程序代码如下:
<?php
session_start();
$Author=$_SESSION[UserName];
$Face="face".$_POST[emote].".gif";
$content=$_POST[content];
$Createtime=date("y-m-d h:i:s");
$IP=getenv(REMOTE_ADDR);
if ($_POST[content]!="" ) {
$myquery="start transaction"; //启动事务
$result=mysql_query($myquery); //执行启动事务sql语句
$myquery=mysql_query("Insert Into tb_topic (Author,Face,content,CreateTime,IP) values ('$Author',' $Face','$content','$Createtime','$IP')"); //执行插入sql语句
$result=mysql_fetch_array($myquery);
if(!$myquery){
mysql_query("rollback"); //调用rollback取消事务,这样会导致前面的一条记录插入也失败
echo "插入失败!事务被取消!<br>";
}
else{
mysql_query("commit");
echo "事务提交成功!<br>";
}
}
?>
(3)利用For循环语句输出tb_topic数据表中的信息,来查看提交留言信息的结果是否正确。代码如下:
<?php
//检索判断是否新数据已经插入成功
$result = mysql_query("select * from tb_topic") or die("<br>查询表items失败: " . mysql_error());
$rows=mysql_num_rows($result); //取得记录数量
echo "<br>";
echo "<table border=1 align=center ><tr align=center bgcolor=#9cA6C6><td>编号</ td> <td>用户名</ td><td>头像</td><td>留言信息</td><td>留言时间</td><td>用户IP</td></tr>";
for ($i=0;$i<$rows;$i++)
{
$row=mysql_fetch_array($result);
echo "<tr><td> $row[0] </td> <td> $row[1] </td> <td> $row[2] </td><td> $row[3] </td><td> $row[4] </td><td> $row[5] </td></tr>";
}
echo "</table>";
echo " <br><table align=center><tr><td>总记录数: $rows </td></tr></table><br>";
?>