29套

逐题详细解析


第1题:修改字段类型

ALTER TABLE tb_class 
MODIFY department VARCHAR(20);

解析

  • ALTER TABLE tb_class:修改班级信息表
  • MODIFY department:修改 department 字段
  • VARCHAR(20):将数据类型改为变长字符串,长度20
  • 不能修改字段名称,所以用 MODIFY 而不是 CHANGE

注意:如果原字段有 NOT NULLDEFAULT 约束,需要保留:

ALTER TABLE tb_class 
MODIFY department VARCHAR(20) NOT NULL DEFAULT '';

第2题:更新班级所属院系

UPDATE tb_class 
SET department = '管理学院' 
WHERE classno LIKE '%信息管理%';

解析

  • UPDATE tb_class:更新班级信息表
  • SET department = '管理学院':将院系设置为“管理学院”
  • WHERE classno LIKE '%信息管理%':班级编号中包含“信息管理”的班级

LIKE 通配符说明

写法含义
'%信息管理%'包含“信息管理”
'信息管理%'以“信息管理”开头
'%信息管理'以“信息管理”结尾

第3题:查询参加社团总数排名前两位的学生

SELECT s.sno, s.sname, COUNT(gs.gno) AS 参加社团总数
FROM tb_student s
LEFT JOIN tb_gs gs ON s.sno = gs.sno
GROUP BY s.sno, s.sname
ORDER BY 参加社团总数 DESC
LIMIT 2;

解析

  • LEFT JOIN:确保没有参加社团的学生也被统计(人数为0)
  • GROUP BY:按学号分组,统计每个学生参加的社团数
  • ORDER BY ... DESC:按社团总数降序排列
  • LIMIT 2:取前两名

输出字段:学号、姓名、参加社团总数

保存:将语句保存到 sj13.txt 文件


第4题:创建视图

CREATE VIEW v_club AS
SELECT g.gname AS 社团名称, COUNT(gs.sno) AS 社团人数
FROM tb_group g
LEFT JOIN tb_gs gs ON g.gno = gs.gno
GROUP BY g.gno, g.gname
ORDER BY 社团人数 DESC;

解析

  • CREATE VIEW v_club:创建名为 v_club 的视图
  • AS 社团名称:字段别名显示为“社团名称”
  • AS 社团人数:字段别名显示为“社团人数”
  • LEFT JOIN:确保没有成员的社团也显示(人数为0)
  • GROUP BY:按社团分组统计人数
  • ORDER BY 社团人数 DESC:按人数降序排列

第5题:授予用户权限

GRANT UPDATE (sname) 
ON db_club.tb_student 
TO '李宏'@'localhost' 
WITH GRANT OPTION;

解析

  • GRANT UPDATE (sname):授予修改学生姓名的权限(列级权限)
  • ON db_club.tb_student:指定数据库和表
  • TO '李宏'@'localhost':指定用户和主机名
  • WITH GRANT OPTION:允许该用户将权限传播给其他用户

如果用户不存在,先创建

CREATE USER '李宏'@'localhost' IDENTIFIED BY 'password';

答案汇总

题号答案
1ALTER TABLE tb_class MODIFY department VARCHAR(20);
2UPDATE tb_class SET department = '管理学院' WHERE classno LIKE '%信息管理%';
3SELECT s.sno, s.sname, COUNT(gs.gno) AS 参加社团总数 FROM tb_student s LEFT JOIN tb_gs gs ON s.sno = gs.sno GROUP BY s.sno, s.sname ORDER BY 参加社团总数 DESC LIMIT 2;
4CREATE VIEW v_club AS SELECT g.gname AS 社团名称, COUNT(gs.sno) AS 社团人数 FROM tb_group g LEFT JOIN tb_gs gs ON g.gno = gs.gno GROUP BY g.gno, g.gname ORDER BY 社团人数 DESC;
5GRANT UPDATE (sname) ON db_club.tb_student TO '李宏'@'localhost' WITH GRANT OPTION;

知识点总结

题号考点关键语法
1修改字段类型ALTER TABLE ... MODIFY ...
2条件更新UPDATE ... SET ... WHERE ... LIKE
3分组统计+排序+限制GROUP BY + COUNT() + ORDER BY + LIMIT
4创建视图CREATE VIEW ... AS SELECT ...
5列级权限+传播GRANT UPDATE(字段) ... WITH GRANT OPTION
DELIMITER $$
CREATE PROCEDURE sp_gs( ______  groupname VARCHAR(20))
BEGIN 
	DECLARE num TINYINT;
	DECLARE years TINYINT;
	SELECT _____________ INTO num FROM tb_gs, tb_group WHERE tb_gs.gno = tb_group.gno AND gname = groupname;
	SELECT TIMESTAMPDIFF(YEAR,buildup,CURDATE()) INTO years FROM tb_group WHERE gname = groupname;
	IF ( ____________ AND ____________ ) THEN
		DELETE FROM tb_group WHERE gname = groupname;
	END IF; 
END $$
DELIMITER ;

存储过程 sp_gs 逐空详细解析


第1个空:IN

CREATE PROCEDURE sp_gs( ______ groupname VARCHAR(20))

答案IN

解析

  • 存储过程的参数类型关键字
  • IN 表示输入参数,由调用者传入
  • groupname 是社团名称,用于指定要操作的社团

第2个空:COUNT(*)

SELECT _____________ INTO num FROM tb_gs, tb_group WHERE tb_gs.gno = tb_group.gno AND gname = groupname;

答案COUNT(*)

解析

  • 统计该社团的成员人数
  • num 变量用于存储成员数量
  • 连接条件:tb_gs.gno = tb_group.gno 关联社团表和成员表

子查询逻辑

SELECT COUNT(*) INTO num 
FROM tb_gs, tb_group 
WHERE tb_gs.gno = tb_group.gno AND gname = groupname;
-- 统计指定社团有多少成员

第3个空:num = 0

IF ( ____________ AND ____________ ) THEN

答案num = 0

解析

  • 第一个条件:成员人数为0
  • 即该社团没有任何成员

第4个空:years >= 3

IF ( num = 0 AND ____________ ) THEN

答案years >= 3

解析

  • 第二个条件:社团成立年限大于等于3年
  • years 变量存储的是成立年限(已通过 TIMESTAMPDIFF 计算)
  • 两个条件同时满足时,才执行删除操作

完整代码

DELIMITER $$
CREATE PROCEDURE sp_gs(IN groupname VARCHAR(20))
BEGIN 
    DECLARE num TINYINT;
    DECLARE years TINYINT;
    SELECT COUNT(*) INTO num FROM tb_gs, tb_group WHERE tb_gs.gno = tb_group.gno AND gname = groupname;
    SELECT TIMESTAMPDIFF(YEAR, buildup, CURDATE()) INTO years FROM tb_group WHERE gname = groupname;
    IF (num = 0 AND years >= 3) THEN
        DELETE FROM tb_group WHERE gname = groupname;
    END IF; 
END $$
DELIMITER ;

存储过程功能说明

功能:删除符合条件的社团(无成员且成立满3年)

执行逻辑

1. 接收输入参数 groupname(社团名称)
2. 统计该社团的成员人数 → num
3. 计算该社团成立至今的年数 → years
4. 判断条件:
   - 成员人数为0(num = 0)
   - 成立年限 ≥ 3年(years >= 3)
5. 两个条件都满足时,删除该社团

调用示例

-- 删除“书法社”(如果无成员且成立满3年)
CALL sp_gs('书法社');

关键函数说明

TIMESTAMPDIFF 函数

TIMESTAMPDIFF(YEAR, buildup, CURDATE())
  • 计算两个日期之间的差值
  • YEAR:以年为单位
  • buildup:社团成立时间
  • CURDATE():当前日期
  • 返回成立至今的年数

示例

成立时间当前日期返回值
2020-03-012026-03-286
2024-12-012026-03-281

答案汇总

空位答案含义
第1空IN输入参数类型
第2空COUNT(*)统计成员人数
第3空num = 0成员人数为0
第4空years >= 3成立满3年
DELIMITER //
CREATE TRIGGER tr_gs BEFORE INSERT  
ON tb_gs FOR EACH ROW
BEGIN
    ____________ times INT;    
    IF ( ____________ ='社长') THEN
    BEGIN
	SELECT COUNT(*) INTO times FROM tb_gs WHERE sno=NEW.sno AND ____________;
	IF ( times > ________ ) THEN
	BEGIN
	    SET NEW.role='社员';
	    SET @str='每个学生只能在一个社团担任社长!';
	END;
	END IF;
    END;
    END IF;
END //
DELIMITER ;

/*激活触发器*/
INSERT INTO tb_gs VALUES('g202','s201501103','2022-04-18','社长'); /*s201501103已经担任其他团的社长*/
INSERT INTO tb_gs VALUES('g102','s201501201','2017-04-18','社长'); /*s201501201没有参加过社团*/
INSERT INTO tb_gs VALUES('g102','s201605104','2017-04-18','社长'); /*s201605104作为社员参加过社团*/

触发器 tr_gs 逐空详细解析


第1个空:DECLARE

____________ times INT;

答案DECLARE

解析

  • 声明局部变量的关键字
  • 语法:DECLARE 变量名 数据类型
  • 这里声明 times 变量,用于统计该学生担任社长的社团数量

第2个空:NEW.role

IF ( ____________ ='社长') THEN

答案NEW.role

解析

  • NEW 是触发器中的特殊变量,代表新插入的行
  • NEW.role 是新插入记录的职务字段
  • 判断插入的职务是否为“社长”

第3个空:role='社长'

SELECT COUNT(*) INTO times FROM tb_gs WHERE sno=NEW.sno AND ____________;

答案role = '社长'

解析

  • 统计该学生(NEW.sno)已经担任社长的社团数量
  • 条件:role = '社长' 筛选出职务为社长的记录
  • 如果已经担任其他社团的社长,则 times > 0

第4个空:0

IF ( times > ________ ) THEN

答案0

解析

  • 判断该学生是否已经担任其他社团的社长
  • 如果 times > 0,说明已经担任社长
  • 此时不允许再插入为社长,自动改为社员

完整代码

DELIMITER //
CREATE TRIGGER tr_gs BEFORE INSERT  
ON tb_gs FOR EACH ROW
BEGIN
    DECLARE times INT;    
    IF (NEW.role = '社长') THEN
    BEGIN
    SELECT COUNT(*) INTO times FROM tb_gs WHERE sno = NEW.sno AND role = '社长';
    IF (times > 0) THEN
    BEGIN
        SET NEW.role = '社员';
        SET @str = '每个学生只能在一个社团担任社长!';
    END;
    END IF;
    END;
    END IF;
END //
DELIMITER ;

触发器功能说明

功能:防止一个学生在多个社团担任社长

执行逻辑

1. 用户插入新记录(加入社团)
2. 检查新记录的职务是否是“社长”
   ↓ 是社长
3. 统计该学生已经担任社长的社团数量
   ↓
4. 如果已经担任社长(times > 0)
   ↓
5. 自动将职务改为“社员”
   ↓
6. 设置提示信息 @str

触发示例解析

示例1(已担任社长)

INSERT INTO tb_gs VALUES('g202','s201501103','2022-04-18','社长');
  • s201501103 已经是其他社团的社长
  • 触发器检测到 times > 0
  • 自动将 role 改为 '社员'
  • 实际插入:职务变为“社员”

示例2(未参加过社团)

INSERT INTO tb_gs VALUES('g102','s201501201','2017-04-18','社长');
  • s201501201 没有参加过任何社团
  • times = 0,条件不满足
  • 保持职务为“社长”正常插入

示例3(作为社员参加过)

INSERT INTO tb_gs VALUES('g102','s201605104','2017-04-18','社长');
  • s201605104 参加过社团但只是社员,不是社长
  • times = 0,条件不满足
  • 保持职务为“社长”正常插入

答案汇总

空位答案含义
第1空DECLARE声明变量关键字
第2空NEW.role新插入记录的职务字段
第3空role = '社长'筛选社长职务
第4空0比较阈值
<html>
<meta http-equiv="Content-Type" content="text/html; charset=gbk" />

<?php
$host="localhost"; $user="root"; $pwd="";
//**********found**********
$db_name="____________";
$conn=mysql_connect($host,$user,$pwd ) 
	or die("连接数据库服务器失败。".mysql_error());
//**********found**********
________________($db_name,$conn)
	or die("连接数据库失败。".mysql_error());
mysql_query("set names 'gbk'");
?>

<body >
	<br><br>
	<div align="center"><font face="楷体" size="5" color="#006000">
					<b>学院参加社团情况查询</b></font></div><br><br>
<form name="frm" method="post">
<table width="400" align="center">
<tr><td><span class="STYLE1">学院名称:</span></td>
	<td><input type="text" name="DeptName" size="30"></td>
	<td><input type="submit" name="select" value="查询"></td></tr>
</table>
</form>

<?php
//**********found**********
if(isset($_POST['____________']))
{
	$DeptName=$_POST['DeptName'];
	if(!$DeptName)
		echo "<script> alert('输入不正确!')</script>;";
	else
	{		
		echo "<br>";
		echo "<table width=500 border=2 align=center>";
		echo "<tr><td>班级</td><td>姓名</td><td>性别</td><td>籍贯</td><td>社团名称</td><td>参加社团时间</td><td>承担的工作</td></tr>";
//**********found**********
		$sql="select ___________, sname,sex,native,gname,joindate, role from tb_student s,tb_gs gs,tb_group g,tb_class c where s.classno=c.classno AND gs.sno=s.sno AND gs.gno=g.gno AND department ='$DeptName'  order by CONVERT(c.classno USING gbk) desc,CONVERT(gname USING gbk)";
		$result=mysql_query($sql);
//**********found**********
		while($row=mysql_fetch_row(_____________)
		  {list($CLASS,$SNAME,$SEX,$NATIVE,$GNAME,$JOINDATE,$ROLE)=$row;
		   echo "<tr><td>$CLASS</td><td>$SNAME</td><td>$SEX</td><td>$NATIVE</td><td>$GNAME</td><td>$JOINDATE</td><td>$ROLE</td></tr>";
  		   }
		echo "</table>";		
	}
}
?>

</body>
</html>

PHP程序逐空详细解析


第1个空:db_club

$db_name="____________";

答案db_club

解析

  • 根据题目背景,这是学生活动俱乐部数据库
  • 数据库名称应为 db_club
  • 该数据库包含社团信息表、学生信息表、班级信息表等

第2个空:mysql_select_db

________________($db_name,$conn)

答案mysql_select_db

解析

  • 选择数据库的函数
  • 语法:mysql_select_db(数据库名, 连接资源)
  • 第1个参数:数据库名称 $db_name
  • 第2个参数:数据库连接资源 $conn

第3个空:select

if(isset($_POST['____________']))

答案select

解析

  • 判断表单是否已提交
  • 表单提交按钮的 name 属性是 select
  • 当点击“查询”按钮时,$_POST['select'] 被设置

表单中的对应代码

<input type="submit" name="select" value="查询">

第4个空:c.classno

$sql="select ___________, sname,sex,native,gname,joindate, role from tb_student s,tb_gs gs,tb_group g,tb_class c where ...";

答案c.classno

解析

  • 查询结果需要显示班级信息
  • 后面代码中有 list($CLASS,$SNAME,...) 对应输出
  • $CLASS 对应第一个字段,即班级编号
  • 需要从班级表 tb_class 中查询 classno 字段

完整字段对应

输出位置字段别名/来源
第1列$CLASSc.classno
第2列$SNAMEs.sname
第3列$SEXs.sex
第4列$NATIVEs.native
第5列$GNAMEg.gname
第6列$JOINDATEgs.joindate
第7列$ROLEgs.role

第5个空:$result)

while($row=mysql_fetch_row(_____________)

答案$result)

解析

  • mysql_fetch_row() 函数需要传入结果集资源
  • 前面 $result=mysql_query($sql) 执行查询返回结果集
  • 需要将 $result 作为参数传入
  • 注意括号闭合:mysql_fetch_row($result)

正确写法

while($row = mysql_fetch_row($result))

完整代码

<html>
<meta http-equiv="Content-Type" content="text/html; charset=gbk" />

<?php
$host="localhost"; $user="root"; $pwd="";
//**********found**********
$db_name="db_club";
$conn=mysql_connect($host,$user,$pwd ) 
    or die("连接数据库服务器失败。".mysql_error());
//**********found**********
mysql_select_db($db_name,$conn)
    or die("连接数据库失败。".mysql_error());
mysql_query("set names 'gbk'");
?>

<body >
    <br><br>
    <div align="center"><font face="楷体" size="5" color="#006000">
                    <b>学院参加社团情况查询</b></font></div><br><br>
<form name="frm" method="post">
<table width="400" align="center">
<tr><td><span class="STYLE1">学院名称:</span></td>
    <td><input type="text" name="DeptName" size="30"></td>
    <td><input type="submit" name="select" value="查询"></td>
</tr>
</table>
</form>

<?php
//**********found**********
if(isset($_POST['select']))
{
    $DeptName=$_POST['DeptName'];
    if(!$DeptName)
        echo "<script> alert('输入不正确!')</script>;";
    else
    {       
        echo "<br>";
        echo "<table width=500 border=2 align=center>";
        echo "<tr><th>班级</th><th>姓名</th><th>性别</th><th>籍贯</th><th>社团名称</th><th>参加社团时间</th><th>承担的工作</th></tr>";
//**********found**********
        $sql="select c.classno, sname,sex,native,gname,joindate, role from tb_student s,tb_gs gs,tb_group g,tb_class c where s.classno=c.classno AND gs.sno=s.sno AND gs.gno=g.gno AND department ='$DeptName'  order by CONVERT(c.classno USING gbk) desc,CONVERT(gname USING gbk)";
        $result=mysql_query($sql);
//**********found**********
        while($row=mysql_fetch_row($result))
          {list($CLASS,$SNAME,$SEX,$NATIVE,$GNAME,$JOINDATE,$ROLE)=$row;
           echo "<tr><td>$CLASS</td><td>$SNAME</td><td>$SEX</td><td>$NATIVE</td><td>$GNAME</td><td>$JOINDATE</td><td>$ROLE</td></tr>";
             }
        echo "</table>";        
    }
}
?>

</body>
</html>

程序功能说明

功能:按学院名称查询该学院学生参加社团的情况

执行流程

  1. 用户输入学院名称,点击“查询”
  2. 四表连接查询:
  • tb_student(学生表)
  • tb_class(班级表)→ 关联学院
  • tb_gs(学生社团表)
  • tb_group(社团表)
  1. 输出:班级、姓名、性别、籍贯、社团名称、参加时间、职务

答案汇总

空位答案说明
第1空db_club数据库名称
第2空mysql_select_db选择数据库函数
第3空select表单提交按钮名称
第4空c.classno班级编号字段
第5空$result)结果集资源参数

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注