达梦数据库语法知识

语法知识和案例

                                             目录

  1. 前言
  2. 一、select查询
  3. 二、DM程序设计基础
  4.      1.变量声明及初始化
  5.      2.变量的赋值
  6.      3.变量类型
  7.          3.1标量
  8.          3.2 大数据类型
  9.          3.3 %TYPE 类型
  10.          3.4 %ROWTYPE 
  11.          3.5 动态数组
  12. 三、案例 
  13.      1.数据库查询与操作 
  14.      2.DM SQL程序设计基础
  15. 总结


前言

主要涵盖了数据库查询和DM(Data Migration)程序设计基础的相关内容,以下是对各部分的总结:


一、select查询

select 查询项 from 表格
where 条件表达式
group by 分组字段 having 统计结果的条件表达式
order by 排序字段 desc/asc
limit 偏移量 ,记录数;

--设置当前模式为达梦

set schema dmhr;

例1.查询employee表中,工资在2000到5000之间的员工信息

select * from employee where salary between 2000 and 5000;

例2:查询部门编号(department)为101,102,103的员工信息

select * from employee where department_id in(101,102,103);

例3:查询employee表中姓名中姓黄的员工信息
'_':任意单个字符
'%':任意多个字符

select * from employee where employee_name  like '黄%';

例4.查询各部门的人数,人数排名前5,显示部门名称,人数。

select department_name as 部门名称 ,count(*) as 人数
from department 
group by department_name
order by count(*) desc
limit 5;

例5.查询employee各工作岗位的人数,人数排名前6-10的记录,显示中文工作编号,人数.

select job_id 工作编号,count(*) 人数
from  employee 
group by job_id
order by count(*) desc
limit 5,5;
hav

select

from 表1 join 表2

on 表2.公共字段=表1.公共字段

--非公共字段前面的表名可以省略不写,但是公共字段必须写

例6:查询员工的姓名(employee_name)、员工电话号码(phone_num)、员工的部门名称(department_name)、员工的地址编号(location_id)

select employee_name,phone_num,department_name,location_id,a.department_id
from employee a
join department b
on b.department_id=a.department_id;

例7:查询所有街道所在城市名称,显示街道名称,城市名称

select street_address,city_name from city a inner join location b on b.city_id=a.city_id;

--连接成一张大表

select

from

inner join location 表2 on 表2.公共字段=表1.公共字段

group by

order by

limit

练习8-1:查询街道“江宁开发区迎翠路7号”所在城市

select street_address,city_name 
from city a 
inner join location b on b.city_id=a.city_id

练习8-2:查询所有街道所在城市名称,显示街道名称,城市名称,按照city_name 排序 desc 前面5条记录

select street_address,city_name 
from city a inner join location b on b.city_id = a.city_id
order by city_name desc
limit 5;

例9:查询员工编号(employee_id)、姓名(employee_name)、电子邮箱(email),所属部门(department_name),职务(job_title)、办公城市(city_name)。

员工编号(employee_id)、姓名(employee_name)、电子邮箱(email)  = >来自于employee

所属部门(department_name)                     =>               来自于department

职务(job_title)                             =>                     来自于job

办公城市(city_name)                      =>                        来自于city

select a.employee_id,employee_name,email,department_name,job_title,city_name
from employee a inner join job b on b.job_id=a.job_id
inner join department c on c.department_id=a.department_id
inner join location d on d.location_id=c.location_id
inner join city e on e.city_id=d.city_id;

例10:部门名称为“行政部”且所在城市为“武汉”的员工的员工编号(employee_id)、姓名(employee_name)、电子邮箱(email),所属部门(department_name),职务(job_title)、办公城市(city_name)。

select a.employee_id,employee_name,email,department_name,job_title,city_name
from employee a inner join job b on b.job_id=a.job_id
inner join department c on c.department_id=a.department_id
inner join location d on d.location_id=c.location_id
inner join city e on e.city_id=d.city_id
where department_name='行政部' and city_name='武汉';

例13:查询街道“江宁开发区迎翠路7号”所在城市
第一步查询街道的city_id

elect city_id from location where street_address='江宁开发区迎翠路7号';--nj

第二步根据city_id查询相应的城市名称

select city_name from city where city_id=(select city_id from location where street_address='江宁开发区迎翠路7号');

二、DM程序设计基础

1.变量声明及初始化

标识符[constant] 数据类型 [not null][:= | default 表达式];

代码如下(示例):

DECLARE
   v_name varchar(40) not null:='马学铭';
BEGIN
   SELECT * FROM dmhr.employee WHERE employee_name=v_name;
END;

练习1:定义一个变量dep_id,初始值为‘104’,请查询department_id=dep_id的所有员工记录
 

DECLARE
   dep_id int not null:='104';
BEGIN
   SELECT * FROM dmhr.department WHERE department_id=dep_id;
END;

2.变量的赋值

variable :=expression
或者 set variable :=expression

操作符:    + - * / <  >  <> :=赋值符号    IS NULL LIKE BETWEEN IN    AND OR NOT

3.变量类型

3.1标量

数字型:INT, INTEGER, BIGINT, SMALLINT, BYTE, NUMERIC, BIT, FLOAT, DOUBLE, DECIMAL, NUMERIC

字符型:CHAR, VARCHAR

日期时间型:DATE, TIME, TIMESTAMP

布尔型:BOOL, BOOLEAN

3.2 大数据类型

BLOB, CLOB, TEXT, IMAGE, LONGVARBINARY, LONGVARCHAR, BFILE

3.3 %TYPE 类型

表名 %type
在程序中,变量可以被用来处理存储在数据库表中的数据。在这种情况下,变量应该拥有与表列相同的类型

练习2:请定义一个变量v_phone 与employee表中phone_num字段的数据类型保持一致。

DECLARE
   v_phone dmhr.employee.phone_num %type;
   v_email dmhr employee.email %type;

3.4 %ROWTYPE

将返回一个基于表定义的复合类型,它将一个记录声明为具有相同结构的数据表的一行。与%type类似,如果表结构定义发生变化了,那么%ROWTYPE类型也发生变化。

代码如下(示例):

set schema dmhr;
DECLARE 
    emp_record employee %ROWTYPE;
    BEGIN
        select * into emp_record from dmhr.employee where employee_id='1003';
        print emp_record.employee_id;
        print emp_record.identity_card;
        print emp_record.phone_num;
        print emp_record.email;
        print emp_record.hire_date;
   END;

    练习3:定义一个变量job_record,将job_id=21的job记录显示出来,请输出

job_title.min_salary.max_salary
set job_title.min_salary.max_salary from dmhr.job where job_id=21;
DECLARE 
    job_record dmhr.job %ROWTYPE;
    BEGIN
        select * into job_record from dmhr.job where job_id=21;
        print job_record.job_title;
        print job_record.min_salary;
        print job_record.max_salary;   
   END;

3.5 动态数组

动态数组语法格式:
TYPE 数组名 IS ARRAY 数据类型[,...]
为多维动态数组分配空间的语法如下:
数组名 := NEW 数据类型[常量表达式1, 常量表达式2,...]

例5:动态数组举例

DECLARE
        TYPE array_type IS ARRAY INT[]; -- 定义数组类型
        a array_type;-- 用自己定义的数组类型声明数组
   BEGIN
        a:=NEW INT[8]; --动态分配空间
        FOR i IN 1..8 LOOP
            a[i]:=i*10;
           print a[i];
        END LOOP;
   END;

例6:多维动态数组举例

DECLARE
        TYPE array_type IS ARRAY INT[,]; -- 定义数组类型
        a array_type;-- 用自己定义的数组类型声明数组
   BEGIN
        a:=NEW INT[3,4]; --动态分配空间
        FOR i IN 1..3 LOOP
          FOR J IN 1..4 LOOP
            a[i][j]:=i+j;
           print a[i][j];
        END LOOP;
   END;

三、案例

数据库的E-R图如下:

1.数据库查询与操作

set schema dmhr;

练习1:在DMHR模式下,查询工资为8000~12000元的员工信息。

select * from employee where salary between 8000 and 12000;

参考截图:

2.在DMHR模式下,查询姓名为两个汉字且姓“周”的员工的姓名、职务、工资及提高20%后的工资,并用中文显示列名。 

select a.employee_name as 姓名,b.job_title as 职务,a.salary as 工资,a.salary * 1.2 as 提高后的工资 
from  employee a
join  job b
on  b.job_id=a.job_id
where a.employee_name like '周_';

参考截图:

3.在DMHR模式下,查询2012年以后入职的员工信息,要求显示员工的姓名、所属部门、电子邮箱、电话号码、入职日期和工资。

select a.employee_name as 姓名,b.department_id as 所属部门,a.email as 电子邮箱,a.phone_num as 电话号码,a.hire_date as 入职日期,a.salary as 工资 
from  employee a
inner join department b on a.department_id=b.department_id
where a.hire_date>'2012-01-1';

参考截图:

4.在DMHR模式下,从员工表查询员工数量大于100的部门,要求显示部门名称、员工数量,并用中文显示列名。

select department_name as 部门名称,count(*) as 员工数量
from employee a
inner join department b on a.department_id=b.department_id
group by department_name
having count(*)>100;

参考截图:

2.DM SQL程序设计基础

SET SCHEMA dmhr;
1.自定义类型定义动态数组。变量分配一个包含5个元素的数组空间,for循环遍历范围

DECLARE
   TYPE v_var_type IS VARCHAR(100);
   TYPE v_varry_type IS ARRAY v_var_type[];
      b v_varry_type;
  BEGIN
      b = new v_var_type[5];
    FOR i IN 1..4 LOOP
       b[i] :=i*11;
 PRINT b[i];
    END LOOP;
 PRINT ARRAYLEN(b);
END;

参考截图:

2.补充完成:【例1-31】REPEAT语句用法举例-1。

DECLARE
       a int;
  BEGIN
       a:=0;
   REPEAT
      print a;
       a:=a+1;
     UNTIL a>10;
  END;

参考截图:

3.补充完成:【例1-31】REPEAT语句用法举例-2

DECLARE  
      a int;
   BEGIN  
      a:=0;
  REPEAT   
     print a;  
      a:=a+1; 
  UNTIL a>11;
END;

参考截图:


4.循环语句 FOR语句应用:输出1+2+3+...+n的结果s ,n=10

DECLARE
     s int:=0;
     n int:=10;
  BEGIN
     FOR i IN 1..n LOOP
       s:=s+i;
     END LOOP;
     PRINT '1+2+3+...+n='||s;
END;

参考截图:

5. 条件控制语句 IF-THEN-ELSE 应用:
定义变量 x = 32
如果 x ≥ 18,则输出“允许参加竞赛”
如果 x < 18,则输出“不允许参加竞赛”

 DECLARE
     x NUMBER :=32;
  BEGIN
     IF x>=18 THEN
        PRINT ('允许参加竞赛');
     ELSE
        PRINT ('不允许参加竞赛');   
END IF;
END;

参考截图:

四、 异常处理与游标应用实战

1..预定义的异常

(没有抛出异常,直接输出异常)

例1.更新指定员工工资,如工资小于8500,则加100
 

​​​​​​​set schema dmhr;
DECLARE
    v_empno employee.employee_id%TYPE :=1003;
    v_sal employee.salary%TYPE;
BEGIN
    SELECT salary INTO v_sal FROM employee WHERE employee_id=v_empno;
    
    IF v_sal<=8500 THEN
        UPDATE employee SET salary=salary+100 WHERE employee_id=v_empno;
        
        PRINT('编码为'||v_empno||'员工工资已更新!');
    ELSE
        PRINT('编码为'||v_empno||'员工工资已经超过规定值!');
    END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
    PRINT('数据库中没有编码为'||v_empno||'的员工');
END;

2.非预定义的异常 

此方法可以关联DM服务器内部异常,
语法如下: 异常名 EXCEPTION;
PRAGMA EXCEPTION_INIT (异常名,错误号) 

例2:删除指定部门的记录信息,以确保该部门没有员工。
(在DM服务器内部异常):

DECLARE
    v_deptno department.department_id%TYPE :=102
BEGIN
    DELETE FROM department WHERE department_id=v_deptno 
END;

例3:更新指定部门的记录信息,薪水=原薪水+100。
 

set schema dmhr;

区别:
当UPDATE或DELETE语句的WHERE子句未找到时触发属性SQL%NOTFOUND;
SELECT...INTO语句WHERE子句未找到时会触发异常:NO_DATA_FOUND。

DECLARE
    empno_exception EXCEPTION;
BEGIN
    UPDATE dmhr.employee SET salary=salary+100 WHERE employee_id=:v_empno;
     
    IF SQL%NOTFOUND THEN
        RAISE empno_exception;
    END IF;
EXCEPTION
WHEN empno_exception THEN
    PRINT('你的数据更新语句失败了!');
WHEN OTHERS THEN
    NULL;
END;

3.游标

循环读取数据举例:

 例:查询前10名员工的信息。 

第一种方式(1)while...loop

 set schema dmhr; 
DECLARE
	v_ename  employee.employee_name%TYPE;
   	v_sal    employee.salary%TYPE;
   	CURSOR c_cursor IS SELECT employee_name,salary FROM dmhr.employee WHERE rownum<11;
BEGIN
   OPEN c_cursor;
     FETCH c_cursor INTO v_ename,v_sal;
     while(c_cursor%FOUND) loop --当最近一次读记录时成功返回,则值为TRUE; 
       print(v_ename||'的工资是:'||v_sal);
       FETCH c_cursor INTO v_ename,v_sal;
     end loop;
   close c_cursor;
END;

第二种方式(2) loop...end loop

 set schema dmhr; 
DECLARE
	v_ename  employee.employee_name%TYPE;
   	v_sal    employee.salary%TYPE;
   	CURSOR c_cursor IS SELECT employee_name,salary FROM dmhr.employee WHERE rownum<11;
BEGIN
   OPEN c_cursor;
    LOOP
       FETCH c_cursor INTO v_ename,v_sal;
       EXIT WHEN c_cursor%NOTFOUND;
       PRINT(v_ename||'的工资是:'||v_sal);
   END LOOP;
   close c_cursor;
END;

第三种方式

(3)For 记录名 in 游标名 LOOP;
         end loop;
         for它自动打开,关闭游标,提取数据,推进指针

 set schema dmhr; 
DECLARE
	v_ename  employee.employee_name%TYPE;
   	v_sal    employee.salary%TYPE;
   	CURSOR c_cursor IS SELECT employee_name,salary FROM dmhr.employee WHERE rownum<11;
BEGIN
    FOR c_record IN c_cursor LOOP
        print c_record.employee_name||'工资是:'||c_record.salary ;
    END LOOP;
END;

4.应用实战

1.题目: 编写一个DM SQL代码块,使用FOR循环和游标,从表中读取职位ID为31的员工的employee_id、employee_name、phone_num和email,并打印这些信息。

提示: 使用游标参数来传递职位ID,并在FOR循环中打印每个员工的信息。

说明:

  1. 游标定义: 定义了一个带参数的游标emp_cursor,该参数用于接收职位ID。

  2. FOR循环: 使用FOR循环读取职位ID为31的员工信息。

  3. 打印信息: 使用PRINT语句打印每个员工的employee_id、employee_name、 phone_num和email

SET SCHEMA DMHR;
DECLARE
    CURSOR emp_cursor(v_job_id employee.job_id%TYPE) 
    IS SELECT employee_id, employee_name, phone_num, email 
          FROM employee
         WHERE job_id=v_job_id;
BEGIN
FOR v_record IN emp_cursor(31) loop
    PRINT v_record.employee_id;
    PRINT v_record.employee_name;
    PRINT v_record.phone_num;
    PRINT v_record.email;
     END LOOP;
END;

参考截图:

2.题目:使用CTAS方式创建一个新表 dmhr.t1_employee ,基于 dmhr.employee 表的结构和数据。然后参考【例 1-54】编写一个DM SQL代码块,使用游标定位操作,删除 dmhr.t1_employee 表中 department_id 为 101 的第 3 条记录。

说明

  1. 创建新表: 使用 CREATE TABLE AS SELECT (CTAS) 方式创建 dmhr.t1_employee 表,该表具有与 dmhr.employee 表相同的结构和数据。

  2. 游标定义:定义了一个带 FOR UPDATE 子句的游标 emp_cursor,用于锁定 department_id 为 101 的记录,以便进行删除操作。

  3. 游标操作:使用 FETCH ABSOLUTE 语句遍历游标,游标定位到结果集中的第 3 条记录。

  4. 删除记录:使用 DELETE WHERE CURRENT OF 语句删除游标当前指向的记录。

  5. 关闭游标游标使用完后,关闭游标,从内存释放活动集。

  6. 事务提交:在操作完成后提交事务,以确保数据更改永久生效。

CREATE TABLE dmhr.t1_employee AS 
SELECT *FROM dmhr.employee;
DECLARE
    CURSOR emp_cursor IS
        SELECT*FROM dmhr.t1_employee WHERE DEPARTMENT_ID=101 FOR UPDATE;
BEGIN
    OPEN emp_cursor;
    FETCH ABSOLUTE 3 emp_cursor;
    DELETE FROM dmhr.t1_employee 
    WHERE CURRENT OF emp_cursor;
    close emp_cursor;
    COMMIT;
END;

参考截图:

4. 题目:使用CTAS方式创建一个新表 dmhr.t2_employee ,基于 dmhr.employee 表的结构和数据。写一个DM SQL代码块,使用游标定位操作,将 dmhr.t2_employee 表中 department_id 为 101 的第 3 条记录中工资 salary 列增加 1000。

说明:

创建新表使用 CREATE TABLE AS SELECT (CTAS) 方式创建 dmhr.t2_employee 表,该表具有与 dmhr.employee 表相同的结构和数据。

游标定义定义了一个带 FOR UPDATE 子句的游标 emp_cursor,用于锁定 department_id 为 101 的记录,以便进行更新操作。

游标操作:使用 FETCH ABSOLUTE 语句遍历游标,游标定位到结果集中的第 3 条记录。

更新数据:使用 UPDATA SET WHERE CURRENT OF 语句更新游标当前指向的记录的 salary 列。

关闭游标:游标使用完后,关闭游标,从内存释放活动集。

事务提交:在操作完成后提交事务,以确保数据更改永久生效。

CREATE TABLE dmhr.t2_employee AS 
SELECT * FROM DMHR.employee;

DECLARE
    CURSOR emp_cursor IS
        SELECT * FROM dmhr.t2_employee WHERE department_id = 101 FOR UPDATE;

BEGIN
    OPEN emp_cursor;
    FETCH ABSOLUTE 3 emp_cursor;
    
    UPDATE dmhr.t2_employee SET SALARY=salary+1000 WHERE CURRENT OF emp_cursor;
    
    CLOSE emp_cursor;
    COMMIT;
END;

参考截图:


总结

对整个文档的内容进行了回顾和总结,帮助读者巩固所学知识。通过以上章节的学习,读者可以掌握基本的数据库查询技术和异常处理与游标、DM程序设计的基础知识,从而在实际工作中能够有效地进行数据处理和分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值