

逐题详细解析
第1题:增加列
ALTER TABLE tb_booking
ADD COLUMN bak VARCHAR(100) NULL;
解析:
ALTER TABLE tb_booking:修改预订信息表ADD COLUMN bak:添加名为bak的新列VARCHAR(100):可变长字符串,长度100NULL:允许取空值(允许为空)
简化写法(省略COLUMN关键字):
ALTER TABLE tb_booking
ADD bak VARCHAR(100) NULL;
注意:如果题目没有明确要求,NULL 可以省略(因为默认就是允许NULL)
第2题:插入两条记录
INSERT INTO tb_customers (cno, cname, teleNo) VALUES
('c106', '宋佳', '13587654321'),
('c107', '李文', '13934785641');
解析:
INSERT INTO tb_customers:插入客户信息表(cno, cname, teleNo):指定要插入的字段VALUES:指定对应的值- 一次插入两条记录,用逗号分隔
逐条插入写法:
INSERT INTO tb_customers VALUES ('c106', '宋佳', '13587654321');
INSERT INTO tb_customers VALUES ('c107', '李文', '13934785641');
注意:
- 字符型数据必须加引号
- 字段顺序要与表结构一致
第3题:查询尚未预订过的客房类型
SELECT rtype
FROM tb_room
WHERE rno NOT IN (SELECT DISTINCT rno FROM tb_booking);
解析:
- 思路:客房类型表中没有被预订过的客房类型
- 子查询
SELECT DISTINCT rno FROM tb_booking:获取所有被预订过的客房类型编号 NOT IN:不在这个列表中,即从未被预订过- 最后输出这些客房类型的名称
rtype
其他写法:
-- 使用 NOT EXISTS
SELECT rtype
FROM tb_room r
WHERE NOT EXISTS (
SELECT 1 FROM tb_booking b
WHERE b.rno = r.rno
);
-- 使用 LEFT JOIN
SELECT r.rtype
FROM tb_room r
LEFT JOIN tb_booking b ON r.rno = b.rno
WHERE b.rno IS NULL;
第4题:创建视图
CREATE VIEW v_LastBooking AS
SELECT b.bno, c.cname
FROM tb_booking b
JOIN tb_customers c ON b.cno = c.cno
WHERE b.bno = (SELECT MAX(bno) FROM tb_booking);
解析:
- 视图名:
v_LastBooking - 显示字段:订单号
bno、客户姓名cname - 连接条件:预订表与客户表通过
cno关联 - 筛选条件:
bno = (SELECT MAX(bno) FROM tb_booking)获取最后一条预订记录
MAX(bno) 说明:
- 假设
bno是数值型(如自增ID),MAX()返回最大值即最新记录 - 如果
bno是字符型(如 ‘B001’),可能需要用ORDER BY和LIMIT
如果 bno 是字符型:
CREATE VIEW v_LastBooking AS
SELECT b.bno, c.cname
FROM tb_booking b
JOIN tb_customers c ON b.cno = c.cno
ORDER BY b.bno DESC
LIMIT 1;
第5题:创建用户并授权
-- 创建用户
CREATE USER 'abc'@'192.168.1.100' IDENTIFIED BY '123';
-- 授予权限
GRANT SELECT, DELETE ON db_booking.* TO 'abc'@'192.168.1.100';
解析:
创建用户部分:
CREATE USER:创建新用户'abc'@'192.168.1.100':用户名和主机名(登录IP)IDENTIFIED BY '123':设置密码
授权部分:
GRANT SELECT, DELETE:授予查询和删除权限ON db_booking.*:对db_booking数据库的所有表TO 'abc'@'192.168.1.100':指定用户
验证权限:
-- 查看用户权限
SHOW GRANTS FOR 'abc'@'192.168.1.100';
注意事项:
- 如果用户已存在,需要先删除:
DROP USER 'abc'@'192.168.1.100'; - 密码 ‘123’ 是纯数字,需要用引号(字符串)
答案汇总
| 题号 | 答案 |
|---|---|
| 1 | ALTER TABLE tb_booking ADD bak VARCHAR(100) NULL; |
| 2 | INSERT INTO tb_customers (cno, cname, teleNo) VALUES ('c106', '宋佳', '13587654321'), ('c107', '李文', '13934785641'); |
| 3 | SELECT rtype FROM tb_room WHERE rno NOT IN (SELECT DISTINCT rno FROM tb_booking); |
| 4 | CREATE VIEW v_LastBooking AS SELECT b.bno, c.cname FROM tb_booking b JOIN tb_customers c ON b.cno = c.cno WHERE b.bno = (SELECT MAX(bno) FROM tb_booking); |
| 5 | CREATE USER 'abc'@'192.168.1.100' IDENTIFIED BY '123';GRANT SELECT, DELETE ON db_booking.* TO 'abc'@'192.168.1.100'; |
知识点总结
| 题号 | 考点 | 关键语法 |
|---|---|---|
| 1 | 修改表结构 | ALTER TABLE ... ADD ... |
| 2 | 插入多条记录 | INSERT INTO ... VALUES (...), (...); |
| 3 | 子查询/NOT EXISTS | NOT IN 或 NOT EXISTS |
| 4 | 创建视图 | CREATE VIEW ... AS SELECT ... |
| 5 | 用户管理 | CREATE USER + GRANT |

函数 fn_hotrtype 逐空详细解析
第1个空:VARCHAR(20)
DECLARE tmp ____;
答案:VARCHAR(20)
解析:
- 声明变量
tmp,用于存储查询结果(客房类型) - 函数返回类型是
VARCHAR(20),变量类型应与返回类型一致 - 语法:
DECLARE 变量名 数据类型
第2个空:tb_room.type
GROUP BY _____
答案:tb_room.rno
解析:
- 按客房类型编号分组
- 每个客房类型有多个预订记录,分组后可以统计每个类型的预订次数
- 用
tb_room.rno确保按客房类型编号分组(保证唯一性)
为什么用 rno 而不是 rtype?
rno是主键,确保唯一性rtype可能有重复(但通常客房类型是唯一的,实际也可以)- 用主键分组更准确
第3个空:DESC
ORDER BY count(*) _____ LIMIT 1
答案:DESC
解析:
COUNT(*)统计每个客房类型的预订次数DESC表示降序排列,预订次数多的排在前面LIMIT 1只取第一条,即预订次数最多的客房类型
排序方式:
| 关键字 | 含义 |
|---|---|
ASC | 升序(默认),从小到大 |
DESC | 降序,从大到小 |
完整代码
DELIMITER $
CREATE FUNCTION fn_hotrtype()
RETURNS VARCHAR(20)
DETERMINISTIC
BEGIN
DECLARE tmp VARCHAR(20);
SELECT tb_room.rtype INTO tmp
FROM tb_booking, tb_room
WHERE tb_booking.rno = tb_room.rno
GROUP BY tb_room.rno
ORDER BY COUNT(*) DESC
LIMIT 1;
RETURN tmp;
END$
DELIMITER ;
函数功能说明
功能:查询预订次数最多的客房类型
执行逻辑:
1. 连接 tb_booking 和 tb_room 表(通过 rno)
2. 按客房类型编号分组
3. 统计每个类型的预订次数 COUNT(*)
4. 按次数降序排列(多的在前)
5. 取第一条记录(预订最多的类型)
6. 返回该类型的名称
示例演示
tb_booking 表:
| bno | rno |
|---|---|
| B001 | R01 |
| B002 | R01 |
| B003 | R01 |
| B004 | R02 |
| B005 | R02 |
| B006 | R03 |
tb_room 表:
| rno | rtype |
|---|---|
| R01 | 标准间 |
| R02 | 大床房 |
| R03 | 套房 |
统计结果:
| rno | rtype | COUNT(*) |
|---|---|---|
| R01 | 标准间 | 3 |
| R02 | 大床房 | 2 |
| R03 | 套房 | 1 |
返回结果:'标准间'
答案汇总
| 空位 | 答案 | 含义 |
|---|---|---|
| 第1空 | VARCHAR(20) | 变量数据类型 |
| 第2空 | tb_room.rtype | 分组字段(客房类型编号) |
| 第3空 | DESC | 降序排列 |
DELIMITER $
CREATE PROCEDURE sp_modifybookingflag(IN bno INT, IN ____fstate____ VARCHAR(10))
DETERMINISTIC
BEGIN
Update tb_booking
SET tb_booking.flag=
(SELECT ___flag______
FROM tb_flag
WHERE tb_flag.fstate=fstate)
WHERE tb_booking.bno=_bno_______;
END $
DELIMITER ;
存储过程 sp_modifybookingflag 逐空详细解析
第1个空:fstate
CREATE PROCEDURE sp_modifybookingflag(IN bno INT, IN ________ VARCHAR(10))
答案:fstate
解析:
- 这是存储过程的第二个输入参数
- 参数名
fstate,数据类型VARCHAR(10) - 用于接收要修改的预订状态名称(如’已确认’、’取消’等)
- 调用时传入状态名称,而不是状态代码
第2个空:flag
SET tb_booking.flag = (SELECT _________ FROM tb_flag WHERE tb_flag.fstate = fstate)
答案:flag
解析:
- 子查询需要返回预订状态代码
tb_flag表结构:flag:预订状态代码(如 F01、F02、F03)fstate:状态名称(如’已预订’、’已确认’、’取消’)- 根据传入的状态名称
fstate查询对应的状态代码
子查询逻辑:
SELECT flag FROM tb_flag WHERE tb_flag.fstate = fstate
-- 参数 fstate = '取消' 时,返回 'F03'
第3个空:bno
WHERE tb_booking.bno = ________;
答案:bno
解析:
- 这是存储过程的第一个输入参数名
- 用于指定更新条件:只更新该预订单号的记录
tb_booking.bno是表中的字段,bno是传入的参数
WHERE 条件作用:
WHERE tb_booking.bno = bno- 将表中预订单号字段与传入的参数值进行匹配
- 只更新指定的预订记录
完整代码
DELIMITER $
CREATE PROCEDURE sp_modifybookingflag(IN bno INT, IN fstate VARCHAR(10))
DETERMINISTIC
BEGIN
UPDATE tb_booking
SET tb_booking.flag = (SELECT flag FROM tb_flag WHERE tb_flag.fstate = fstate)
WHERE tb_booking.bno = bno;
END $
DELIMITER ;
存储过程功能说明
功能:修改指定预订单的状态(通过状态名称)
执行逻辑:
1. 接收两个输入参数:
- bno:预订单号
- fstate:要修改成的状态名称(如'取消'、'已确认')
2. 查询 tb_flag 表,根据状态名称获取对应的状态代码
3. 更新 tb_booking 表,将该订单的状态代码改为新值
调用示例:
-- 将订单 B001 的状态改为"取消"
CALL sp_modifybookingflag('B001', '取消');
-- 将订单 B002 的状态改为"已确认"
CALL sp_modifybookingflag('B002', '已确认');
参数区分说明
| 写法 | 含义 |
|---|---|
tb_booking.bno | 表中的预订单号字段 |
bno | 存储过程的输入参数(传入的订单号) |
tb_flag.fstate | 表中的状态名称字段 |
fstate | 存储过程的输入参数(传入的状态名称) |
答案汇总
| 空位 | 答案 | 含义 |
|---|---|---|
| 第1空 | fstate | 第二个输入参数,状态名称 |
| 第2空 | flag | 状态代码字段 |
| 第3空 | bno | 第一个输入参数,预订单号 |
<?php header('content-type:text/html;charset=utf-8');
$con= mysql_connect("localhost:3306","root","")
or die("no database!<br>");
//**********found**********
_____ ("db_booking",$con) or die( "database fail!<br>");
mysql_query("SET NAMES UTF8");
if(isset($_GET['custName']))
{
$name=$_GET['custName'];
//**********found**********
$_____='select tb_customers.cname, tb_booking.bdate from tb_booking,tb_customers '.
//**********found**********
'where tb_booking.cno = _____
and tb_customers.cname="'.$name.'"';
$result_onecust=mysql_query($sql_onecust,$con);
?>
<table border='1px'>
<caption>客户 <?php echo $name?> 的预订记录 </caption>
<tr>
<td>客户姓名</td>
<td>预订日期</td>
</tr>
<?php
//**********found**********
while($row_onecust=_____($result_onecust)){
?>
<tr>
<td><?php echo $row_onecust[0];?></td>
<td><?php echo $row_onecust[1];?></td>
</tr>
<?php
}
?>
</table>
<a href="sj3.php">Back</a>
<?php
}
else{
$sql_custs="SELECT tb_customers.cno,tb_customers.cname FROM tb_customers";
$result_custs=mysql_query($sql_custs,$con);
?>
<table border='1px'>
<caption>所有客户</caption>
<tr>
<td>客户编号</td>
<td>客户姓名</td>
</tr>
<?php
while($rows_custs=mysql_fetch_array($result_custs)){
?>
<tr>
<td><?php echo $rows_custs[0];?></td>
<td><?php echo $rows_custs[1];?></td>
</tr>
<?php
}
?>
</table><br/><br/>
<form action="sj3.php" method="get">
<!--**********found**********-->
客户姓名: <input type="text" name="_____" />
<input type="submit" />
</form>
<?php
}
mysql_close($con);
?>
PHP程序逐空详细解析
第1个空:mysql_select_db
_____ ("db_booking",$con) or die( "database fail!<br>");
答案:mysql_select_db
解析:
- 选择要操作的数据库的函数
- 语法:
mysql_select_db(数据库名, 连接资源) - 第1个参数:数据库名称
"db_booking" - 第2个参数:数据库连接资源
$con
第2个空:sql_onecust
$_____='select tb_customers.cname, tb_booking.bdate from tb_booking,tb_customers '.
答案:sql_onecust
解析:
- 定义变量存储SQL查询语句
- 变量名需要与后面
mysql_query($sql_onecust,$con)保持一致 - 该变量用于查询指定客户的预订记录
SQL语句内容:
select tb_customers.cname, tb_booking.bdate
from tb_booking, tb_customers
where tb_booking.cno = tb_customers.cno
and tb_customers.cname = "用户输入的姓名"
第3个空:tb_customers.cno
'where tb_booking.cno = _____
答案:tb_customers.cno
解析:
- 两表连接的条件
tb_booking表(预订表)和tb_customers表(客户表)通过cno(客户编号)关联- 确保查询结果中预订记录对应的客户信息正确
第4个空:mysql_fetch_row
while($row_onecust=_____($result_onecust)){
答案:mysql_fetch_row
解析:
- 从结果集中取出一行作为索引数组
- 后面代码使用
$row_onecust[0]和$row_onecust[1]访问数据 - 索引数组正好对应SELECT语句中的字段顺序:
[0]对应cname(客户姓名)[1]对应bdate(预订日期)
对比其他函数:
| 函数 | 返回类型 | 访问方式 |
|---|---|---|
mysql_fetch_row() | 索引数组 | $row[0]、$row[1] |
mysql_fetch_assoc() | 关联数组 | $row['cname'] |
mysql_fetch_array() | 两者都支持 | 两种方式均可 |
第5个空:custName
客户姓名: <input type="text" name="_____" />
答案:custName
解析:
- 表单输入框的
name属性 - 提交后数据以
$_GET['custName']接收 - 程序开头有
if(isset($_GET['custName']))判断 - 必须与接收时的键名一致
完整代码
<?php header('content-type:text/html;charset=utf-8');
$con= mysql_connect("localhost:3306","root","")
or die("no database!<br>");
//**********found**********
mysql_select_db ("db_booking",$con) or die( "database fail!<br>");
mysql_query("SET NAMES UTF8");
if(isset($_GET['custName']))
{
$name=$_GET['custName'];
//**********found**********
$sql_onecust='select tb_customers.cname, tb_booking.bdate from tb_booking,tb_customers '.
//**********found**********
'where tb_booking.cno = tb_customers.cno
and tb_customers.cname="'.$name.'"';
$result_onecust=mysql_query($sql_onecust,$con);
?>
<table border='1px'>
<caption>客户 <?php echo $name?> 的预订记录 </caption>
<tr>
<th>客户姓名</th>
<th>预订日期</th>
</tr>
<?php
//**********found**********
while($row_onecust=mysql_fetch_row($result_onecust)){
?>
<tr>
<td><?php echo $row_onecust[0];?></td>
<td><?php echo $row_onecust[1];?></td>
</tr>
<?php
}
?>
</table>
<a href="sj3.php">Back</a>
<?php
}
else{
$sql_custs="SELECT tb_customers.cno,tb_customers.cname FROM tb_customers";
$result_custs=mysql_query($sql_custs,$con);
?>
<table border='1px'>
<caption>所有客户</caption>
<tr>
<th>客户编号</th>
<th>客户姓名</th>
</tr>
<?php
while($rows_custs=mysql_fetch_array($result_custs)){
?>
<tr>
<td><?php echo $rows_custs[0];?></td>
<td><?php echo $rows_custs[1];?></td>
</tr>
<?php
}
?>
</table><br/><br/>
<form action="sj3.php" method="get">
<!--**********found**********-->
客户姓名: <input type="text" name="custName" />
<input type="submit" />
</form>
<?php
}
mysql_close($con);
?>
答案汇总
| 空位 | 答案 | 说明 |
|---|---|---|
| 第1空 | mysql_select_db | 选择数据库函数 |
| 第2空 | sql_onecust | SQL查询语句变量名 |
| 第3空 | tb_customers.cno | 两表连接条件 |
| 第4空 | mysql_fetch_row | 获取索引数组行 |
| 第5空 | custName | 表单输入框名称 |
发表回复