源码-PL/SQL从入门到精通-第十四章-包-Part 1

调试经验:

1. 编译包时,如果出现编译错误(PL/SQL developer中包名出现红叉),可通过以下语句查看:

SELECT   name,line, POSITION, text
    FROM user_errors
   WHERE NAME = 'INITTEST'
ORDER BY SEQUENCE;

2. 上述语句中,引号中的包名(如,INITTEST)一定要大写,否则查不到


另外,PL/SQL中的包分为包规范(包的定义)和包体(包的实现)两部分,是PL/SQL编程的基本单元。

虽然名称为包,但包中内容无非是一些类型定义(常量、集合、记录、游标、函数、过程等变量)及实现方法,这更像是Java中的一个类(字段+方法),而比Java的包(package) 又低一个层次。


--第14章开始
--代码14.1 包规范定义示例
--定义包规范,包规范将被用于应用程序的接口部分,供外部调用
CREATE OR REPLACE PACKAGE emp_pkg AS
   --定义集合类型
   TYPE emp_tab IS TABLE OF emp%ROWTYPE INDEX BY BINARY_INTEGER;
   --在包规范中定义一个记录类型
   TYPE emprectyp IS RECORD(
      emp_no NUMBER,
      sal  NUMBER
   );
   --定义一个游标变量
   CURSOR desc_salary RETURN emprectyp;
   --定义雇佣员工的过程
   PROCEDURE hire_employee(p_empno NUMBER,p_ename VARCHAR2,p_job VARCHAR2,p_mgr NUMBER,p_sal NUMBER,
                        p_comm NUMBER,p_deptno NUMBER,p_hiredate DATE);
   --定义解雇员工的过程                        
   PROCEDURE fire_employee(p_emp_id NUMBER );
END emp_pkg;

--代码14.2 包体定义示例
--定义包体
CREATE OR REPLACE PACKAGE BODY emp_pkg
AS
   --定义游标变量的具体类型
   CURSOR desc_salary RETURN emprectyp IS
      SELECT empno, sal FROM emp ORDER BY sal DESC;
   --定义雇佣员工的具体实现
   PROCEDURE hire_employee(p_empno NUMBER,p_ename VARCHAR2,
                           p_job VARCHAR2,p_mgr NUMBER,p_sal NUMBER,
                           p_comm NUMBER,p_deptno NUMBER,p_hiredate DATE) IS
   BEGIN
      --向emp表中插入一条员工信息
      INSERT INTO emp VALUES(p_empno,p_ename,p_job,p_mgr,p_hiredate,p_sal,p_comm,p_deptno); 
   END;       
   --定义解雇员工的具体实现                 
   PROCEDURE fire_employee(p_emp_id NUMBER ) IS
   BEGIN
      --从emp表中删除员工信息
      DELETE FROM emp WHERE empno=p_emp_id;
   END;          
END emp_pkg;



--代码14.3 包规范定义示例
--定义包规范,包规范将被用于应用程序的接口部分,供外部调用
CREATE OR REPLACE PACKAGE dept_pkg AS
   dept_count NUMBER:=1;
   --定义集合类型
   TYPE dept_tab IS TABLE OF dept%ROWTYPE INDEX BY BINARY_INTEGER;
   --在包规范中定义一个记录类型
   TYPE deptrectyp IS RECORD(
      dept_no NUMBER,
      dname  VARCHAR2(30),
      loc VARCHAR2(30)
   );
   CURSOR deptcur RETURN deptrectyp;       --定义一个游标变量
   e_nodept_assign EXCEPTION;              --定义一个异常
END dept_pkg;


--代码14.4 调用包规范中定义的元素
DECLARE
   mydept dept_pkg.dept_tab;                           --定义包中的集合类型的变量     
BEGIN
   FOR deptrow IN (SELECT * FROM dept) LOOP            --使用游标FOR循环提取dept数据
     mydept(dept_pkg.dept_count):=deptrow;             --为集合类型赋值
     dept_pkg.dept_count:=dept_pkg.dept_count+1;       --递增包中的变量的值
   END LOOP;    
   FOR i IN 1..mydept.count LOOP                       --循环显示集合中的部门的部门名称
      DBMS_OUTPUT.put_line(mydept(i).dname);
   END LOOP;
   dept_pkg.dept_count:=1;                             --重置dept_pkg.dept_count的值。
EXCEPTION
   WHEN  dept_pkg.e_nodept_assign THEN
      DBMS_OUTPUT.put_line('没有找到员工记录');     --捕捉异常,如果有触发的话
END;   



--代码14.5 包体实现示例
--定义包规范
CREATE OR REPLACE PACKAGE emp_action_pkg IS
   v_deptno NUMBER(3):=20;              --包公开的变量
   --定义一个增加新员工的过程
   PROCEDURE newdept (
       p_deptno   dept.deptno%TYPE,    --部门编号
       p_dname    dept.dname%TYPE,     --部门名称
       p_loc      dept.loc%TYPE        --位置
    );   
    --定义一个获取员工加薪数量的函数
    FUNCTION getraisedsalary (p_empno emp.empno%TYPE)
       RETURN NUMBER;    
END emp_action_pkg;

--定义包体
CREATE OR REPLACE PACKAGE BODY emp_action_pkg IS
  --公开,实现包规范中定义的newdept过程
  PROCEDURE newdept (
       p_deptno   dept.deptno%TYPE,    --部门编号
       p_dname    dept.dname%TYPE,     --部门名称
       p_loc      dept.loc%TYPE        --位置
    )
    AS
       v_deptcount   NUMBER;           --保存是否存在员工编号
       BEGIN
       SELECT COUNT (*) INTO v_deptcount FROM dept
        WHERE deptno = p_deptno;       --查询在dept表中是否存在部门编号
       IF v_deptcount > 0              --如果存在相同的员工记录
       THEN                            --抛出异常
          raise_application_error (-20002, '出现了相同的部门记录');
       END IF;
       INSERT INTO dept(deptno, dname, loc)  
            VALUES (p_deptno, p_dname, p_loc);--插入记录
    END newdept;
    --公开,实现包规范中定义的getraisedsalary函数
    FUNCTION getraisedsalary (p_empno emp.empno%TYPE)
       RETURN NUMBER
    IS
       v_job           emp.job%TYPE;            --职位变量
       v_sal           emp.sal%TYPE;            --薪资变量
       v_salaryratio   NUMBER (10, 2);          --调薪比率
    BEGIN
       --获取员工表中的薪资信息
       SELECT job, sal INTO v_job, v_sal FROM emp WHERE empno = p_empno;
       CASE v_job                               --根据不同的职位获取调薪比率
          WHEN '职员' THEN
             v_salaryratio := 1.09;
          WHEN '销售人员' THEN
             v_salaryratio := 1.11;
          WHEN '经理' THEN
             v_salaryratio := 1.18;
          ELSE
             v_salaryratio := 1.1;
       END CASE;
       IF v_salaryratio <> 1                    --如果有调薪的可能
       THEN
          RETURN ROUND(v_sal * v_salaryratio,2);         --返回调薪后的薪资
       ELSE
          RETURN v_sal;                         --否则不返回薪资
       END IF;
     EXCEPTION
          WHEN NO_DATA_FOUND THEN
             RETURN 0;                             --如果没找到原工记录,返回0
     END getraisedsalary;
    --私有,该函数在包规范中并不存在,只能在包体内被引用
    FUNCTION checkdeptno(p_deptno dept.deptno%TYPE) RETURN NUMBER
    AS
      v_counter NUMBER(2);
    BEGIN
       SELECT COUNT(*) INTO v_counter FROM dept WHERE deptno=p_deptno;
       RETURN v_counter; 
    END;           
END emp_action_pkg;       

--代码14.6 调用包组件示例
--在该块中为v_deptno赋值为30,调用getraisedsalary函数
BEGIN
   emp_action_pkg.v_deptno:=30;                                  --为包规范变量赋值
   DBMS_OUTPUT.put_line(emp_action_pkg.getraisedsalary(7369));--调用包中的函数
END;

select * from dept;
--在该块中为v_deptno赋值为50,并调用newdept过程
BEGIN
   emp_action_pkg.v_deptno:=50;
   emp_action_pkg.newdept(45,'采纳部','佛山');
END;
--在该块中输出v_deptno的值

BEGIN
   DBMS_OUTPUT.put_line(emp_action_pkg.v_deptno);
END;

DELETE FROM dept WHERE deptno=45;

--代码14.7 使用SERIALLY_RESUABLE编译提示
--定义包规范
CREATE OR REPLACE PACKAGE emp_action_pkg IS
   PRAGMA SERIALLY_REUSABLE;            --指定编译提示
   v_deptno NUMBER(3):=20;              --包公开的变量
   --定义一个增加新员工的过程
   PROCEDURE newdept (
       p_deptno   dept.deptno%TYPE,    --部门编号
       p_dname    dept.dname%TYPE,     --部门名称
       p_loc      dept.loc%TYPE        --位置
    );   
    --定义一个获取员工加薪数量的函数
    FUNCTION getraisedsalary (p_empno emp.empno%TYPE)
       RETURN NUMBER;    
END emp_action_pkg;

--定义包体
CREATE OR REPLACE PACKAGE BODY emp_action_pkg IS
   PRAGMA SERIALLY_REUSABLE;            --指定编译提示
  --公开,实现包规范中定义的newdept过程
  PROCEDURE newdept (
       p_deptno   dept.deptno%TYPE,    --部门编号
       p_dname    dept.dname%TYPE,     --部门名称
       p_loc      dept.loc%TYPE        --位置
    )
    AS
       v_deptcount   NUMBER;           --保存是否存在员工编号
       BEGIN
       SELECT COUNT (*) INTO v_deptcount FROM dept
        WHERE deptno = p_deptno;       --查询在dept表中是否存在部门编号
       IF v_deptcount > 0              --如果存在相同的员工记录
       THEN                            --抛出异常
          raise_application_error (-20002, '出现了相同的员工记录');
       END IF;
       INSERT INTO dept(deptno, dname, loc)  
            VALUES (p_deptno, p_dname, p_loc);--插入记录
    END newdept;
    --公开,实现包规范中定义的getraisedsalary函数
    FUNCTION getraisedsalary (p_empno emp.empno%TYPE)
       RETURN NUMBER
    IS
       v_job           emp.job%TYPE;            --职位变量
       v_sal           emp.sal%TYPE;            --薪资变量
       v_salaryratio   NUMBER (10, 2);          --调薪比率
    BEGIN
       --获取员工表中的薪资信息
       SELECT job, sal INTO v_job, v_sal FROM emp WHERE empno = p_empno;
       CASE v_job                               --根据不同的职位获取调薪比率
          WHEN '职员' THEN
             v_salaryratio := 1.09;
          WHEN '销售人员' THEN
             v_salaryratio := 1.11;
          WHEN '经理' THEN
             v_salaryratio := 1.18;
          ELSE
             v_salaryratio := 1;
       END CASE;
       IF v_salaryratio <> 1                    --如果有调薪的可能
       THEN
          RETURN ROUND(v_sal * v_salaryratio,2);         --返回调薪后的薪资
       ELSE
          RETURN v_sal;                         --否则不返回薪资
       END IF;
     EXCEPTION
          WHEN NO_DATA_FOUND THEN
             RETURN 0;                             --如果没找到原工记录,返回0
     END getraisedsalary;
    --私有,该函数在包规范中并不存在,只能在包体内被引用
    FUNCTION checkdeptno(p_deptno dept.deptno%TYPE) RETURN NUMBER
    AS
      v_counter NUMBER(2);
    BEGIN
       SELECT COUNT(*) INTO v_counter FROM dept WHERE deptno=p_deptno;
       RETURN v_counter; 
    END;           
END emp_action_pkg;   



--包的重新编译
ALTER PACKAGE emp_action_pkg COMPILE BODY;           --编译包体
ALTER PACKAGE emp_action_pkg COMPILE PACKAGE;        --编译包规范和包体
ALTER PACKAGE emp_action_pkg COMPILE SPECIFICATION;  --编译包规范

--查看包对象和包体对象
 SELECT object_type 对象类型, object_name 对象名称, status 状态
  FROM user_objects
  WHERE object_type IN ('PACKAGE', 'PACKAGE BODY')
  ORDER BY object_type, status, object_name;
  
--查看包规范的源代码  
SELECT   line, text
    FROM user_source
   WHERE NAME = 'EMP_ACTION_PKG' AND TYPE = 'PACKAGE'
ORDER BY line;

--查看包体的源代码  
SELECT   line, text
    FROM user_source
   WHERE NAME = 'EMP_ACTION_PKG' AND TYPE = 'PACKAGE BODY'
ORDER BY line;

--代码14.8 在包中重载子程序
--定义包规范
CREATE OR REPLACE PACKAGE emp_action_pkg_overload IS
   --定义一个增加新员工的过程
   PROCEDURE newdept (
       p_deptno   dept.deptno%TYPE,    --部门编号
       p_dname    dept.dname%TYPE,     --部门名称
       p_loc      dept.loc%TYPE        --位置
    );   
   --定义一个增加新员工的过程,重载过程
   PROCEDURE newdept (
       p_deptno   dept.deptno%TYPE,    --部门编号
       p_dname    dept.dname%TYPE     --部门名称
    );       
    --定义一个获取员工加薪数量的函数
    FUNCTION getraisedsalary (p_empno emp.empno%TYPE)
       RETURN NUMBER;
       
    --定义一个获取员工加薪数量的函数,重载函数
    FUNCTION getraisedsalary (p_ename emp.ename%TYPE)
       RETURN NUMBER;                  
END emp_action_pkg_overload;

--代码14.9 包含重载子程序的包体实现
--定义包体
CREATE OR REPLACE PACKAGE BODY emp_action_pkg_overload IS
  --公开,实现包规范中定义的newdept过程
  PROCEDURE newdept (
       p_deptno   dept.deptno%TYPE,    --部门编号
       p_dname    dept.dname%TYPE,     --部门名称
       p_loc      dept.loc%TYPE        --位置
    )
    AS
       v_deptcount   NUMBER;           --保存是否存在员工编号
       BEGIN
       SELECT COUNT (*) INTO v_deptcount FROM dept
        WHERE deptno = p_deptno;       --查询在dept表中是否存在部门编号
       IF v_deptcount > 0              --如果存在相同的员工记录
       THEN                            --抛出异常
          raise_application_error (-20002, '出现了相同的员工记录');
       END IF;
       INSERT INTO dept(deptno, dname, loc)  
            VALUES (p_deptno, p_dname, p_loc);--插入记录
    END newdept;
    
  PROCEDURE newdept (
       p_deptno   dept.deptno%TYPE,    --部门编号
       p_dname    dept.dname%TYPE     --部门名称
    )
    AS
       v_deptcount   NUMBER;           --保存是否存在员工编号
       BEGIN
       SELECT COUNT (*) INTO v_deptcount FROM dept
        WHERE deptno = p_deptno;       --查询在dept表中是否存在部门编号
       IF v_deptcount > 0              --如果存在相同的员工记录
       THEN                            --抛出异常
          raise_application_error (-20002, '出现了相同的员工记录');
       END IF;
       INSERT INTO dept(deptno, dname, loc)  
            VALUES (p_deptno, p_dname, '中国');--插入记录
    END newdept;    
    
    --公开,实现包规范中定义的getraisedsalary函数
    FUNCTION getraisedsalary (p_empno emp.empno%TYPE)
       RETURN NUMBER
    IS
       v_job           emp.job%TYPE;            --职位变量
       v_sal           emp.sal%TYPE;            --薪资变量
       v_salaryratio   NUMBER (10, 2);          --调薪比率
    BEGIN
       --获取员工表中的薪资信息
       SELECT job, sal INTO v_job, v_sal FROM emp WHERE empno = p_empno;
       CASE v_job                               --根据不同的职位获取调薪比率
          WHEN '职员' THEN
             v_salaryratio := 1.09;
          WHEN '销售人员' THEN
             v_salaryratio := 1.11;
          WHEN '经理' THEN
             v_salaryratio := 1.18;
          ELSE
             v_salaryratio := 1;
       END CASE;
       IF v_salaryratio <> 1                    --如果有调薪的可能
       THEN
          RETURN ROUND(v_sal * v_salaryratio,2);         --返回调薪后的薪资
       ELSE
          RETURN v_sal;                         --否则不返回薪资
       END IF;
     EXCEPTION
          WHEN NO_DATA_FOUND THEN
             RETURN 0;                             --如果没找到原工记录,返回0
     END getraisedsalary;
     
    --重载函数的实现
    FUNCTION getraisedsalary (p_ename emp.ename%TYPE)
       RETURN NUMBER
    IS
       v_job           emp.job%TYPE;            --职位变量
       v_sal           emp.sal%TYPE;            --薪资变量
       v_salaryratio   NUMBER (10, 2);          --调薪比率
    BEGIN
       --获取员工表中的薪资信息
       SELECT job, sal INTO v_job, v_sal FROM emp WHERE ename = p_ename;
       CASE v_job                               --根据不同的职位获取调薪比率
          WHEN '职员' THEN
             v_salaryratio := 1.09;
          WHEN '销售人员' THEN
             v_salaryratio := 1.11;
          WHEN '经理' THEN
             v_salaryratio := 1.18;
          ELSE
             v_salaryratio := 1;
       END CASE;
       IF v_salaryratio <> 1                    --如果有调薪的可能
       THEN
          RETURN ROUND(v_sal * v_salaryratio,2);         --返回调薪后的薪资
       ELSE
          RETURN v_sal;                         --否则不返回薪资
       END IF;
     EXCEPTION
          WHEN NO_DATA_FOUND THEN
             RETURN 0;                             --如果没找到原工记录,返回0
     END getraisedsalary;     
     
    --私有,该函数在包规范中并不存在,只能在包体内被引用
    FUNCTION checkdeptno(p_deptno dept.deptno%TYPE) RETURN NUMBER
    AS
      v_counter NUMBER(2);
    BEGIN
       SELECT COUNT(*) INTO v_counter FROM dept WHERE deptno=p_deptno;
       RETURN v_counter; 
    END;           
END emp_action_pkg_overload;   


--重载过程调用示例
DECLARE
   v_sal NUMBER(10,2);
BEGIN
   emp_action_pkg_overload.newdept(43,'样品部','东京');          --重载过程使用示例
   emp_action_pkg_overload.newdept(44,'纸品部');
   v_sal:=emp_action_pkg_overload.getraisedsalary(7369);         --重载函数使用示例
   v_sal:=emp_action_pkg_overload.getraisedsalary('史密斯');
END;


--代码14.10 包体初始化单元示例
--定义包头,在包头中定义要公开的成员
CREATE OR REPLACE PACKAGE InitTest IS
   TYPE emp_typ IS TABLE OF emp%ROWTYPE INDEX BY BINARY_INTEGER;
   CURSOR emp_cur RETURN emp%ROWTYPE;      --定义游标
   curr_time NUMBER;                       --当前秒数
   emp_tab emp_typ;                        --定义集合类型的变量
   --定义一个增加新员工的过程
   PROCEDURE newdept (
       p_deptno   dept.deptno%TYPE,    --部门编号
       p_dname    dept.dname%TYPE,     --部门名称
       p_loc      dept.loc%TYPE        --位置
    );   
    --定义一个获取员工加薪数量的函数
    FUNCTION getraisedsalary (p_empno emp.empno%TYPE)
       RETURN NUMBER;         
END InitTest;
--定义包体,在包体的初始化区域对包进行初始化
CREATE OR REPLACE PACKAGE BODY InitTest IS
   row_counter NUMBER:=1;
   CURSOR emp_cur RETURN emp%ROWTYPE IS
      SELECT * FROM emp ORDER BY sal DESC; --定义游标体         
    --定义一个增加新员工的过程
   PROCEDURE newdept (
       p_deptno   dept.deptno%TYPE,    --部门编号
       p_dname    dept.dname%TYPE,     --部门名称
       p_loc      dept.loc%TYPE        --位置
    ) AS
    BEGIN
       NULL;
    END newdept;
    --定义一个获取员工加薪数量的函数
    FUNCTION getraisedsalary (p_empno emp.empno%TYPE)
       RETURN NUMBER IS
    BEGIN
       NULL;
    END getraisedsalary;
BEGIN    
    --包初始化部分,定义包的代码
    SELECT TO_NUMBER(TO_CHAR(SYSDATE,'SSSSS')) INTO curr_time FROM dual;
     FOR emp_row IN emp_cur LOOP
       emp_tab(row_counter):=emp_row;          --为集合赋值
       row_counter:=row_counter+1;
    END LOOP;   
EXCEPTION 
    WHEN OTHERS THEN 
       DBMS_OUTPUT.put_line('出现了异常');               
END InitTest;

SELECT   name,line, POSITION, text
    FROM user_errors
   WHERE NAME = 'INITTEST'
ORDER BY SEQUENCE;


DECLARE
   v_time NUMBER;
BEGIN
   v_time:=InitTest.curr_time;              --获取当前的时间秒数
   --输出索引表中的员工名称,以及当前的秒数(应该是初始化时的秒数)。
  DBMS_OUTPUT.put_line(InitTest.emp_tab(1).ename||' '||v_time);
END;



本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。

DB2数据库的学习及总结 - 2016-07-23 19:07:12

                                                                                                                                                   db2命令 给db2用赋权的命令 db2 grant dbadm on database to user dsp #导出数据库结构会生成一个faldb20160224.sql文件  db2look -d udep -
对于PL/SQL这种基本上面向过程的语言来讲,子程序(过程和函数)就是其核心所在了。 整个解决方案可通过组织、调用由过程和函数构成的模块来实现。 在“Divide and conquer”(分而治之)的编程世界中,子程序就是程序员手中的兵器,用的越熟练越好。 --代码 13.1 创建过程示例CREATE OR REPLACE PROCEDURE newdept ( p_deptno dept.deptno%TYPE, --部门编号 p_dname dept.dname%TYPE, --部门名称 p_loc
调试nocopy功能时,为了看到实际效果,设置了一个比较大的循环次数,结果悲剧了: 运行了近1个小时没出结果,电脑死机(任务管理器都打不开);无奈只能强行关机,开机时间又特别长,一度让我以为系统崩溃。 看来,PL/SQL developer下调试这种暴力计算的程序风险很高啊,我在Eclipse下调试Java程序时从来没碰到过这种造成电脑死机的情况。 不过,这章的内容实用性很强,死机也值了(有点心疼电脑了 ) -代码13.11 使用%Type定义形式参数CREATE OR REPLACE PROCEDURE
Less - 54 Challenge-1 Test Sourse Code Solution Less - 55 Challenge-2 Test Sourse Code Solution Less - 56 Challenge-3 Test Sourse Code Solution Less - 57 Challenge-4 Test Sourse Code Solution Less - 58 Challenge-5 Test Sourse Code Solution Less - 59 Chall

CentOS7安装配置hadoop2.7.2 - 2016-07-23 18:07:08

linux 虚拟机配置 系统配置: 虚拟机:一个master(Master.Hadoop),两个slave(Slave1.Hadoop, Slave2.Hadoop) 网络设置:我使用的是桥接的方式 内存:每个虚拟机配置4G内存 分区:手动配置 软件选择:最小安装,注意选择开发工具 用户设置:密码都设置为:hadoophadoop, 不创建任何用户,操作时使用root直接进行 安装完后各个虚拟机的ip配置(参考用) 主机 ip地址 master.hadoop 192.168.200.30 slave1.h
最近写的项目中有用到数据库,写了不少蛋疼的sql语句,每次都是好几行代码,而且每次都是重复的没有一点技术含量的代码,虽然也有不少基于sqlite的封装,不过用起来还是感觉不够面向对象! 为了不再写重复的代码,花了几天时间,基于SQLite3简单封装了下,实现了一行代码解决增删改查等常用的功能!并没有太过高深的知识,主要用了runtime和KVC: 首先我们创建个大家都熟悉的Person类,并声明两个属性,下面将以类此展开分析 @interface Person : NSObject @property (

MySQL原来也有内存数据库 - 2016-07-23 18:07:20

以前只知道MySQL可以做分库分表,支持多种数据库引擎。这次听了来自台湾的MySQL专家Ivan Tu的讲座,有两点印象深刻,一是MySQL具有丰富的高可用方案,二是MySQL也有内存数据库,即MySQL Cluster CGE。Ivan形象的将内存数据库比喻成浅浅的盘子,而传统的MySQL磁盘存储方式比喻成深深的瓶子。 另外,也探讨了MySQL作为开源数据库,和Oracle数据库的关系。MySQL并行发展企业版和社区版,企业版增加了很多企业级的特性,如安全,备份和恢复,监控,以及CGE(电信运营商版)。
CleverCode研究了一下,怎么kill掉慢的sql语句。 1 单个kill mysql show processlist; mysql kill 251; #批量kill 1)查找Lockd语句 mysql -uroot -p123456 -h 192.1.20.101 -e "show processlist" | grep -i 'Locked' locked_log.txt 2)组合kill for line in `cat locked_log.txt | awk '{print $1}'`
前段时间把项目中的JPA从EclipseLink换成Hibernate。这其中遇到了很多问题,也记录了一部分在其他的文章中。这里介绍一个UT中遇到的问题。 当时的测试是忘H2数据库中插入多项数据,然后用Query的方式删除,assert读出来的数据是null。这个测试用例在EclipseLink下面是可以通过的,但换成Hibernate之后发现数据仍然可以读出这个数据。 测试用例如下: @Test public void shouldRemovesAllFmReportFromDb () { FmRepo
实施逻辑复制软件时对在目的端数据库的字符集(排序规则)的要求 1.当目的端数据库是Oracle数据库时,务必保证目的端Oracle数据库的字符集与源头Oracle数据库的字符集保持一致. 2.当目的端数据库是MSSQLServer数据库时,务必保证目的端MSSQLServer 用户数据库的排序规则与源头MSSQLServer 用户数据库的排序规则一致. 3.当目的端数据库是MSSQLServer数据库时,务必保证目的端MSSQLServer master数据库的排序规则与源头MSSQLServer mas