过程化SQL数据库编程

article/2025/7/22 20:57:41

一、过程化SQL的块结构

基本的SQL是高度非过程化的语言。嵌入式SQL将SQL语句嵌入程序设计语言,借助高级语言的控制功能实现过程化。过程化SQL是对SQL的扩展,使其增加了过程化语句功能。
过程化SQL程序的基本结构是块。所有的过程化SQL程序都是由块组成的。这些块之间可以相互嵌套,每个块完成一个逻辑操作。
1.过程化SQL块的基本结构图示:
在这里插入图片描述
2. 变量和常量的定义
变量定义
变量名 数据类型 [[NOT NULL] :=初值表达式]
或者
变量名 数据类型 [[NOT NULL] 初值表达式]
常量定义
常量名 数据类型 CONSTANT:=常量表达式
常量必须要给一个值,并且该值在存在期间或常量的作用域内不能改变。如果试图修改它,过程化SQL将返回一个异常。
赋值语句
变量名 :=表达式
3. 流程控制
过程化SQL提供了流程控制语句,主要有条件控制语句和循环控制语句。这些语句的语法、定义和一般的高级语言类似。

  1. 条件控制语句
    1)IF语句
IF  condition  THENSequence_of_statements;     /*条件为真时语句序列才被执行*/
END IF      /*条件为假或NULL时什么也不做,控制转移至下一个语句*/

2)IF-THEN语句

IF  condition  THENSequence_of_statements1;     /*条件为真时语句序列才被执行*/
ELSESequence_of_statements2;     /*条件为假或NULL时才被执行*/  
END IF

3)嵌套的IF语句
在THEN和ELSE子句中还可以包含IF语句,IF语句可以嵌套。
2. 循环控制语句
1)最简单的循环语句LOOP

LOOPSequence_of_statements;    /*循环体,一组过程化SQL语句*/
END LOOP;

多数数据库服务器的过程化SQL都提供EXIT、BREAK或LEAVE等循环结束语句以保证LOOP语句块能够在适当的条件下提前结束。
2)WHERE-LOOP循环语句

WHERE condition LOOPSequence_of_statements;    /*条件为真时执行循环体内的语句序列*/
END LOOP;

每次执行循环体语句之前首先对条件进行求值,如果条件为真则执行循环体内的语句序列,如果条件为假则跳过循环并把控制传递给下一个语句。
3)FOR-LOOP

FOR count IN [REVERSE] bound1...bound2  LOOPSequence_of_statements;
END LOOP;

FOR循环的基本执行过程:
将count设置为循环的下界bound1,检查它是否小于上界bound2。当指定REVERSE时则将count设置为循环的上界bound2,检查count是否大于下界bound1。如果越界则执行跳出循环,否则执行循环体,然后按照步长(+1或-1)更新count的值,重新判断条件。
3. 错误处理
如果过程化SQL在执行时出现异常,则应该让程序在产生异常的语句处停下来,根据异常的类型去执行异常处理语句。
SQL标准对数据库服务器提供什么样的异常处理作出了建议,要求过程化SQL管理器提供完善的一次处理机制。

二、存储过程和函数

过程化SQL块主要有命名块和匿名块。匿名块每次执行时都要进行编译,它不能被存储到数据库中,也不能在其他过程化SQL块中调用。过程和函数是命名块,他们被编译后保存在数据库中,称为持久性存储模块(PSM),可以 被反复调用,运行速度较快。
1.存储过程
存储过程是由过程化SQL语句书写的过程,这个过程经编译和优化后存储在数据库服务器中,因此称它为存储过程,使用时只要调用即可。
1. 存储过程的优点
1)由于存储过程不像解释执行的SQL语句那样在提出操作请求时才进行语法分析和优化工作,因而运行效率高,它提供了在服务器端快速执行SQL语句的有效途径。
2)存储过程降低了客户机和服务器之间的通信量。客户机上的应用程序只要通过网络向服务器发出调用存储过程的名字和参数,就可以让关系数据库管理系统执行其中的多条SQL语句并进行数据处理,只有最终的处理结果才返回客户端。
3)方便实施企业规则。可以把企业规则的运算程序写成存储过程放入数据库服务器中,由关系数据库管理系统管理,既有利于集中控制,又能够方便地进行维护。当企业规则发生变化时只要修改存储过程即可,无需修改其他应用程序。
2. 存储过程的用户接口
1)创建存储过程

CREATE OR REPLACE PROCEDURE 过程名([参数1,参数2,,,]/*存储过程首部*/
AS <过程化SQL>  /*存储过程体,描述该存储过程的操作*/

存储过程包括过程首部和过程体,在过程首部,“过程名”是数据库服务器合法的对象标识;参数列表[参数1,参数2,]用名字来标识调用时给出的参数值,必须指定值的数据类型。
过程体是一个<过程化SQL块>,包括声明部分和可执行语句部分。
2)执行存储过程

CALL/PERFORM PROCEDURE 过程名([参数1,参数2,,,]

使用CALL或者PERFORM等方式激活存储过程的执行,在过程化SQL中,数据库服务器支持在过程体中调用其他存储过程。
3)修改存储过程

ALTER PROCEDURE 过程名1 RENAME TO 过程名2;(重新命名一个存储过程)
ALTER PROCEDURE 过程名 COMPILEL;(重新编译一个存储过程)

4)删除存储过程

DROP PROCEDURE 过程名()

2. 函数
函数必须指定返回的类型。

  1. 函数的定义语句格式
CREATE OR REPLACE FUNCTION 函数名([参数名1,参数名2...]) RETURNS<类型> AS <过程化SQL>

函数的执行语句格式

CALL/SELECT  函数名([参数名1,参数名2...])

修改函数
重命名一个自定义函数

ALTER FUNCTION 函数名1 RENAME TO 函数名2

重新编译一个函数

ALTER FUNCTION 函数名 COMPILE;

三、过程化SQL中的游标

和嵌入式SQL一样,在过程化SQL中如果SELECT语句只返回一条记录,可以将该结果存放到变量中。当查询返回多条记录时,就要使用游标对结果集进行处理。一个游标与一个SQL语句相关联。在存储过程中可以定义普通 游标、REFCURSOR类型游标、带参数的游标等。

存储过程和自定义函数用的比较多,因此对存储过程和函数要加深了解。

四. 存储过程和触发器的区别?

触发器与存储过程的主要区别在于触发器的运行方式。存储过程必须有用户、应用程序或者触发器来显示的调用并执行,而触发器是当特定时间出现的时候,自动执行或者激活的,与连接用数据库中的用户、或者应用程序无关。

五. 存储过程和函数的区别?

存储过程是用户定义的一系列SQL语句的集合,而函数通常是数据库已定义的方法,具体区别如下:

1.对于存储过程来说可以返回参数,而函数只能返回值或者表对象.

2.函数必须有返回值,存储过程可有可无

3.存储过程一般是作为一个独立的部分来执行,而函数可以作为查询语句的一部分来调用

六.触发器

在这里插入图片描述
1、什么是触发器
触发器是一个在修改指定表中的数据执行的存储过程。通常通过创建触发器来强制实现 不同表 中的逻辑相关数据的引用完整性或一致性。由于用户不能绕过触发器,所以用来 强制实施复杂的业务规则!以此确保数据的 完整性
2、为什么要使用触发器
(1)触发器自动执行,他们在表的数据做了任何修改,之后立即激活!(和事件差不多了)
(2)触发器可以通过数据库中的相关表进行层叠更改,这直接把代码写在客户端更加合理!
(3)触发器的限制可以引用到其它表中的列!
3、触发器如何保证数据的完整性
个人理解:比如我们做牛腩新闻系统的时候,如果我们删除了一条新闻,那么删除这条新闻的时候,它下面的新闻的评论也随之删除,此时涉及到两个表,一个是新闻表,一个是评论表!如果没有触发器的话,我们在程序中还要加上删除新闻评论表中的对应的内容!但是有时候程序员万一要是忘记设计删除新闻评论类,那么数据就不完整了!(新闻表中没有了此类新闻,但是评论表中却有此类新闻的评论!)
4、触发器的种类
我们之前设计的触发器好像都是DML的,但是还有DDL,那么二者之间有何区别呢!

DML触发器(修改表中的数据用)
DML(Data Manipulation Language)触发器是当数据库中发生数据操作语言事件要执行的操作。它通常包含三种:INSERT触发器,UPDATE触发器,DELETE触发器!当我们要对 数据库里的数据 进行操作的时候,我们要用到DML触发器!

DDL触发器(修改表)
DDL触发器是当数据库中发生数据定义语言(Data Definition Language)主要包括CREATE,ALTER,DROP等操作!当我们用在 定义或者改变表的结构,数据类型,表之间的连接和约束的时候,我们就用DDL触发器!

后记:
触发器保证了我们数据库数据的完整性,DDL是修改表的层次,DML是修改表中的数据层次!
创建DML触发器

接下来看看例题,首先先创建两张表

CREATE TABLE [dbo].[Stu]([ID] [int] IDENTITY(1,1) NOT NULL,--自增长ID[Name] [varchar](50) NOT NULL,--学生姓名[subject] [varchar](50) NOT NULL,--学科[credit] [decimal](18, 2) NOT NULL--单科学分)
GOCREATE TABLE [dbo].[Stu_sum]([Name] [varchar](50) NULL,--学生姓名[number] [int] NULL--总学分
) 
GO

现在有一张学生单科成绩表和一个成绩汇总表
INSERT触发器
要求插入一个学生单科成绩,并把分数汇总到Stu_sum 表中,根据学生的姓名(这里做测试没有做其他约束)

CREATE TRIGGER dbo.stu_TRIGGER_INSERTON dbo.StuAFTER  INSERT
AS 
BEGINSET NOCOUNT ON;--不返回影响行数--插入数据时会产生INSERTED表(表结构和Stu一样)--把[Stu_sum]存在的数据先更新掉update b set b.number=isnull(b.number,0)+a.credit from (select [Name],sum(credit) credit  from  INSERTED group by [Name]) ajoin [dbo].[Stu_sum] b on a.Name=b.Name--把不存在的添加进[Stu_sum]INSERT into [dbo].[Stu_sum](Name,number)select a.Name,a.creditfrom (select [Name],sum(credit) credit  from  INSERTED group by [Name]) aleft join [dbo].[Stu_sum] b on a.Name=b.Namewhere b.Name is null
END
GO

首先插入一条数据

insert into [dbo].[Stu]([Name],[subject],[credit]) values('张三','数学',100),('张三','英语',100)

查询结果,如下图Stu_Sum表中

select * from [Stu]
select * from [Stu_sum]

在这里插入图片描述
DELETE触发器
先插入几条值

insert into [dbo].[Stu]([Name],[subject],[credit]) values('张三','体育',60),('李四','英语',100),('李四','语文',80)

先查询一下表看一下表目前的值
在这里插入图片描述
目标删除张三的体育成绩,同时更新张三的总成绩。

DELETE触发器创建
CREATE TRIGGER dbo.stu_TRIGGER_DELETEON dbo.StuAFTER  DELETE
AS 
BEGINSET NOCOUNT ON;--不返回影响行数--删除数据时会产生DELETEED表(表结构和Stu一样)--把[Stu_sum]存在的数据更新掉update b set b.number=isnull(b.number,0)-a.credit from (select [Name],sum(credit) credit  from  DELETED group by [Name]) ajoin [dbo].[Stu_sum] b on a.Name=b.Name
END
GO

执行删除语句

delete from [dbo].[Stu] where Name='张三' and subject='体育'

在这里插入图片描述
UPDATE触发器
案例:需要把张三数学改成98分,同时修改张三总成绩

创建UPDATE触发器

CREATE TRIGGER dbo.stu_TRIGGER_UPDATEON dbo.StuAFTER  UPDATE
AS 
BEGINSET NOCOUNT ON;--不返回影响行数--更新数据时会产生INSERTED 、DELETEED表(表结构和Stu一样)--把[Stu_sum]存在的数据更新掉update b set b.number=isnull(b.number,0)+d.credit from (select Name,sum(credit) credit from(select a.[Name],b.credit-a.credit credit  from  DELETED a join INSERTED b on a.ID=b.ID) c group by [name]) djoin [dbo].[Stu_sum] b on d.Name=b.Name
END
GO

执行语句

update [dbo].[Stu] set [credit]=98 where [Name]='张三' and [subject]='数学'

在这里插入图片描述
替代触发器
与前面介绍了三种AFTER触发器不同,SQLServer 服务器在执行触发AFTER触发器的SQL代码后,先建立临时的INSERTED和DELETED表,然后执行SQL代码中对数据的操作,最后才激活触发器中的代码。而对于替代(INSTEAD OF)触发器,SQL SERVER服务器执行触发INSERTAD OF 触发器时,先建立临时的INSERTED和DELETED表,然后直接触发INSTEAD OF 触发器。

案例:当用户插入学生单科成绩大于100分时,直接提示报错。

创建触发器

 
CREATE TRIGGER dbo.stu_TRIGGER_INSTEADOFON dbo.StuINstead of  INSERT
AS 
BEGINif exists(select ID from inserted where credit>100)beginselect '插入成绩错误' as 错误原因end
END
GO

执行插入语句

insert into [dbo].[Stu]([Name],[subject],[credit]) values('张三','体育',130)

执行结果,错误的成绩没有被插入。
在这里插入图片描述

在这里插入图片描述


http://chatgpt.dhexx.cn/article/sIYCPfd7.shtml

相关文章

Java的数据库编程:JDBC

目录 一、JDBC是什么&#xff1f; 二、使用步骤 1.首先将JDBC的包引进java中 2.创建新的类来写代码 3.描述你的服务器 4.设置你的数据库地址,数据库用户名,数据库密码 5.连接数据库 6.书写你所要执行的SQL语句 7.把字符串风格的sql转化成一个对象 8.执行语句 9.回收资…

Python数据库编程

操作SQLite3数据库 从Python3.x版本开始&#xff0c;在标准库中已经内置了SQLlite3模块&#xff0c;它可以支持SQLite3数据库的访问和相关的数据库操作。在需要操作SQLite3数据库数据时&#xff0c;只须在程序中导入SQLite3模块即可。Python语言操作SQLite3数据库的基本流程如…

实验7 数据库编程

第1关 定义一个名为PROC_COUNT的无参数存储过程 任务描述 定义一个名为PROC_COUNT的无参数存储过程&#xff0c;查询工程名称中含有“厂”字的工程数量&#xff0c;并调用该存储过程。 相关知识 1、工程项目表J由工程项目代码(JNO)、工程项目名(JNAME)、工程项目所在城市(CITY)…

C++数据库编程简介

C数据库编程简介 C数据库编程 ODBC简介 C数据库编程 ODBC连接SQL Server数据库 C数据库编程 ODBC插入数据 C数据库编程 ODBC查询数据 C数据库编程 ODBC删除数据 C数据库编程 ODBC修改数据 C数据库编程 ODBC连接MySQL增删改查数据 C数据库编程 MySQL Connecttor C简介 …

游戏设计模式——面向数据编程(转)

作者&#xff1a;KillerAery 出处&#xff1a;http://www.cnblogs.com/KillerAery/ 随着软件需求的日益复杂发展&#xff0c;远古时期面的向过程编程思想才渐渐萌生了面向对象编程思想。 当人们发现面向对象在应对高层软件的种种好处时&#xff0c;越来越沉醉于面向对象&…

数据科学必备Python编程基础

前言 对于Python复杂的编程语言中提取了数据分析常用的数据处理以及数据可视化等数据分析师常用的内容&#xff0c;区别与其他的Python编程教程&#xff0c;如果是纯开发的小伙伴&#xff0c;看完本系列的文章仅仅只能掌握数据相关处理的内容&#xff0c;并不能完全掌握开发方…

数据结构中的C语言编程基础

​ 在学习数据结构时&#xff0c;需要我们编写许多的程序&#xff0c;对于一些变量的定义、结构体的声明、指针的使用&#xff0c;需要有一个统一的标准&#xff0c;这样才能方便我们使用、并简化记忆难度。 ​ 本文结合自身的编程经验和高分笔记中对考研数据结构编程的一些建…

面向数据编程 Data-Oriented Programming [1]

RuntimeMapMaker3D-Pro 面向数据的编程原则 0.1 简介 面向数据的编程是一种编程范式&#xff0c;旨在简化以信息为中心的软件系统的设计和实施。而不是围绕着将数据和代码结合在一起的实体&#xff08;如实例化的对象&#xff09;来设计信息系统&#xff08;例如&#xff0c;从…

ODBC API开发教程

ODBC API开发教程 作者&#xff1a;闻怡洋 未得到作者允许请勿转载 http://wyy.vchelp.net/ 目录 第 1 章 介绍... 2 第 2 章 ODBC API访问数据库... 2 2.1 ODBC简要介绍... 2 2.1.1 在没有ODBC以前... 2 2.1.2 ODBC介绍... 3 2.1.3 ODBC结构…

Microsoft Server 2008 空间存储 应用方法详解

2019独角兽企业重金招聘Python工程师标准>>> 刚接触2008的空间存储&#xff0c;资料比较少&#xff0c;在数据库操作中有很多不懂的地方&#xff0c;包括用法&#xff0c;语法等&#xff0c;经过同事的指点明白了一些&#xff0c;感谢大腿同事~这里只记录数据库操作…

ODBC 数据类型和API(VC)

目录 ODBC 数据类型API 函数 ODBC 数据类型 ODBC SQL 数据类型 展开显示 ODBC SQL 数据类型SQL类型标识SQL 92类型标识类型描述SQL_CHARCHAR(n)定长字符串,其长度为nSQL_VARCHARVARCHAR(n)变长字符串,最大长度为nSQL_LONGVARCHARLONG VARCHAR变长字符串,最大长度取决于数据源S…

Sql的decimal、float、double类型的区别

三者的区别介绍 float:浮点型&#xff0c;含字节数为4&#xff0c;32bit&#xff0c;数值范围为-3.4E38~3.4E38&#xff08;7个有效位&#xff09; double:双精度实型&#xff0c;含字节数为8&#xff0c;64bit数值范围-1.7E308~1.7E308&#xff08;15个有效位&#xff09; d…

【网络编程实践】2.3.4.2 建议关闭 Nagle 算法

Nagle算法主要是避免发送小的数据包&#xff0c;要求TCP连接上最多只能有一个未被确认的小分组&#xff0c;在该分组的确认到达之前不能发送其他的小分组。 Nagle算法的目的&#xff1a;避免发送大量的小包&#xff0c;网络上每次只能一个小包存在&#xff0c;在小包被确认之前…

Nagle算法与TCP_CORK,TCP_NODELAY,TCP_QUICKACK

1. Nagel算法 TCP/IP协议中&#xff0c;无论发送多少数据&#xff0c;总是要在数据前面加上协议头&#xff0c;同时&#xff0c;对方接收到数据&#xff0c;也需要发送ACK表示确认。为了尽可能的利用网络带宽&#xff0c;TCP总是希望尽可能的发送足够大的数据。&#xff08;一…

如何关闭和启用Nagle算法

如果各位读者在搜索如何关闭的话&#xff0c;那么我有理由相信各位对想要解决的问题已经算是比较清楚了&#xff0c;废话不多数。 什么是nagle算法&#xff0c;它是干嘛用的&#xff0c;请自行google or 百度 Step1 Open regredit 快捷键&#xff1a;winr 打开&#xff1a…

19- TCP 协议(Nagle)

前面我们所用的 unp/protocol/tools/winclient/echo_cli.cpp 程序的特别之处是它总会发送一个小分组&#xff08;TCP 段&#xff0c;只有 41 字节&#xff09;到服务器。这样的小分组在英文中称为 tinygram&#xff0c;在网络状态好的情况下&#xff0c;比如局域网中&#xff0…

TCP Nagle算法详解

转: http://bbs.chinaunix.net/thread-3767363-1-1.html 在网络拥塞控制领域&#xff0c;我们知道有一个非常有名的算法叫做Nagle算法&#xff08;Nagle algorithm&#xff09;&#xff0c;这是使用它的发明人John Nagle的名字来命名的&#xff0c;John Nagle在1984年首次用这个…

TCP之延时Nagle算法实验详解

TCP/IP协议中&#xff0c;无论发送多少数据&#xff0c;总是要在数据前面加上协议头&#xff0c;同时&#xff0c;对方接收到数据&#xff0c;也需要发送ACK表示确认。为了尽可能的利用网络带宽&#xff0c;TCP总是希望尽可能的发送足够大的数据。&#xff08;一个连接会设置MS…

Nagle Algorithm

转: http://bbs.chinaunix.NET/thread-3767363-1-1.html 在网络拥塞控制领域&#xff0c;我们知道有一个非常有名的算法叫做Nagle算法&#xff08;Nagle algorithm&#xff09;&#xff0c;这是使用它的发明人John Nagle的名字来命名的&#xff0c;John Nagle在1984年首次用这…

TCP中的Nagle算法

TCP中的Nagle算法 一. Nagel算法 TCP/IP协议中,无论发送多少数据,总是要在数据前面加上协议头,同时,对方接收到数据,也需要发送ACK表示确认.为了尽可能的利用网络带宽,TCP总是希望尽可能的发送足够大的数据.(在一个连接中会设置MSS参数,因此,TCP/IP希望每次都能够以MSS尺寸的数…