DM8开发技能
基础学习笔记005
文章目录
- DM8开发技能
- 1、DMSQL程序设计
- 1.1 概念
- 1.2 数据类型
- 1.3 程序定义
- 1.3.1 存储过程
- 1.3.2 存储函数
- 1.3.3 客户端DMSQL程序
- 1.3.4 参数
- 1.3.5 控制结构
- (1)顺序结构
- (2)分支结构
- (3)循环结构
- 1.3.6 调用语句
- 1.4 对象及其操作
- 1.4.1 包
- 1.4.5类类型
- 1.4.6 触发器
- 1.4.7 游标
- 2、开发实战
- 2.1 JDBC
- 2.1.1 提前准备
- 2.2 代码
- 2.2 ODBC
- 2.2.1 配置数据源
- 2.2.2 测试代码
1、DMSQL程序设计
1.1 概念
DMSQL是一种过程性语言,其DMSQL程序分为两种:存储模块和客户端DMSQL程序
存储模块:一般是存储过程和存储函数的统称
存储过程和存储函数:是用户使用 DMSQL 程序语言创建的过程或函数
1.2 数据类型
数组类型:静态数组、动态数组
集合类型:VARRAY类(可伸缩性数组)、索引表类、嵌套表类
类类型:支持封装成类
游标类型:用于定义游标变量。对游标变量进行赋值时必须是同类型的对象即游标对象
//语法
CURSOR|SYS_REFCURSOR
//例子 用 CURSOR 定义游标变量 c2
DECLARE
CURSOR c1 IS SELECT TITLE FROM RESOURCES.EMPLOYEE WHERE MANAGERID = 3;
c2 CURSOR;
BEGIN
c2 =c1;
open c2;
close c2;
END;
操作符:算术操作符、关系操作符、比较操作符、逻辑操作符
1.3 程序定义
1.3.1 存储过程
CREATE [OR REPLACE ] PROCEDURE<过程声明><AS_OR_IS><模块体>
//OR REPLACE 选项的作用是当同名的存储过程存在时,首先将其删除,再创建新的存储过程。
存储过程没有返回值,调用者只能通过访问 OUT 或 IN OUT 参数来获得执行结果
参数模式: 参数模式可设置为 IN、 OUT 或 IN OUT(OUT IN),缺省为 IN 类型
--例子
CREATE OR REPLACE PROCEDURE DMHR.PROC_1(a IN OUT INT) AS
b INT:=10;
BEGIN
a := a+b;
PRINT a;
EXCEPTION
WHEN OTHERS THEN NULL;
END;
/
1.3.2 存储函数
CREATE [OR REPLACE ] FUNCTION <函数声明><AS_OR_IS><模块体>
存储函数是有返回值
--例1
CREATE OR REPLACE FUNCTION DMHR.fun_1(a INT,b INT) RETURN INT AS
s INT;
BEGIN
s:=a+b;
RETURN s;
EXCEPTION
WHEN OTHERS THEN NULL;
END;
/
SELECT DMHR.FUN_1(1,3);
--例2计算函数
--FOR CALCULATE 指定存储函数为计算函数
CREATE OR REPLACE FUNCTION DMHR.F1 FOR CALCULATE
RETURN INT
IS
BEGIN
RETURN 1;
END;
/
--在表 T 中使用
CREATE TABLE DMHR.T(C1 INT, C2 INT DEFAULT DMHR.F1());
--或者
CREATE TABLE DMHR.T(C1 INT, C2 INT DEFAULT DMHR.F1);
1.3.3 客户端DMSQL程序
客户端DMSQL程序的声明部分必须包含DECLARE。
创建立即执行,执行之后立即释放
1.3.4 参数
参数模式:
IN:输入参数,用来将数据传送给模块;
IN OUT:输出参数,用来从模块返回数据到进行调用的模块;
IN OUT:既作为输入参数,也作为输出参数。
1.3.5 控制结构
(1)顺序结构
(2)分支结构
IF语句、CASE语句、WHICH语句
1> IF语句
语法1:
IF 条件 THEN
代码
END IF;
语法2:
IF 条件 THEN
代码 1
ELSE
代码 2
END IF;
语法3:
IF 条件 1 THEN
代码 1
ELSEIF 条件 2 THEN
代码 2
…
ELSE
代码 N
END IF;
2> CASE语句
语法1:简单形式:将一个表达式与多个值进行比较
这种形式的 CASE 语句会选择第一个满足条件的对应的执行部分来执行,剩下的则不会计算
CASE <条件表达式>
WHEN <条件> THEN <执行部分>;
{WHEN <条件> THEN <执行部分>;}
[ ELSE <执行部分> ]
END [CASE];
--例 定义一个存储过程
CREATE OR REPLACE PROCEDURE PROC_CASE(GRADE CHAR(10)) AS
DECLARE
appraisal VARCHAR2(20);
BEGIN
appraisal :=
CASE GRADE
WHEN NULL THEN 'IS NULL'
WHEN 'A' THEN 'Excellent'
WHEN 'B' THEN 'Good'
WHEN 'C' THEN 'Fair'
ELSE 'No such grade'
END;
DBMS_OUTPUT.PUT_LINE ('Grade ' ||grade|| ' is ' ||appraisal);
END;
/
语法2:搜索形式:对多个条件进行计算,取第一个结果为真的条件
这种形式:CASE 语句依次执行各条件表达式,当遇见第一个为真的条件时,执行其对应的执行部分,在第一个为真的条件后面的所有条件都不会再执行
--例
CREATE OR REPLACE PROCEDURE PROC_CASE(GRADE CHAR(10)) AS
DECLARE
appraisal VARCHAR2(20);
BEGIN
appraisal :=
CASE
WHEN grade IS NULL THEN 'IS NULL'
WHEN grade = 'A' THEN 'Excellent'
WHEN grade = 'B' THEN 'Good'
WHEN grade = 'C' THEN 'Fair'
ELSE 'No such grade'
END;
DBMS_OUTPUT.PUT_LINE ('Grade ' ||grade|| ' is ' ||appraisal);
END;
/
3> WHICH 语句
语法和C语言同
SWITCH (<条件表达式>)
{
CASE <常量表达式> : <执行部分>; BREAK;
{ CASE <常量表达式> : <执行部分>; BREAK;}
[DEFAULT : <执行部分>; ]
}
(3)循环结构
DMSQL支持的循环语句:LOOP 语句、 WHILE 语句、 FOR 语句、REPEAT 语句和 FORALL 语句。
1> LOOP语句
LOOP
<执行部分>;
END LOOP [标号名];
2> WHILE语句
WHILE <条件表达式> LOOP
<执行部分>;
END LOOP [标号名];
3> FOR语句
FOR <循环计数器> IN [REVERSE] <下限表达式> .. <上限表达式> LOOP
<执行部分>;
END LOOP [标号名];
CREATE OR REPLACE PROCEDURE PROC_FOR1 (a IN OUT INT) AS
BEGIN
FOR I IN REVERSE 1 .. a LOOP
PRINT I;
a:=I-1;
END LOOP;
END;
/
CALL PROC_FOR1(5);
4> REPEAT语句
(好像是C语言中do…while)
REPEAT
<执行部分>;
UNTIL <条件表达式>;
5> FORALL 语句
6> EXIT
7> COUNTINUE
1.3.6 调用语句
[CALL] [<模式名>.]<存储模块名>[@dblink_name] [(<参数>{, <参数>})];
1.4 对象及其操作
包、类、触发器、游标、函数、存储过程
1.4.1 包
使用包可以创建应用程序和管理存储过程和函数
使用语法
--创建包
CREATE [OR REPLACE] PACKAGE BODY [<模式名>.]<包名> [WITH ENCRYPTION] AS|IS <包体部分> END [包名]
--重编译包 重编功能主要用于检验包的正确性。
ALTER PACKAGE [<模式名>.]<包名> COMPILE [DEBUG];
/*
包删除
包对象的删除分为包规范的删除和包主体的删除。
*/
--删除包规范
DROP PACKAGE [IF EXISTS] [<模式名>.]<包名>;
--删除包主体
DROP PACKAGE BODY [IF EXISTS] [<模式名>.]<包名>;
--例1
CREATE TABLE Person(Id INT IDENTITY, Name VARCHAR(100), City VARCHAR(100));
INSERT INTO Person(Name, City) VALUES('Tom','武汉');
INSERT INTO Person(Name, City) VALUES('Jack','北京');
INSERT INTO Person(Name, City) VALUES('Mary','上海');
SELECT * FROM Person;
--创建包规范
CREATE OR REPLACE PACKAGE PersonPackage AS
E_NoPerson EXCEPTION; --异常定义
PersonCount INT; --变量定义
Pcur CURSOR; --游标定义
PROCEDURE AddPerson(Pname VARCHAR(100), Pcity varchar(100)); --过程定义
PROCEDURE RemovePerson(Pname VARCHAR(100), Pcity varchar(100));
PROCEDURE RemovePerson(Pid INT);
FUNCTION GetPersonCount RETURN INT; --函数定义
PROCEDURE PersonList;
END PersonPackage;
--创建包主体
CREATE OR REPLACE PACKAGE BODY PersonPackage AS
PROCEDURE AddPerson(Pname VARCHAR(100), Pcity varchar(100) )AS
BEGIN
INSERT INTO Person(Name, City) VALUES(Pname, Pcity);
PersonCount = PersonCount + SQL%ROWCOUNT;
END AddPerson;
PROCEDURE RemovePerson(Pname VARCHAR(100), Pcity varchar(100)) AS
BEGIN
DELETE FROM Person WHERE NAME LIKE Pname AND City like Pcity;
PersonCount = PersonCount - SQL%ROWCOUNT;
END RemovePerson;
PROCEDURE RemovePerson(Pid INT) AS
BEGIN
DELETE FROM Person WHERE Id = Pid;
PersonCount = PersonCount - SQL%ROWCOUNT;
END RemovePerson;
FUNCTION GetPersonCount RETURN INT AS
BEGIN
RETURN PersonCount;
END GetPersonCount;
PROCEDURE PersonList AS
DECLARE
V_id INT;
V_name VARCHAR(100);
V_city VARCHAR(100);
BEGIN
IF PersonCount = 0 THEN
RAISE E_NoPerson;
END IF;
OPEN Pcur FOR SELECT Id, Name, City FROM Person;
LOOP
FETCH Pcur INTO V_id,V_name,V_city;
EXIT WHEN Pcur%NOTFOUND;
PRINT ('No.' || (cast (V_id as varchar(100))) || ' ' || V_name || '来自' || V_city );
END LOOP;
CLOSE Pcur;
END PersonList;
BEGIN
SELECT COUNT(*) INTO PersonCount FROM Person;
END PersonPackage;
--重新编译包
ALTER PACKAGE PersonPackage COMPILE;
--调用包中的 AddPerson 过程,往数据表中增加一条记录:
CALL PersonPackage. AddPerson ('BLACK', '南京') ;
CALL PersonPackage.REMOVEPERSON(4);--调用包中删除函数
CALL PersonPackage. RemovePerson ('JACK', '北京') ;
--调用包中的变量
SELECT PersonPackage. PersonCount;
SELECT PersonPackage. GetPersonCount;
--调用包中的过程 PersonList 查看表中的所有记录
CALL PersonPackage. PersonList;
SELECT * FROM Person;
1.4.5类类型
分为普通类和Java类
1.4.6 触发器
触发器的使用语法
--基表上创建触发器
CREATE [OR REPLACE] TRIGGER [<模式名>.]<触发器名> [WITH ENCRYPTION]
CREATE OR REPLACE TRIGGER TRG_UPD
AFTER UPDATE OF NAME,CITY ON PERSION1
BEGIN
PRINT 'UPDATE OPERATION ON COLUMNS NAME OR CITY OF PERSION1';
END;
1.4.7 游标
引入原因:使用查询语句将查询结果存放到变量中进行处理的方法 要么返回一条记录,要么返回很多条记录
游标:允许程序对多行数据(结果集)进行逐条处理
类别:
-
静态游标
-
显式游标
-
隐式游标
-
-
动态游标
显式游标使用步骤:定义、打开、拨动、关闭
--隐式游标
BEGIN
UPDATE DMHR.EMPLOYEE SET PHONE_NUM=1531248552 WHERE DMHR.EMPLOYEE.EMPLOYEE_NAME='马学铭';
IF SQL%NOTFOUND THEN
PRINT '此人不存在';
ELSE
PRINT '已修改';
END IF;
END;
2、开发实战
2.1 JDBC
2.1.1 提前准备
(1)在IDEA中安装maven——便于项目构建
(2)导入DM8JDBC驱动包
(3)新建一个JDBC连接类,测试连接是否成功
(4)若是需要在IDEA中操作数据库:
① 在IDEA中的数据库中新建DM8的数据源并导入驱动,
② 新建好之后进入DM8数据库,输入用户密码和URL测试连接,即可在IDEA中操作数据库
2.2 代码
JDBC连接类:
package org.example.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class JDBC_CONN {
static Connection con = null;
static String cname = "dm.jdbc.driver.DmDriver";
static String url = "jdbc:dm://localhost:5237";
static String userid = "SYSDBA";
static String pwd = "SYSDBA";
public static void main(String[] args) {
try {
Class.forName(cname);
con = DriverManager.getConnection(url, userid, pwd);
con.setAutoCommit(true);
System.out.println("[SUCCESS]conn database");
} catch (Exception e) {
System.out.println("[FAIL]conn database:" + e.getMessage());
}
}
public void disConn(Connection con) throws SQLException {
if (con != null) {
con.close();
}
}
}
简单测试操作数据库:
package org.example.test;
import java.sql.*;
public class test1 {
static Connection con = null;
static String cname = "dm.jdbc.driver.DmDriver";
static String url = "jdbc:dm://localhost:5237";
static String userid = "SYSDBA";
static String pwd = "SYSDBA";
static Statement state = null;
static ResultSet rs = null;
public static void main(String[] args) throws ClassNotFoundException, SQLException {
try {
//连接JDBC驱动程序
System.out.println("Loading JDBC Driver...");
Class.forName(cname);
System.out.println("加载成功");
//连接DM数据库
System.out.println("Connecting to DM Server..");
con = DriverManager.getConnection(url,userid,pwd);
//通过连接对象创建java.sql.Statement对象
state = con.createStatement();
System.out.println("连接成功");
System.out.println("-----------------------");
//定义插入SQL语句
String sql_insert1 = "insert into SYSDBA.T1(name,age)values('带土',10)";
state.execute(sql_insert1);
System.out.println("插入成功");
//定义删除SQL语句
String sql_del = "delete from SYSDBA.T1 where age = 12";
boolean b = state.execute(sql_del);
System.out.println("删除成功");
//修改
String sql_update = "update SYSDBA.T1 set"+" name = '神秘面具男' where name = '带土';";
state.executeUpdate(sql_update);
System.out.println("更新成功");
//定义查询 SQL
String sql_selectAll = "select * from SYSDBA.T1";
//执行查询的 SQL 语句
rs = state.executeQuery(sql_selectAll);
}catch (ClassNotFoundException e){
e.printStackTrace();
}catch (SQLException e){
e.printStackTrace();
}finally {
try {
rs.close();
state.close();
con.close();
}catch (SQLException e){
e.printStackTrace();
}
}
}
}
2.2 ODBC
2.2.1 配置数据源
2.2.2 测试代码
DM8达梦数据库ODBC 接口 - 墨天轮 (modb.pro)