数据库:数据库编程
sql编程
为什么要使用sql编程?
标准的sql是非过程化的查询语言
特点:操作简单、面向集合、功能丰富、使用简单等
缺点:缺少流程控制能力,难以实现应用业务中的逻辑控制
办法:使用sql编程,可以提高应用系统和数据库管理系统间的互操作性
使用sql编程来访问和管理数据库中的数据的方式有:
嵌入式sql【ESQL】、过程化sql(PL/SQL)、存储过程和函数、开放数据库互联【ODBC】、java数据库连接【JDBC】等
嵌入式sql
sql的特点之一:
在交互式和嵌入式两种不同的使用方式下,sql的语法结构基本是一致的
嵌入式sql:就是将sql语句嵌入到程序设计语言中,例如:C、C++、java等成为宿主语言,简称主语言【SQL语句负责操作数据库,高级语言负责控制逻辑流程】
将sql嵌入其他语言中,必须解决三个问题:
ESQL的处理过程
面对ESQL,DBMS采用预编译方法处理:
1、由DBMS的预处理程序,识别出ESQL语句
2、将之转换成主语言调用语句,使主语言编译程序能识别他们
3、然后由主语言的编译程序将纯的主语言程序编译成目标代码
在ESQL中,为了快速区分sql语句和主语言语句,所有sql语句必须加前缀:
若主语言是C,则前缀是EXEC SQL
若主语言是Java,则ESQL 成为SQLJ
一般形式:SQL< SQL语句 >
ESQL与主语言之间的通信
SQL语句负责操作数据库,高级语言负责控制逻辑流程,这时,程序中会有两种不同计算模型的语句,它们之间会如何通信?
数据库工作单元和源程序工作单元之间的通信:
1、向主语言传递sql语句的执行状态信息,使主语言能够根据此信息控制程序流程,主要用于SQL通信区实现
2、主语句向SQL语句提供参数,主要用于主变量实现
3、将SQL语句查询数据库的结果交予主语言处理,主要用于主变量和游标实现
SQl通信区
向主语言传递sql语句的执行状态信息,使主语言能够根据此信息控制程序流程
主变量
主语言向sql语句提供参数
将sql语句查询数据库的结果交主语言进一步处理
游标
解决集合型操作语言与过程性操作语言的不匹配
过程化SQL
过程化sql是对sql的扩展,使其增加了过程化语句功能
块
过程化sql程序的基本结构是块,所有的过程化sql程序都是由块组成,这些块之间可以相互嵌套,每个块完成一个逻辑操作。
块的基本结构:
变量和常量的定义:
1、变量定义
变量名 数据类型 [[NOT NULL] :=初值表达式]
或者
变量名 数据类型 [[NOT NULL] 初值表达式]
2、常量定义
常量名 数据类型 CONSTANT:=常量表达式
常量必须要给一个值,并且该值在存在期间或常量的作用域内不能改变。如果试图修改它,过程化SQL将返回一个异常。
3、赋值语句
变量名 :=表达式
流程控制
过程化SQL提供了流程控制语句,主要有条件控制语句和循环控制语句。这些语句的语法、定义和一般的高级语言类似。
1. 条件控制语句
IF语句
IF condition THEN Sequence_of_statements; /*条件为真时语句序列才被执行*/ END IF /*条件为假或NULL时什么也不做,控制转移至下一个语句*/
IF-THEN语句
IF condition THEN Sequence_of_statements1; /*条件为真时语句序列才被执行*/ ELSE Sequence_of_statements2; /*条件为假或NULL时才被执行*/ END IF
嵌套的IF语句
在THEN和ELSE子句中还可以包含IF语句,IF语句可以嵌套。
2. 循环控制语句
最简单的循环语句LOOP
LOOP Sequence_of_statements; /*循环体,一组过程化SQL语句*/ END LOOP;
多数数据库服务器的过程化SQL都提供EXIT、BREAK或LEAVE等循环结束语句以保证LOOP语句块能够在适当的条件下提前结束。
WHERE-LOOP循环语句
WHERE condition LOOP Sequence_of_statements; /*条件为真时执行循环体内的语句序列*/ END LOOP;
每次执行循环体语句之前首先对条件进行求值,如果条件为真则执行循环体内的语句序列,如果条件为假则跳过循环并把控制传递给下一个语句。
FOR-LOOP
FOR count IN [REVERSE] bound1...bound2 LOOP Sequence_of_statements; END LOOP;
FOR循环的基本执行过程:
将count设置为循环的下界bound1,检查它是否小于上界bound2。当指定REVERSE时则将count设置为循环的上界bound2,检查count是否大于下界bound1。如果越界则执行跳出循环,否则执行循环体,然后按照步长(+1或-1)更新count的值,重新判断条件。
3、错误处理
如果过程化SQL在执行时出现异常,则应该让程序在产生异常的语句处停下来,根据异常的类型去执行异常处理语句。
SQL标准对数据库服务器提供什么样的异常处理作出了建议,要求过程化SQL管理器提供完善的一次处理机制。
存储过程和函数
过程化SQL块主要有命名块和匿名块。匿名块每次执行时都要进行编译,它不能被存储到数据库中,也不能在其他过程化SQL块中调用。
过程和函数是命名块,他们被编译后保存在数据库中,称为持久性存储模块(PSM),可以 被反复调用,运行速度较快。
存储过程
存储过程是由过程化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 过程名();
函数
函数必须指定返回的类型。.
1. 函数的定义语句格式
CREATE OR REPLACE FUNCTION 函数名([参数名1,参数名2,...]) RETURNS<类型> AS <过程化SQL块>
2、函数的执行语句格式
CALL/SELECT 函数名([参数名1,参数名2,...])
3、修改函数 -- 重命名一个自定义函数
ALTER FUNCTION 函数名1 RENAME TO 函数名2
4、重新编译一个函数
ALTER FUNCTION 函数名 COMPILE;