欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > 四、关系数据库标准语言SQL_3

四、关系数据库标准语言SQL_3

2025/6/9 1:32:19 来源:https://blog.csdn.net/xjsj62728/article/details/148400103  浏览:    关键词:四、关系数据库标准语言SQL_3

四、关系数据库标准语言SQL_3

这里的讲述内容是SQL嵌入C语言,但我会结合MySQL嵌入Python,采用的是PyMySQL这里我的工具会有MySQL,Pycharm。

4.9 嵌入式SQL

主要内容

  • 嵌入式SQL概述
  • 嵌入式SQL与主语言的接口
  • 不用游标的嵌入式SQL
  • 用游标的嵌入式SQL
  • 嵌入式SQL应用实例
  • 动态SQL
  • 嵌入式SQL小结

嵌入式SQL概述

  • SQL语言提供了两种不同的使用方式

    • 交互式

    • 嵌入式

      SQL迁入到C,C++,Java,COBOL等程序设计语言中,称为嵌入式SQL(Embedded SQL)

  • 宿主语言(主语言)

    被嵌入SQL的程序设计语言,称为宿主语言,如C、C++、Java等,称为宿主语言,简称主语言。

  • 引入嵌入式SQL的原因

    • SQL语言是非过程语言
    • 事务处理一般是过程性的,需要应用高级语言
  • 将SQL嵌入主语言后

    • SQL语句负责数据库的操纵
    • 宿主语言负责控制程序流程和数据的输入输出
  • 嵌入式SQL和交互式SQL

    • 主要命令语句相同
    • 实现细节上有所不同
    • 嵌入式SQL做了某些必要的扩充

嵌入式SQL与主语言的接口

  • 将SQL语句嵌入到宿主语言中必须解决的问题
    1. 将嵌入主语言的SQL语句编译成为可执行代码
    2. 数据库和主语言程序间的通信
    3. 数据库和主语言程序间的数据交换
    4. 需要协调面向集合和面向记录两种不同的处理方式
1. 嵌入式SQL的编译
SQL与C语言
  • 采用预编译方法

    • 在编译之前,先对SQL语句进行预处理;
    • 通过执行预处理程序把SQL语句编程主语言能够识别的形式;
    • 由主语言编译器统一对预处理后的源程序进行编译。
  • 预处理要求:

    • 所有SQL语句必须加前缀EXEC SQL,以区分SQL语句与主语言造句。

    • 有的主语言还在SQL语句结尾加上结束标志。

    • 在C语言嵌入式SQL的一般格式为:

      EXEC SQL <SQL语句>;

    • 以COBOL作为主语言的嵌入式SQL语句的一般形式

      EXEC SQL <SQL语句> END-EXEC

  • 嵌入式SQL的C语言源程序的基本编译过程

    1. 使用预编译器对含有嵌入式SQL语句的C语言源程序进行预处理,把SQL语句变为C语言编译器可识别的命令语句。预处理包括语法检查、存取权限检查、路径选择等。SQL语句处理后生成调用语句。
    2. 对预处理后的源程序用C编译器进行编译,生成目标代码。
    3. 连接目标代码,包括C语言库函数和SQL库函数,生成可执行程序。

    image-20250531144904808

MySQL与Python
  • 采用编译方法(原理)

    C 语言中Python 中的实现
    SQL 语句要加 EXEC SQL直接写 SQL 字符串,无需前缀
    需要预处理器Python 解释器直接执行 SQL 语句
    编译器统一处理PyMySQL 自动解析和执行

    PyMySQL是“无预编译”的,不需要预处理。我们直接把SQL写在字符串里传给cursor.execute()即可

  • 预处理要求

    C语言写法Python 写法(等价实现)
    EXEC SQL SELECT ...;cursor.execute("SELECT ...")
    C 中语句结尾需要 ;Python 中只需字符串 + 变量
  • Python+PyMySQL的编译过程

    1. SQL写入cursor.excute
    2. Python解释器直接执行SQL语句
    3. 数据库通信、语法处理、结果接收等工作由 PyMySQL 封装的内部模块自动完成
2. 数据库和主语言程序间的通信
SQL与C语言
  • 数据库的DBMS负责数据存取,SQL语句的执行是否成功,其执行结果需反馈给应用程序

    • 在SQL中设有一通信区SQLCA(SQL Communication Area)

      • 这是一个数据结构,其中包含描述DBMS当前工作状态的若干信息
    • 应用程序和用户通过SQLCA了解数据库的执行情况

      • SQLCA中有一状态指示单元SQLCODE,用于存放SQL语句的执行结果,通过判断SQLCODE的值可以知道SQL语句的执行情况(0表示成功)
    • 应用程序引用SQLCA,需要加以说明,格式为:

      EXEC SQL INCLUDE SQLCA;

  • SQLCA的具体内容

    • 与所执行的SQL语句有关
    • 与该SQL语句的执行情况有关
MySQL与Python
  • 数据库的 PyMySQL 负责数据存取,SQL 语句的执行是否成功,其执行结果需要反馈给应用程序

    • PyMySQL中没有SQLCA,但用try/except完成通信机制

      • PyMySQL中,try/except是通信机制的核心
        • 我们不需要手动检查状态码
        • SQL一旦执行出错,程序会自动跳转到except部分
    • try/except的作用

      • 是Python中处理 SQL执行成功或失败 的主要方式
      • 可以获取详细的异常信息,如:
        • 语法错误
        • 数据库连接失败
        • 表不存在
        • SQL执行失败等
    • 语法格式

      try:# 可能出错的代码块cursor.execute("SQL语句", 参数)  # 可以是 INSERT、SELECT、UPDATE、DELETE 等result = cursor.fetchall()       # 如果是查询可以这样获取结果# 处理查询结果(可以打印,也可以判断结果是否为空)
      except Exception as e:# 出现异常后的处理逻辑print("SQL执行出错,错误信息如下:")print(e)
      finally:# 无论对错都执行(常用于关闭连接)conn.close()
      
      结构用途说明
      try:放你“可能出错”的代码块(执行 SQL 的语句)
      except Exception as e:捕获所有类型的 SQL 错误,并把错误信息存到变量 e
      print(e)打印错误信息(如:语法错误、表不存在等)
      finally:不论是否出错,都执行的代码(如关闭数据库连接)
3. 数据库和主语言程序间的数据交换
SQL与C语言
  • 嵌入式SQL语句通过主变量与主语言程序进行数据交换。

  • 在SQL语句中使用的主语言程序变量简称为主变量(Host Variable)或宿主变量。按用途分:

    • 输入变量
      • 指定向数据库中插入的数据;
      • 将数据库中的数据修改为指定值;
      • 指定执行的操作;
      • 指定WHERE子句或HAVING子句中的条件;
    • 输出变量
      • 获取SQL语句的结果数据
      • 获取SQL语句的执行状态
  • 主变量的使用

    • 输入主变量
      • 由应用程序对其赋值,SQL语句引用
    • 输出主变量
      • 由SQL语句赋值或设置状态信息,返回应用程序
    • 一个主变量有可能既是输入主变量又是输出主变量
    • 主变量可以出现在SQL语句中任何一个能够使用表达式的地方
    • 先说明后使用
    • 为了区别于数据库对象(表、视图、列等),在SQL语句中,主变量前要加冒号“”作为标志。
  • 主变量的说明格式

    EXEC SQL BEGIN DECLARE SECTION;
    <主变量>
    EXEC SQL END DECLARE SECTION;
    
MySQL与Python
  • 嵌入式SQL通过主变量与主语言程序进行数据交换

  • PyMySQL中,主变量 = Python中的普通变量,在SQL语句中使用的主语言程序变量,简称主变量(Host Varaible)。主变量按用途分类:

    • 输入变量

      • 指定向数据库中插入的数据;
      • 将数据库中的数据修改为指定值;
      • 指定执行的操作;
      • 指定WHERE子句或HAVING子句中的条件;

      示例(插入一条记录):

      sno = "S01"
      sname = "张三"
      sage = 20
      cursor.execute("INSERT INTO Student (Sno, Sname, Sage) VALUES (%s, %s, %s)", (sno, sname, sage))
      
    • 输出变量

      • 获取SQL语句的结果数据;
      • 获取SQL语句的执行装填(Pythontry/except实现)

      示例(输出查询结果)

      cursor.execute("SELECT Sname FROM Student WHERE Sno = %s",("S01,"))
      result = cursor.fetchone()
      print("学生姓名:",resultp[0])
      
  • 主变量的使用

    • 输入主变量

      • 由应用程序对其赋值,SQL语句引用
    • 输出主变量

      • 由SQL语句执行后将结果写入变量,再由应用程序使用
    • 同一个主变量可以同时作为输入和输出变量

    • 可以出现在 SQL 中任意表达式的位置

    • 先定义再使用

    • 在C语言中主变量要加前缀:,而Python中不用加

      C语言嵌入式SQLPython PyMySQL 实现
      EXEC SQL SELECT Sname INTO :name ...cursor.execute("SELECT Sname WHERE ...")
      :变量名(代表主变量)使用 Python 普通变量即可,无需特殊标记
  • 主变量的说明格式

    Python中主变量“说明格式”就是变量定义

    在C中:

    EXEC SQL BEGIN DECLARE SECTION;
    char Sno[6];
    int Age;
    EXEC SQL END DECLARE SECTION;
    

    在Python中:

    sno = "S02"
    age = 20
    

    无需声明块,直接定义即可使用。

4. 面向集合和面向记录的协调
SQL与C语言
  • SQL语句是面向集合的,一条SQL语句可以产生或处理多条记录;主语言是面向记录的,一组主变量一次只能存放一条记录。
  • 使用主变量并不能满足SQL语句面向应用程序输出数据的要求。
  • 嵌入式SQL引入游标(cursor)机制来协调面向集合和面向记录的不同处理方式。
    • 游标是系统为用户开设的一个数据缓冲区里,存放SQL语句的执行结果。
    • 游标包含两部分:
      1. 定义该游标的SELECT语句返回的结果集
      2. 指向结果集中某一行的指针

MySQL与Python

  • SQL语言是面向集合的,Python是面向记录的

    • SQL是面向集合的,一条SQL语句可以产生或处理 多条记录,如

      SELECT * FROM Student;
      

      会一次性返回所有学生记录(结果集)

    • Python是面向记录的,程序中的变量一次只能存放一条记录(一个元组),Python必须通过循环、游标等方式,一行一行读取数据

  • 使用普通变量(主变量)无法满足SQL输出多个记录的需求

    • 一个变量如row = cursor.fetchone()只能接受一行
    • 要处理所有结果,就需要遍历
  • Python中的游标机制(cursor)

    Python的游标对象与SQL中的概念一致,本质上:是一个接口,用来协调SQL的集合结果和Python的记录式处理

  • Python实例:协调处理集合和记录

    import pymysql# 连接数据库
    conn=pymysql.connct(host="localhost",user='your_username',password="your_password",database='testdb')
    # 执行集合式查询(返回多个记录)
    cursor.excute("SELECT Sno,Sname,Sage FROM Student WHERE Sage > %s",(18,))
    for row in cursor.fetchall():sno,sname,sage = rowprint(f"学号:{sno},姓名:{sname},年龄:{sage}")conn.close()
    

不用游标的嵌入式SQL

SQL与C语言
  • 如果嵌入式SQL语句的执行结果为单记录,或一次处理多个记录而不是对记录逐个处理,可以不用游标。

  • 不用游标的SQL语句的种类

    • 说明性语句
    • 数据定义语句
    • 查询结果为单记录的SELECT语句
    • INSERT语句
    • CURRENT形式的UPDATE语句
    • CURRENT形式的DELETE语句
    • 授权和回收语句

    “非 CURRENT 形式的 UPDATE / DELETE 语句”
    意思是这些语句不依赖游标

  • 不用游标,用主变量;先说明,后使用。

    【例】定义字符串型主变量SnoSname

    EXEC SQL BEGIN DECLARE SECTION;CHAR Sno(6);CHAR Sname(8);……
    EXEC SQL END DECLARE SECTION;
    
    • 所有主变量在使用前需用DECLARE语句说明。
    • SQL语句中变量名前要加 :(冒号),此时变量名按C语言的大小写来解释

    【例】根据学号查询姓名和选修2号课的成绩

    EXEC SQL SELECT Sname,Cno,GradeINTO :Hsname,:Hcno,:HgradeFROM Student,SCWHERE Student.Sno = :Hsno AND Cno = '2'AND Student.Sno = SC.Sno;
    
    • Hsno为输入主变量,在执行该语句前,应先用主语言命令给Hsno赋值
    • INTO子句指定将查询结果放入相应的主变量(按顺序对应)

    【例】在学生选课中插入选课成绩。

    EXEC SQL INSERT INTO SCVALUES (:Sno,:Cno,:GRADE);
    
    • 在执行该语句前,应先给主变量赋值,然后执行该语句,将选课成绩插入SC表。

    【例】给出学生的学号和要修改的课程号,修改学生选修记录。

    EXEC SQL UPDATE SCSET Cno = :HnewcnoWHERE Sno = :Hsno AND Cno = :Holdcno;
    
    • 主变量Holdcno中为修改前的课程号,Hnewcno中为修改后的课程号。
    • 非CURRENT形式的UPDATE语句可以操作多条记录。

    【例】给出学号和课程号,删除学生选课记录。

    EXEC SQL DELETE FROM SCWHERE Sno = :Hsno AND Cno = :Hcno;
    
    • 非CURRENT形式的DELETE语句可以操作多个元组
MySQL与Python
  • 不用游标的适用场景:如果SQL执行结果是单条记录,或不是逐条处理结果集,就可以不用游标,直接用主变量完成。

  • 不用游标的SQL语句类型

    • 说明性语句(Python中不涉及)
    • 数据定义语句(如CREATE TABLE
    • 查询结果为单记录的SELECT语句
    • INSERT语句
    • CURRENTUPDATEDELETE
    • 授权和回收语句(不常用)
  • Python中主变量的使用方式:

    同样是先说明再使用,但是简单得多

    C语言格式:

    EXEC SQL BEGIN DECLARE SECTION;CHAR Sno(6);CHAR Sname(8);
    EXEC SQL END DECLARE SECTION;
    

    Python中:

    Sno = "S01";
    Sname = "张三";
    

    无需DECLARE,变量即主变量

  • Python中游标和C语言嵌入SQL中有些不同

    术语C语言嵌入式SQL中的含义Python / PyMySQL 中的含义
    游标(cursor)是数据库中面向集合处理的“数据指针”是 Python 中操作数据库必须创建的对象
    不用游标指不使用 DECLARE CURSOR 来处理多条记录不是说不创建 Python 的 cursor 对象
    • Python中的cursor本质上是一个 操作接口(我们必须用它来 exexute SQL语句),不是C语言中的“显示游标声明”
    类比MySQL术语Python术语
    SQL 游标DECLARE C1 CURSOR FOR ...用于处理多行结果(循环FETCH)
    Python 操作句柄db.cursor()用于执行任何 SQL 操作(必须有)
【例】根据学号查询学生姓名和选修2号课的成绩
import pymysql # 导入 PyMySQL模块(用于操作MySQL数据库)#连接到 MySQL 数据库
db = pymysql.connect(host = 'localhost',user = 'your_username',# 填写自己的用户名password = 'your_password',# 填写自己的密码database = 'sst'
)
# 创建 cursor对象,用于执行SQL语句(这是PyMySQL必须的操作句柄)
cursor = db.cursor()# -----------------示例1:单记录查询--------
# 模拟主变量 Hsno,输入学号,查询该学生选修 C2 的成绩
hsno = "200701"# 执行查询语句(只查询一条记录,因此不用 DECLARE CURSOR 等)
cursor.execute("""SELECT Sname,Cno,GradeFROM Student,SCWHERE Student.Sno = %s AND Cno = '2' AND Student.Sno = SC.Sno""",(hsno,))
# 获取查询结果的一行,赋值给 Python 变量(相当于主变量输出)
row = cursor.fetchone()
if row != None:hsname,hcno,hgrade = rowprint(f"[查询成功] 姓名:{hsname},课程号:{hcno},成绩:{hgrade}")
else:print("[查询结果]未找到该学生选修2号课程的记录")cursor.close()
  • cursor = db.cursor()

    • cursor是一个 游标对象
    • 作用是:用来执行 SQL语句,获取数据库返回的结果
    • 可以理解为我们访问数据库的”工具句柄“

    常见用法:

    cursor = db.cursor()	# 创建游标
    cursor.execute(……)		# 执行 SQL
    result = cursor.fetchone()# 获取一条结果
    cursor.close()			# 关闭游标
    
  • cursor.execute()

    • execute()游标对象 cursoe的方法
    • 用来执行一条 SQL 语句(查询、插入、更新、删除等)
    • 可以配合占位符 %s 和参数传递,避免SQL注入风险

    示例

    cursor.execute("SELECT * FROM Student WHERE Sno = %s",(hsno,))
    

    说明:

    • SQL中 %s 是占位符;
    • (hsno,)是一元元组,其中的值会安全地绑定进去,不会被当作SQL字符串拼接。
  • row = cursor.fetchone()

    • fetchone()方法会从SQL查询结果中读取一行数据
    • 如果没有数据,会返回None
    • 结果通常一个 元组(tuple),包含这一行所有字段的值

    示例:

    row = cursor.fetchone()
    if row:name,course,grade = rowprint(name,course,grade)
    
  • f"……"

    • 这是 Python 的 f-string(格式化字符串)
    • 语法是:字符串前面加f,字符串中用{变量}来嵌入变量值
    • 从从 Python 3.6 开始支持,写法直观、清晰、推荐使用

    示例:

    name = "张三"
    score = 90
    print(f"姓名:{name}, 成绩:{score}")
    

    等价于

    print("姓名:" + name + ", 成绩:" + str(score))
    
  • Python中print()函数的输出机制

    1. print()函数语法详解

      print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
      
      参数含义默认值示例
      *objects要打印的多个对象必须指定"hello", "world"
      sep多个对象之间的分隔符' '(空格)sep=',' 输出 hello,world
      end结尾追加的内容'\n'(换行)end='' 表示不换行
      file输出流sys.stdout通常默认即可
      flush是否强制刷新缓冲区False用于调试
    2. 常用示例

      • 多个对象之间自定义分隔符

        print("hello", "world", sep=", ")
        

        输出:

        hello,world
        
      • 不换行输出

        print("hello", end="") 
        print("world")
        

        输出:

        helloworld
        
      • 结合变量和 f-string 输出更复杂内容

        name = "小明"
        score = 95
        print(f"学生 {name} 的成绩是 {score}")
        

        输出:

        学生 小明 的成绩是 95
        
【例】在学生选课表中插入选课成绩。
# ------------示例2:插入记录
cursor = db.cursor()
sno = "200701"
cno = "4"
grade = 88
cursor.execute("""INSERT INTO SC (Sno,Cno,Grade)VALUES (%s ,%s ,%s)""",(sno,cno,grade)
)
db.commit()
print("[插入成功] 新选课记录已添加")
  • db.commit()
    • 提交当前事务,把之前执行的 INSERTUPDATEDELETE 等更改真正保存到数据库中
【例】给出学生的学号和要修改的课程号,修改学生选修记录
import pymysqldb = pymysql.connect(host='localhost',port = 3306,user='your_username',passwd='your_password',database="your_database"
)cursor = db.cursor()
hsno = "200701"
holdcno = "4"
hnewcno = "5"
cursor.execute("""UPDATE sst.SCSET Cno = %s WHERE Sno = %s AND Cno = %s""",(hnewcno,hsno,holdcno))
db.commit()
print("[更新成功] 课程号已从 C2 改为 C3")
  • 非CURRENT形式的UPDATE语句可以操作多个元组,,只要 SQL 语句的条件匹配多行。
【例】给出学号和课程,删除学生的选课记录
# 连接数据库
cursor = db.cursor()
hsno = "200701"
hcno = "5"
cursor.execute("""DELETE FROM SCWHERE Sno = %s AND Cno = %s""",(hsno,hcno))
db.commit()
print("[删除成功] 已删除选课记录")
cursor.close()
db.close()
  • 非CURRENT形式的UPDATE语句可以操作多个元组,,只要 SQL 语句的条件匹配多行。

用游标的嵌入式SQL

SQL与C语言
  • 主语言一次只能处理一条记录,当处理的结果为多条记录时,需借助游标机制,把对结果集的操作转化为对单个记录的处理
  • 必须使用游标的SQL语句
    • 查询结果为多条记录的SELECT语句
    • CURRENT形式的UPDATE语句
    • CURRENT形式的DELETE语句
  • 使用游标的步骤
    1. 定义游标
    2. 打开游标
    3. 推动游标
    4. 关闭游标
1、定义游标
  • 使用DECLARE语句

  • 语句格式

    EXEC SQL DECLARE <游标名> CURSOR
    FOR <SELECT语句>[FOR UPDATE OF <列名>];
    
  • 功能

    • 说明性语句:不会真正访问数据库,而是告诉预编译器或编译器如何处理SQL的声明性语句。
    • 用于建立游标和SELECT语句之间的关系,并不执行SELECT语句
    • FOR UPDATE OF子句表示更新查询结果中的列
2、打开游标
  • 使用OPEN子句

  • 语句格式

    EXEC SQL OPEN <游标名>;
    
  • 功能

    • 执行与游标关联的SQL查询语句,并将查询结果放入数据缓冲区。
    • 此时游标处于打开装态,游标指向查询结果集中第一条记录之前的位置。
3、推动游标
  • 使用FETCH语句

  • 语句格式

    EXEC SQL FETCH <游标名>
    INTO <主变量>[,<主变量>]……;
    
  • 功能

    • 把游标向前推进一个位置,然后按照游标的当前位置取一条记录(元组),将元组的值赋给对应的主变量。

    • 每执行一次该语句,游标向前推进一个位置。

    • 如果最后游标指针所指的位置为空,则SQLCODE返回一个状态码,表示缓冲区没有可处理的元组。

      SQLCODE是嵌入式SQL中的一个状态码变量,当执行SQL语句时,系统会自动设置它的值

      SQLCODE值意义
      0执行成功
      +100没有更多数据(FETCH 到底)
      <0执行错误
4、关闭游标
  • 使用CLOSE语句

  • 语句格式

    EXEC SQL CLOSE <游标名>
    
  • 功能

    • 关闭游标,释放结果集占用的缓冲区及其他资源
  • 说明

    • 游标被关闭后,就不再和原来的查询结果集相联系
    • 被关闭的游标可以再次被打开,与新的查询结果相联系
游标使用示例

使用游标查询学生选课记录。

EXEC SQL DECLARE C1 CURSOR FOR
SELECT Sno,Cno,Grade FROM SC;
EXEC SQL OPEN C1;
while(1){EXEC SQL FETCH C1INTO :Hsno,:Hcno,:Hgrade;if (sqlca,sqlcode != 0) break;printf("sno:%s,cno:%s,grade:%d",Hsno,Hcno,Hgrade);……
};
EXEC SQL CLOSE C1;
游标的扩充
  • 为进一步方便用户处理数据,现在一些关系数据库关系系统对FETCH语句做了扩充,允许用户向任意方向以任意步长移动游标指针。

  • SQL2提供了滚动游标(Scroll Cursor)

    • EXEC SQL DECLARE <游标名> SCROLL CURSOR
      FOR <SELECT 语句>[FOR UPDATE OF <列名>];
      
    • EXEC SQL FETCH [NEXT|PRIOR|FIRST|LAST|ABSOLUTE n|RELATIVE n]<游标名>INTO <主变量>[,<主变量>]……;
      

      FETCH [NEXT | PRIOR | FIRST | LAST | ABSOLUTE n | RELATIVE n] <游标名> INTO <主变量>:使用不同的选项控制游标的移动:

      • NEXT:向前移动到结果集的下一条记录。
      • PRIOR:向后移动到结果集的上一条记录。
      • FIRST:移动到结果集的第一条记录。
      • LAST:移动到结果集的最后一条记录。
      • ABSOLUTE n:移动到结果集的第n条记录。
      • RELATIVE n:相对当前位置移动n条记录(向前或向后)。
CURRENT形式的UPDATE和DELTE语句
  • CURRENT形式的更新语句格式:

    EXEC SQL UPDATE <表名>SET = <表达式>WHERE CURRENT OF <游标名>
    
    • CURRENT OF <游标名>表示当前游标所指的记录
    • 要求游标的定义带有FOR UPDATE子句
  • CURRENT形式的删除语句格式为:

    EXEC SQL DELETE FROM <表名>WHERE CURRENT OF <游标名>;
    
    • 要求使用带FOR UPODATEDECALARE语句定义游标
MySQL与Python
  • 主语言一次只能处理一条记录,当处理的结果为多条记录时,需借助游标机制,把对结果集的操作转化为对单个记录的处理
  • 必须使用游标的SQL语句
    • 查询结果为多条记录的SELECT语句
    • CURRENT形式的UPDATE语句
    • CURRENT形式的DELETE语句
  • 使用游标的步骤
    1. 定义游标
    2. 打开游标
    3. 推动游标
    4. 关闭游标
1、定义游标

​ 在Python中,使用PyMySQL不需要显示声明游标,而是直接使用cursor对象进行查询操作。游标对象会自动处理与SQL查询的关系。

​ 在PyMySQL中,cursor 是一个非常关键的对象,它的作用是用来执行SQL查询并获取结果。可以把它理解为数据库操作的“接口”,它使得您能够执行SQL语句并从数据库获取数据。虽然它是一个“接口”,但它也具有存储结果集的功能。

  1. cursor的角色

​ 在数据库编程中,游标(cursor)通常指代一个指向查询结果集的指针,用于逐条检索数据。在PyMySQL中,cursor对象充当了这个角色,允许我们执行查询、获取结果以及管理数据库连接。

  1. cursor的功能
  • 执行SQL语句:游标对象允许我们执行SQL语句(例如SELECTINSERTUPDATEDELETE等),并返回结果。
  • 存储结果集:当执行SELECT查询时,结果集会存储在游标对象中。游标通过fetchall()fetchone()等方法来访问这些数据。
  • 提供接口与数据库通信:通过cursor对象,Python代码与数据库之间建立了一个连接,您可以通过它传递SQL语句、获取执行状态或获取查询结果。
  1. cursor如何存取结果集

当执行查询时,游标会与数据库建立一个内部连接,并从数据库中检索数据。数据会存储在游标对象的内部缓冲区中。我们可以通过以下几种方法从游标中获取数据:

  • fetchall():返回查询结果中的所有记录,通常是一个列表,列表中的每个元素代表查询结果集中的一行数据。
  • fetchone():返回查询结果中的下一行(如果有的话),每次调用会返回查询结果集中的一条记录。
  • fetchmany(n):返回查询结果中的前n条记录。
2、打开游标

Python中,使用PyMySQL时没有显示的OPEN语句。cursor.execute()执行查询后,游标会自动打开并准备结果集供后续操作。

结果集是指执行SQL查询语句后返回的数据集合。

Python中,使用PyMySQL时,当我们执行查询(SELECT)语句后,数据库返回的结果集会存储在游标对象(cursor)中。你可以通过游标对象的方法来访问这些数据。

  • fetchall():返回查询结果集中的所有记录。
  • fetchone():返回结果集中的第一条记录。
  • fetchmany(n):返回结果集中的前n条记录。
3、推动游标

在Python中,PyMySQL的游标对象支持fetchone()fechall()等方法,可以逐行读取结果。

  • fetchone():获取查询结果的下一条记录。
  • fetchall():获取查询结果的所有记录。

示例代码:fetchone()

import pymysql# 连接到MySQL数据库
db = pymysql.connect(host='localhost',user='root',password='password',database='pharma_sales_system'
)cursor = db.cursor()# 执行查询,获取学生信息
cursor.execute("SELECT Sno, Sname, Sdept FROM Student WHERE Sage > %s", (18,))# 使用fetchone()逐行获取结果
row = cursor.fetchone()  # 获取第一行
while row:print(f"学号: {row[0]}, 姓名: {row[1]}, 专业: {row[2]}")row = cursor.fetchone()  # 获取下一行cursor.close()
connection.close()

示例代码:fetchall()

在使用fetchall()时,它会一次性获取查询结果的所有行,并返回一个包含所有行的列表,每一行是一个元组。

'''
一样先连接数据库
'''
cursor = db.cursor()# 执行查询,获取学生信息
cursor.execute("""SELECT Sno,Sname,Sdetp FROM StudentWHERE Sage > %s""",(18,))# 使用fetchall()获取所有结果
rows = cursor.fetchall()for row in rows:print(f"学号:{row[0]},姓名:{row[1]},专业:{row[2]}")curosr.close()
db.close()
4、关闭游标

在Python中,游标是一个负责数据库操作的对象。通过使用完游标后,通常我们会调用cursor.close()来关闭游标并释放资源。

游标的使用示例
import pymysqldb = pymysql.connect(host = 'localhost',user = 'your_username',password = 'your_password',database = 'your_database'
)cursor = db.cursor()cursor.execute("""SELECT Sno ,Sname,Ssex,Sage,SdeptFROM StudentWHERE Sage > 18""")row = cursor.fetchone()
while row is not None:print(row)row = cursor.fetchone()cursor.close()
db.close()
滚动游标的扩充

滚动游标Scroll Cursor)是SQL2标准的一项扩展,它允许开发者对游标进行更灵活的控制。与普通的游标只能向前逐条处理查询结果集不同,滚动游标允许您向前、向后或根据指定位置自由地在查询结果集中移动游标。

  • 什么是滚动游标

    滚动游标允许程序员控制游标的移动方向,不仅限于“下一条记录”,还可以“上一条”,或者直接跳转到结果集中的任何一条记录,甚至是从当前位置相对偏移一定数量,或者直接跳到绝对某一记录。

  • 滚动游标的有点

    • **灵活性:**滚动游标提供了比普通游标更多的控制,可以随时调整游标的位置,不需要依赖默认的向前查询结果。
    • 性能:对于需要访问查询结果集不同部分的数据(例如随机访问或反向迭代),滚动游标比普通游标更有效。
  • 滚动游标的语法

    虽然PyMySQL并不直接支持滚动游标(即没有直接的SCROLL CURSOR语法),但我们可以通过对查询结果集进行操作,模拟滚动游标的行为。

    示例:模拟滚动游标

    Python中,使用fetchall()方法可以获取所查询结果,之后我们可以通过手动管理索引来模拟游标的“滚动”行为。

    import pymysql# 连接到MySQL数据库
    db = pymysql.connect(host='localhost',user='root',password='password',database='pharma_sales_system'
    )cursor = db.cursor()# 执行查询操作
    cursor.execute("SELECT Sno, Sname, Sdept FROM Student WHERE Sage > %s", (18,))
    students = cursor.fetchall()  # 获取所有查询结果# 模拟滚动游标
    index = 0# 向前(模拟NEXT)
    print("向前(模拟NEXT):")
    while index < len(students):print(f"学号: {students[index][0]}, 姓名: {students[index][1]}, 专业: {students[index][2]}")index += 1# 向后(模拟PRIOR)
    print("\n向后(模拟PRIOR):")
    while index > 0:index -= 1print(f"学号: {students[index][0]}, 姓名: {students[index][1]}, 专业: {students[index][2]}")cursor.close()
    db.close()
CURRENT形式的UPDATE和DELTE语句

​ 在Python中,我们通过cursor.execute()来执行UPDATE语句,而不需要CURRENT关键字。我们可以通过查询来选择特定记录,然后更新它们。

示例:更新成绩(直接执行UPDATE操作)(一次运行只能删除一个)

import pymysqldb = pymysql.connect(host = 'localhost',user = 'your_username',password = 'your_password',database = 'yout_database'
)cursor = db.cursor()# 假设我们要更新选修数据库课程的学生成绩
cursor.execute("""SELECT Sno,Cno,GradeFROM SCWHERE Grade < %s""",(80,))# 使用fetchone()逐条获取查询结果并更新
row = cursor.fetchone()
while row :sno = row[0]cno = row[1]grade = row[2]# 更新当前记录的成绩,假设成绩加5分new_grade = grade + 5cursor.execute("""UPDATE SCSET Grade = %sWHERE Sno = %s AND Cno = %s""",(new_grade,sno,cno))row = cursor.fetchone()db.commit()
cursor.close()
db.close()

错误:该代码一次运行,只能更改一行元组(成绩小于80)。

原因:

  1. cursor.execute("""SELECT Sno,Cno,Grade FROM SC WHERE Grade < %s""",(80,))之后;
  2. 对应的数据库会建立一个虚表,然后cursor会指向虚表的第一行数据
  3. cursor.execute("""UPDATE SC SET Grade = %s WHERE Sno = %s AND Cno = %s""",(new_grade,sno,cno))之后,cursor会被刷新,就是说,cursor更新完对应的元组后,cursor会指向“无结果集”状态
  4. 那么下一行row = cursor.fetchone()row将会是None

解决方案:

  1. 使用两个游标,一个保留查询结果集,一个用作更新
  2. 一次性全部更新,像下面这个示例

示例:更新成绩(执行UPDATE操作)(正确)

import pymysqldb = pymysql.connect(host = 'localhost',user = 'root',password = 'your_password',database = 'your_database'
)cursor = db.cursor()# 假设我们要更新选修数据库课程的学生成绩
cursor.execute("""SELECT Sno, Cno, GradeFROM SCWHERE Grade < %s""", (80,))# 使用fetchone()逐条获取查询结果
rows_to_update = []  # 存储要更新的数据
row = cursor.fetchone()
while row:sno = row[0]cno = row[1]grade = row[2]# 更新当前记录的成绩,假设成绩加5分new_grade = grade + 5rows_to_update.append((new_grade, sno, cno))  # 将要更新的数据保存到列表中row = cursor.fetchone()# 批量更新成绩
cursor.executemany("""UPDATE SCSET Grade = %sWHERE Sno = %s AND Cno = %s""", rows_to_update)# 提交一次事务
db.commit()cursor.close()
db.close()
  • executemany()executemany()方法用于一次性执行多个SQL语句,并将一组参数传递给每个语句。它的用法是将SQL语句和一个包含多组参数的列表传递给它,执行时会将每个参数组合并执行对应的SQL语句。

    语法:cursor.executemany(sql, args)

    • sql:需要执行的 SQL 语句,通常是带有占位符(例如 %s)的查询或更新语句。

    • args:包含多组参数的可迭代对象(例如列表、元组或生成器)。每一组参数都将被传递给 SQL 语句中的占位符。

    在你代码中的使用:

    ​ 在你提供的代码中,executemany() 用来执行批量更新操作,将多个 UPDATE 语句合并成一个批量执行的操作。具体来说:

    1. 构建数据
      你先通过 fetchone() 获取所有需要更新的记录,并将它们存储到一个列表 rows_to_update 中。每一条数据都是一个包含 (new_grade, sno, cno) 的元组,其中:

      • new_grade 是更新后的成绩,
      • sno 是学生的学号,
      • cno 是课程编号。
    2. 执行批量更新

      python复制代码cursor.executemany("""UPDATE SCSET Grade = %sWHERE Sno = %s AND Cno = %s
      """, rows_to_update)
      

      executemany() 会将 rows_to_update 列表中的每一个元组传递给 SQL 语句中的占位符 %s,然后批量执行多个更新操作。

      假设 rows_to_update 列表中有以下内容:

      python复制代码rows_to_update = [(85, 101, 'CS101'),(88, 102, 'CS102'),(90, 103, 'CS103')
      ]
      

      那么 executemany() 会执行以下三个 UPDATE 语句:

      sql复制代码UPDATE SC SET Grade = 85 WHERE Sno = 101 AND Cno = 'CS101';
      UPDATE SC SET Grade = 88 WHERE Sno = 102 AND Cno = 'CS102';
      UPDATE SC SET Grade = 90 WHERE Sno = 103 AND Cno = 'CS103';
      
    3. 提交事务
      调用 db.commit() 后,所有更新操作将一起提交到数据库中,确保数据的一致性和原子性。

示例:删除数据

```
连接数据库
```cursor = db.cursor()cursor.execute("""SELECT Sno,Cno FROM SCWHERE Grade < 60""")rows = cursor.fetchall()
cursor_delete = db.cursor()
for row in rows:cursor_delete.execute("DELETE FROM SC WHERE Sno = %s AND Cno = %s",(row[0],row[1]))db.commit()
cursor.close()
cursor_delete.close()
db.commit()

嵌入式SQL应用示例

SQL与C语言
  • 应用实例

    下面通过一个 C 语言的例子说明嵌入式 SQL 的编程框架和嵌入式 SQL 语句的使用。在这个例子中,使用游标查询并显示学生选修课的成绩,如果成绩在 85 分以上,显示成绩为“优”,在 75~84 之间,成绩为“良”,在 60~74 之间,成绩为“及格”,在 60 分以下,成绩为“不及格”。

    #include <stdio.h>/* 定义变量段 */
    EXEC SQL BEGIN DECLARE SECTION;CHAR uid[20];CHAR pwd[20];CHAR hname[20];CHAR hcno[6];INT hgrade;CHAR hsno[10];
    EXEC SQL END DECLARE SECTION;/* 定义嵌入SQL环境 */
    EXEC SQL INCLUDE SQLCA;int main()
    {char g[6];/* 建立与DBMS的连接 */strcpy(uid, "user");strcpy(pwd, "sql");EXEC SQL CONNECT :uid IDENTIFIED BY :pwd;/* 输入课程号 */scanf("%s", hcno);/* 定义游标 */EXEC SQL DECLARE C1 CURSOR FORSELECT Sno, GradeFROM SCWHERE Cno = :hcno;/* 打开游标 */EXEC SQL OPEN C1;/* 逐行提取记录 */while (1) {EXEC SQL FETCH C1 INTO :hsno, :hgrade;if (sqlca.sqlcode < 0)  // 错误break;if (hgrade >= 85)strcpy(g, "优");else if (hgrade >= 75)strcpy(g, "良");else if (hgrade >= 60)strcpy(g, "及格");elsestrcpy(g, "不及格");printf("Sno: %s   Grade: %s\n", hsno, g);}/* 关闭游标 */EXEC SQL CLOSE C1;/* 提交事务,退出 */EXEC SQL COMMIT WORK RELEASE;return 0;
    }
  • 依次检查某个系的学生记录,交互式更新某些学生年龄

    #include <stdio.h>/* 主变量说明开始 */
    EXEC SQL BEGIN DECLARE SECTION;char Deptname[20];char Hsno[9];char Hsname[20];char Hssex[2];int Hsage;int NEWAGE;
    EXEC SQL END DECLARE SECTION;
    /* 主变量说明结束 *//* 定义SQL通信区 */
    EXEC SQL INCLUDE SQLCA;int main(void)  /* C语言主程序开始 */
    {int count = 0;char yn;  // 变量 yn 表示是否更新(yes/no)printf("Please choose department name(CS/MA/IS): ");scanf("%s", Deptname);  // 为主变量 Deptname 赋值/* 连接数据库 TEST */EXEC SQL CONNECT TO TEST@localhost:54321 USER "SYSTEM"/"MANAGER";/* 定义游标 SX */EXEC SQL DECLARE SX CURSOR FORSELECT Sno, Sname, Ssex, SageFROM StudentWHERE SDept = :Deptname;/* 打开游标 SX,指向查询结果第一行 */EXEC SQL OPEN SX;/* 用循环结构逐条处理结果集中的记录 */for (;;) {/* 推进游标,将当前数据放入主变量 */EXEC SQL FETCH SX INTO :Hsno, :Hsname, :Hssex, :Hsage;if (SQLCA.SQLCODE != 0)  // SQLCODE != 0 表示无数据或错误break;/* 如果是第一行,打印表头 */if (count++ == 0) {printf("\n%-10s %-20s %-10s %-10s\n", "Sno", "Sname", "Ssex", "Sage");}/* 打印查询结果 */printf("%-10s %-20s %-10s %-10d\n", Hsno, Hsname, Hssex, Hsage);/* 询问是否更新当前学生年龄 */printf("UPDATE AGE (y/n)? ");do {scanf(" %c", &yn);} while (yn != 'N' && yn != 'n' && yn != 'Y' && yn != 'y');if (yn == 'y' || yn == 'Y') {printf("INPUT NEW AGE: ");scanf("%d", &NEWAGE);/* 嵌入式SQL更新语句 */EXEC SQL UPDATE StudentSET Sage = :NEWAGEWHERE CURRENT OF SX;  // 对当前游标指向的学生进行更新}}/* 关闭游标 SX */EXEC SQL CLOSE SX;/* 提交事务,断开数据库连接 */EXEC SQL COMMIT WORK;EXEC SQL DISCONNECT TEST;return 0;  // C语言主程序结束
    }
    
Python与MySQL
  • 应用实例

    下面通过一个 C 语言的例子说明嵌入式 SQL 的编程框架和嵌入式 SQL 语句的使用。在这个例子中,使用游标查询并显示学生选修课的成绩,如果成绩在 85 分以上,显示成绩为“优”,在 75~84 之间,成绩为“良”,在 60~74 之间,成绩为“及格”,在 60 分以下,成绩为“不及格”。

    import pymysql# 连接到数据库
    db = pymysql.connect(host='localhost',user='your_username',password='your_password',database='your_database',charset='utf8mb4'
    )cursor = db.cursor()
    # 用户输入课程号
    hcno = input("请输入课程号 Cno:")# 使用参数化查询,防止SQL注入
    cursor.execute("""SELECT Sno,Grade FROM SCWHERE Cno = %s""",(hcno,))# 逐行提取记录
    row = cursor.fetchone()
    while row:hsno,hgrade = row# 判断成绩if hgrade >= 85:g = '优'elif hgrade >= 75:g = '良'elif hgrade >= 60:g = '及格'else:g = '不及格'print(f"Sno:{hsno} Grade:{g}")row = cursor.fetchone()
    #提交事务(此处虽然是只读查询,但保留习惯)
    db.commit()
    # 关闭资源
    cursor.close()
    db.close()
    
    • 什么是SQL注入?

      SQL注入是一种攻击方式,攻击者通过在输入中插入恶意SQL代码,是的程序原本预期执行的SQL查询变成攻击者想要执行的内容,进而获取、修改甚至删除数据库中的数据,

      举个例子:

      hcno = input("请输入课程号:")
      cursor.execute("SELECT Sno, Grade FROM SC WHERE Cno = '" + hcno + "'")
      

      如果用户输入的是正常的课程号,如4,那么SQL执行的是:

      SELECT Sno, Grade FROM SC WHERE Cno = '4'
      

      但如果有人输入的是:4' OR '1' = 1

      那么拼接后的SQL语句是:

      SELECT Sno, Grade FROM SC WHERE Cno = '4' OR '1'='1'
      

      这会导致:

      • 查询条件恒为真
      • 数据库可能返回所有学生成绩
      • 攻击者绕过安全验证,甚至篡改数据
    • 因此我们采用参数化查询

      参数化查询不会直接把用户输入拼接到 SQL 字符串中,而是将用户输入作为参数绑定,在执行时由数据库自动处理转义和类型检查,从而 避免恶意代码被解释为 SQL 语句的一部分

      cursor.execute("SELECT Sno, Grade FROM SC WHERE Cno = %s", (hcno,))
      
  • 依次检查某个系的学生记录,交互式更新某些学生年龄

    import pymysql# 连接到MySQL数据库
    db = pymysql.connect(host='localhost',user='your_username',password='your_password',database='your_database',  # 替换为实际的数据库名称charset='utf8mb4'
    )cursor = db.cursor()# 用户输入专业名称
    Depaname = input("请输入专业名吃称(计算机系/外语/数学):")# 执行查询,获取指定系别的学生记录
    cursor.execute("""SELECT Sno,Sname,Ssex,Sage FROM StudentWHERE Sdept = %s """,(Depaname,))# 打印表头
    print("\n %-10s %-20s %-10s %-10s" %("Sno","Sname","Ssex","Sage"))# 逐条处理查询结果并更新
    count = 0
    while True:row = cursor.fetchone()if not row:breakhsno,hsname,hssex,hsage = row# 打印当前学生信息print("%-10s %-20s %-10s %-10s" % (hsno,hsname,hssex,hsage))# 询问是否更新当前学生年龄yn = input("是否更新学生年龄,y/n (y/n)?").strip().lower()if yn == 'y':new_age = int(input("输入新的年龄:"))# 执行更新,更新当前学生的年龄cursor_update = db.cursor()cursor_update.execute("""UPDATE StudentSET Sage = %sWHERE Sno = %s""",(new_age,hsno))count += 1# 提交事务(保存所有更改)
    db.commit()# 关闭游标和数据库连接
    cursor.close()
    db.close()print(f" {count} students.")
    

动态SQL

SQL与C语言
  • 静态SQL

    • 数据库对象、查询条件以及所做的操作,在预编译时都是确定的。
    • 语句主变量的个数与数据类型在预编译时也是确定的。
    • 用户可以在程序运行过程中根据实际需要输入WHERE子句或HAVING子句中某些变量的
    • 只是主变量的可以在程序运行过程中动态输入。
    • 静态SQL语句提供的编程灵活性在许多情况仍显的不足,不能编写更为通用的程序。
  • 动态SQL

    • 在程序运行期间临时组装SQL语句。
  • 动态SQL的应用范围

    • 预编译时下列信息不能确定时
      • SQL语句正文
      • 主变量个数
      • 主变量的数据类型
      • SQL语句中引用的数据库对象(列、索引、基本表、视图等)
  • 动态SQL的形式

    • 语句可变
      • 临时构造完整的SQL语句
    • 条件可变
      • WHERE子句中的条件
      • HAVING短语中条件
    • 数据库对象、查询条件均可变
      • SELECT子句的列明
      • FROM子句的表明或视图名
      • WHERE子句中的条件
      • HAVING短语中的条件
  • 动态SQL语句的参数化

    • 使用主变量
    • 动态参数
      • SQL语句中的可变元素;
      • 使用参数符号(?)表示该位置的数据在运行时设定
      • 输入不是在编译时完成绑定,而是通过PREPARE语句准备主变量和执行语句EXECUTE绑定数据或主变量来完成。
  • 动态SQL的执行方式

    • 即输入后直接执行

      EXEC SQL EXECUTE IMMEDTATE <主变量1>;

    • 经过预处理后多次执行

      预处理语句格式:

      EXEC SQL PREPARE <语句名> FROM <主变量1>;
      

      执行语句格式:

      EXEC SQL EXECUTE <语句名> [USING <主变量2>];
      
    • 主变量1中存放可执行的SQL语句

    • 主变量2给出与语句名关联的SQL语句的参数

【直接执行】

String dstr = "DELETE FROM SC WHERE Sno = 'S01';";
const char *stms = "CREATE TABEL test(a int);";
EXEC SQL EXECUTE IMMEDIATE :dstr;
EXEC SQL EXECUTE IMMEDIATE :stms;

【预处理执行】

strcpy(dstr,"UPDATE SC SET Grade = :g WHERE Cno = '5';");
EXEC SQL PREPARE S1 FROM :dstr;
EXEC SQL EXECUTE S1 USING :HGrade;

【动态参数】

EXEC SQL BEGIN DECLARE SECTION;const char* stmt = "INSERT INTO test VALUES(?);";
EXEC SQL END DECLARE SECTION;
……
EXEC SQL PREPARE mystmt FROM :stmt;/*准备语句*/
EXEC SQL EXCUTE mystmt USING 100;/*执行语句,设定INSERT语句插入值100*/
EXEC SQL EXCUTE mystmt USING 200;/*执行语句,设定INSERT语句插入值200*/
MySQL与Python

概念描述差不多,执行方式有差别

Python实现动态SQL的方式

  • 直接拼接并执行SQL字符串(使用占位符 + 绑定参数)

    sql = "UPDATE Student SET Sage = %s WHERE SDept = %s"
    data = (22, 'CS')
    cursor.execute(sql, data)
    

Python中静态SQL示例

cursor.execute("""SELECT * FROM Student WHERE Sdept = %s AND Sage > %s""",("CS",20)
)

Python中动态SQL示例

base_sql = "SELECT * FROM Student"
conditions = []
dept = input ("请输入专业:")
if dept:conditions.append(f"Sdept = '{dept}'")min_age = input("请输入最低年龄:")
if min_age:conditions.append(f"Sage >= {min_age}")if conditions:base_sql = base_sql + " WHERE " + "AND".join(conditions)
  • join() 的作用是:把列表中多个字符串,用指定的连接符拼成一个新字符串

    假设我们有这个列表:

    conditions = ["Sdept = 'CS'", "Sage >= 20"]
    

    如果我们直接执行:

    " AND ".join(conditions)
    

    结果是:

    "Sdept = 'CS' AND Sage >= 20"
    

嵌入式SQL小结

  • 在嵌入式SQL中,SQL语句与逐语句分工非常明确
    • SQL语句直接与数据库打交道;
    • 主语言语句,控制程序流程,对SQL语句的执行结果做进一步加工处理。
  • SQL语句用主变量从主语言中接受执行参数,操纵数据库。
  • SQL语句的执行状态由DBMS送至SQLCA中,主语言程序从SQLCA中读取状态信息,据此决定下一步操作。
  • 如果SQL语句从数据库中成功检索出数据,则通过主变量传给主语言进行下一步处理。
  • SQL语言和主语言的不同数据处理方式通过游标来协调。

第四章小结

  • SQL的特点

    • 综合统一
    • 高度非过程化
    • 面向集合的操作方式
    • 同一种语法结构提供两种使用方式(这是指 SQL 中的某些语法结构,既可以用在交互式环境中(直接输入运行),也可以嵌入到程序语言中(嵌入式/API调用)
    • 语言简便,易学易用
  • 交互式SQL的功能

    • 数据定义(CREATEDROPALTER
    • 数据查询(SELECT
    • 数据更新(INSERTUPDATEDELETE
    • 数据控制(GRANTREVOKE
  • 数据查询

    • 对表的选取(FROM
    • 对列的选取(SELECT
      • 目标表达式、可更改列标题
    • 对行的选取(WHERE
      • 消除重复行,WHERE子句等条件表达式
    • 排序(ORDER BY
    • 聚集函数
      • MINMAXAVGSUMCOUNT……
    • 分组
      • GROUP BY(GROUP BY …… HAVING)
  • WHERE子句的条件表达式

    • 比较操作符

      =><>=<=<>

    • 确定范围

      BETWEEN…… AND……

    • 集合查找

      IN

    • 字符串匹配(LIKE、匹配符:_%

    • 空值运算

      IS NULL

    • 多重条件组合

      逻辑表达式或逻辑运算符

  • 单表查询

  • 多表连接查询

    • 条件连接
    • 等值连接
    • 自然连接
    • 外连接
    • 复合条件连接
    • 嵌套查询(子查询)
      • 不相关子查询
      • 相关子查询
  • 集合查询

  • 数据更新

    • 插入数据
      • 插入单条数据
      • 插入多条数据
    • 修改数据
      • 更新单表数据
      • 带子查询的数据修改
    • 删除数据
      • 删除单表数据
      • 带子查询的数据删除
  • 视图

    • 视图的作用
    • 创建视图
    • 使用视图
      • 查询
      • 更新(有条件的)
    • 视图查询的实现
      • 实体化
      • 视图消解
  • 嵌入式SQL

    • 与主语言的通信方式
      • SQL通信区(SQLCA)
      • 主变量
      • 游标
    • 静态SQL
      • 不用游标
      • 使用游标
    • 动态SQL

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词