PL/SQL 编程(二)游标、存储过程、函数
游标--数据的缓存区
游标:类似集合,可以让用户像操作数组一样操作查询出来的数据集,实质上,它提供了一种从集合性质的结果中提取单条记录的手段。
可以将游标形象的看成一个变动的光标,他实质上是一个指针,在一段Oracle存放数据查询结果集或者数据操作结果集的内存中,这个指针可以指向结果集任何一条记录。
游标分静态游标和REF游标两类,静态游标包含显式游标和隐式游标。
显式游标:
在使用之前必须有明确的游标声明和定义,这样的游标定义会关联数据查询语句,通常会返回一行或多行。打开游标后,用户可以利用游标的位置对结果集进行检索,使之返回单一的行记录,用户可以操作此记录。
显式游标需要用户自己写代码完成,一切由用户控制。
显式游标处理需四个 PL/SQL步骤:
l 定义/声明游标:就是定义一个游标名,以及与其相对应的SELECT 语句。
游标参数只能为输入参数。
在指定数据类型时,不能使用长度约束。如NUMBER(4),CHAR(10) 等都是错误的。
l 打开游标:就是执行游标所对应的SELECT 语句,将其查询结果放入工作区,并且指针指向工作区的首部,标识游标结果集合。如果游标查询语句中带有FOR UPDATE选项,OPEN 语句还将锁定数据库表中游标结果集合对应的数据行。
在向游标传递参数时,可以使用与函数参数相同的传值方法,即位置表示法和名称表示法。PL/SQL 程序不能用OPEN 语句重复打开一个游标。
l 提取游标数据:就是检索结果集合中的数据行,放入指定的输出变量中。
执行FETCH语句时,每次返回一个数据行,然后自动将游标移动指向下一个数据行。当检索到最后一行数据时,如果再次执行FETCH语句,将操作失败,并将游标属性%NOTFOUND置为TRUE。所以每次执行完FETCH语句后,检查游标属性%NOTFOUND就可以判断FETCH语句是否执行成功并返回一个数据行,以便确定是否给对应的变量赋了值。
l 对该记录进行处理;
l 继续处理,直到活动集合中没有记录;
l 关闭游标:当提取和处理完游标结果集合数据后,应及时关闭游标,以释放该游标所占用的系统资源,并使该游标的工作区变成无效,不能再使用FETCH 语句取其中数据。关闭后的游标可以使用OPEN 语句重新打开。
注意:定义的游标不能有INTO 子句。
--查询前10名员工的信息。 DECLARE CURSOR c_cursor IS SELECT first_name || last_name, Salary FROM EMPLOYEES ; v_ename EMPLOYEES.first_name%TYPE; v_sal EMPLOYEES.Salary%TYPE; BEGIN OPEN c_cursor; FETCH c_cursor INTO v_ename, v_sal; WHILE c_cursor%FOUND LOOP DBMS_OUTPUT.PUT_LINE(v_ename||'---'||to_char(v_sal) ); FETCH c_cursor INTO v_ename, v_sal; END LOOP; CLOSE c_cursor; END;
--游标参数的传递方法。 DECLARE DeptRec DEPARTMENTS%ROWTYPE; Dept_name DEPARTMENTS.DEPARTMENT_NAME%TYPE; Dept_loc DEPARTMENTS.LOCATION_ID%TYPE; CURSOR c1 IS SELECT DEPARTMENT_NAME, LOCATION_ID FROM DEPARTMENTS ; ) IS SELECT DEPARTMENT_NAME, LOCATION_ID FROM DEPARTMENTS WHERE DEPARTMENT_ID <= dept_no; ) IS SELECT * FROM DEPARTMENTS WHERE DEPARTMENTS.DEPARTMENT_ID <=dept_no; BEGIN OPEN c1; LOOP FETCH c1 INTO dept_name, dept_loc; EXIT WHEN c1%NOTFOUND; DBMS_OUTPUT.PUT_LINE(dept_name||'---'||dept_loc); END LOOP; CLOSE c1; OPEN c2; LOOP FETCH c2 INTO dept_name, dept_loc; EXIT WHEN c2%NOTFOUND; DBMS_OUTPUT.PUT_LINE(dept_name||'---'||dept_loc); END LOOP; CLOSE c2; ); LOOP FETCH c3 INTO deptrec; EXIT WHEN c3%NOTFOUND; DBMS_OUTPUT.PUT_LINE(deptrec.DEPARTMENT_ID||'---'||deptrec.DEPARTMENT_NAME||'---'||deptrec.LOCATION_ID); END LOOP; CLOSE c3; END;
--给工资低于1200 的员工增加工资50。 DECLARE v_empno EMPLOYEES.EMPLOYEE_ID%TYPE; v_sal EMPLOYEES.Salary%TYPE; CURSOR c_cursor IS SELECT EMPLOYEE_ID, Salary FROM EMPLOYEES; BEGIN OPEN c_cursor; LOOP FETCH c_cursor INTO v_empno, v_sal; EXIT WHEN c_cursor%NOTFOUND; THEN WHERE EMPLOYEE_ID=v_empno; DBMS_OUTPUT.PUT_LINE('编码为'||v_empno||'工资已更新!'); END IF; DBMS_OUTPUT.PUT_LINE('记录数:'|| c_cursor %ROWCOUNT); END LOOP; CLOSE c_cursor; END;
--没有参数且没有返回值的游标。 DECLARE v_f_name employees.first_name%TYPE; v_j_id employees.job_id%TYPE; CURSOR c1 --声明游标,没有参数没有返回值 IS SELECT first_name, job_id FROM employees ; BEGIN OPEN c1; --打开游标 LOOP FETCH c1 INTO v_f_name, v_j_id; --提取游标 IF c1%FOUND THEN DBMS_OUTPUT.PUT_LINE(v_f_name||'的岗位是'||v_j_id); ELSE DBMS_OUTPUT.PUT_LINE('已经处理完结果集了'); EXIT; END IF; END LOOP; CLOSE c1; --关闭游标 END;
--有参数且没有返回值的游标。 DECLARE v_f_name employees.first_name%TYPE; v_h_date employees.hire_date%TYPE; CURSOR c2(dept_id NUMBER, j_id VARCHAR2) --声明游标,有参数没有返回值 IS SELECT first_name, hire_date FROM employees WHERE department_id = dept_id AND job_id = j_id; BEGIN , 'AD_VP'); --打开游标,传递参数值 LOOP FETCH c2 INTO v_f_name, v_h_date; --提取游标 IF c2%FOUND THEN DBMS_OUTPUT.PUT_LINE(v_f_name||'的雇佣日期是'||v_h_date); ELSE DBMS_OUTPUT.PUT_LINE('已经处理完结果集了'); EXIT; END IF; END LOOP; CLOSE c2; --关闭游标 END;
--有参数且有返回值的游标。 DECLARE TYPE emp_record_type IS RECORD( f_name employees.first_name%TYPE, h_date employees.hire_date%TYPE); v_emp_record EMP_RECORD_TYPE; CURSOR c3(dept_id NUMBER, j_id VARCHAR2) --声明游标,有参数有返回值 RETURN EMP_RECORD_TYPE IS SELECT first_name, hire_date FROM employees WHERE department_id = dept_id AND job_id = j_id; BEGIN ); --打开游标,传递参数值 LOOP FETCH c3 INTO v_emp_record; --提取游标 IF c3%FOUND THEN DBMS_OUTPUT.PUT_LINE(v_emp_record.f_name||'的雇佣日期是' ||v_emp_record.h_date); ELSE DBMS_OUTPUT.PUT_LINE('已经处理完结果集了'); EXIT; END IF; END LOOP; CLOSE c3; --关闭游标 END;
--基于游标定义记录变量。 DECLARE CURSOR c4(dept_id NUMBER, j_id VARCHAR2) --声明游标,有参数没有返回值 IS SELECT first_name f_name, hire_date FROM employees WHERE department_id = dept_id AND job_id = j_id; --基于游标定义记录变量,比声明记录类型变量要方便,不容易出错 v_emp_record c4%ROWTYPE; BEGIN , 'AD_VP'); --打开游标,传递参数值 LOOP FETCH c4 INTO v_emp_record; --提取游标 IF c4%FOUND THEN DBMS_OUTPUT.PUT_LINE(v_emp_record.f_name||'的雇佣日期是' ||v_emp_record.hire_date); ELSE DBMS_OUTPUT.PUT_LINE('已经处理完结果集了'); EXIT; END IF; END LOOP; CLOSE c4; --关闭游标 END;
隐式游标:
被plsql自动管理,也被称为sql游标,
用户无法控制,但能得到他的属性信息。
对于非查询语句,如修改、删除操作,由ORACLE 系统自动地为这些操作设置游标并创建其工作区,这些由系统隐含创建的游标称为隐式游标,隐式游标的名字为SQL,这是由ORACLE 系统定义的。对于隐式游标的操作,如定义、打开、取值及关闭操作,都由ORACLE 系统自动地完成,无需用户进行处理。用户只能通过隐式游标的相关属性,来完成相应的操作。在隐式游标的工作区中,所存放的数据是与用户自定义的显示游标无关的、最新处理的一条SQL 语句所包含的数据。
格式调用为: SQL%
注:INSERT, UPDATE, DELETE, SELECT 语句中不必明确定义游标。
--删除EMPLOYEES表中某部门的所有员工,如果该部门中已没有员工,则在DEPARTMENT表中删除该部门。 DECLARE V_deptno department_id%TYPE :=&p_deptno; BEGIN DELETE FROM employees WHERE department_id=v_deptno; IF SQL%NOTFOUND THEN DELETE FROM departments WHERE department_id=v_deptno; END IF; END;
--通过隐式游标SQL的%ROWCOUNT属性来了解修改了多少行。 DECLARE v_rows NUMBER; BEGIN --更新数据 AND job_id = 'AD_VP'; --获取默认游标的属性值 v_rows := SQL%ROWCOUNT; DBMS_OUTPUT.PUT_LINE('更新了'||v_rows||'个雇员的工资'); --回退更新,以便使数据库的数据保持原样 ROLLBACK; END;
存储过程
存储过程就是一段存储在数据库中执行某种功能的程序。简单来时是存储在数据库服务器中的封装了一段或多段sql语句的plsql代码块。存储过程可以在编程语言中调用,如Java等。
存储过程的优点:
简化复杂的操作,封装。
增加数据独立性,利用存储过程可以把数据库基础数据和程序或用户隔离开来。
提高安全性。
提高性能。
有参存储过程:
存储过程允许带有参数,过程有输入,输出,输入输出三种参数。
输入 :in 默认,可省略
输出 :out
--输出参数 CREATE OR REPLACE PROCEDURE HANQI2(SCLA IN NUMBER, vari OUT number) AS BEGIN UPDATE STUDENT S SET S.SSEX = '女' WHERE S.CLASS = SCLA; SELECT COUNT(*) INTO vari FROM student s WHERE s.class=scla; DBMS_OUTPUT.PUT_LINE('记录已经修改 !'); END;
--用户连接登记记录; ), logdate date); CREATE OR REPLACE PROCEDURE logexecution IS BEGIN INSERT INTO logtable (userid, logdate) VALUES (USER, SYSDATE); END;
--删除指定员工记录; CREATE OR REPLACE PROCEDURE DelEmp (v_empno IN employees.employee_id%TYPE) AS No_result EXCEPTION; BEGIN DELETE FROM employees WHERE employee_id = v_empno; IF SQL%NOTFOUND THEN RAISE no_result; END IF; DBMS_OUTPUT.PUT_LINE('编码为'||v_empno||'的员工已被删除!'); EXCEPTION WHEN no_result THEN DBMS_OUTPUT.PUT_LINE('温馨提示:你需要的数据不存在!'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM); END DelEmp;
--插入员工记录: CREATE OR REPLACE PROCEDURE InsertEmp( v_empno in employees.employee_id%TYPE, v_firstname in employees.first_name%TYPE, v_lastname in employees.last_name%TYPE, v_deptno in employees.department_id%TYPE ) AS empno_remaining EXCEPTION; PRAGMA EXCEPTION_INIT(empno_remaining, ); /* -1 是违反唯一约束条件的错误代码 */ BEGIN INSERT INTO EMPLOYEES(EMPLOYEE_ID, FIRST_NAME, LAST_NAME, HIRE_DATE,DEPARTMENT_ID) VALUES(v_empno, v_firstname,v_lastname, sysdate, v_deptno); DBMS_OUTPUT.PUT_LINE('温馨提示:插入数据记录成功!'); EXCEPTION WHEN empno_remaining THEN DBMS_OUTPUT.PUT_LINE('温馨提示:违反数据完整性约束!'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM); END InsertEmp;
--使用存储过程向departments表中插入数据。 CREATE OR REPLACE PROCEDURE insert_dept (v_dept_id IN departments.department_id%TYPE, v_dept_name IN departments.department_name%TYPE, v_mgr_id IN departments.manager_id%TYPE, v_loc_id IN departments.location_id%TYPE) IS ept_null_error EXCEPTION; PRAGMA EXCEPTION_INIT(ept_null_error, ); ept_no_loc_id EXCEPTION; PRAGMA EXCEPTION_INIT(ept_no_loc_id, ); BEGIN INSERT INTO departments (department_id, department_name, manager_id, location_id) VALUES (v_dept_id, v_dept_name, v_mgr_id, v_loc_id); DBMS_OUTPUT.PUT_LINE('插入部门'||v_dept_id||'成功'); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN RAISE_APPLICATION_ERROR(, '部门编码不能重复'); WHEN ept_null_error THEN RAISE_APPLICATION_ERROR(, '部门编码、部门名称不能为空'); WHEN ept_no_loc_id THEN RAISE_APPLICATION_ERROR(, '没有该地点'); END insert_dept;
--调用实例一: DECLARE ept_20000 EXCEPTION; PRAGMA EXCEPTION_INIT(ept_20000, ); ept_20001 EXCEPTION; PRAGMA EXCEPTION_INIT(ept_20001, ); ept_20002 EXCEPTION; PRAGMA EXCEPTION_INIT(ept_20002, ); BEGIN insert_dept(, , ); insert_dept(, , ); insert_dept(, , ); EXCEPTION WHEN ept_20000 THEN DBMS_OUTPUT.PUT_LINE('ept_20000部门编码不能重复'); WHEN ept_20001 THEN DBMS_OUTPUT.PUT_LINE('ept_20001部门编码、部门名称不能为空'); WHEN ept_20002 THEN DBMS_OUTPUT.PUT_LINE('ept_20002没有该地点'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('others出现了其他异常错误'); END; --调用实例二: DECLARE ept_20000 EXCEPTION; PRAGMA EXCEPTION_INIT(ept_20000, ); ept_20001 EXCEPTION; PRAGMA EXCEPTION_INIT(ept_20001, ); ept_20002 EXCEPTION; PRAGMA EXCEPTION_INIT(ept_20002, ); BEGIN insert_dept(v_dept_name , v_mgr_id , v_loc_id ); insert_dept(, , v_loc_id ); EXCEPTION WHEN ept_20000 THEN DBMS_OUTPUT.PUT_LINE('ept_20000部门编码不能重复'); WHEN ept_20001 THEN DBMS_OUTPUT.PUT_LINE('ept_20001部门编码、部门名称不能为空'); WHEN ept_20002 THEN DBMS_OUTPUT.PUT_LINE('ept_20002没有该地点'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('others出现了其他异常错误'); END;
函数
函数主要组成部分:
输入部分。输入参数,调用函数时给这些参数赋值。
逻辑计算部分。函数内部将完成对各种数据项目的计算。
输出部分。函数必须有返回值。
--输入参数,计算和 CREATE OR REPLACE FUNCTION CAL_ADD(A IN NUMBER, B IN NUMBER) RETURN NUMBER; AS C NUMBER; BEGIN C := A + B; RETURN C; END;
--获取某部门的工资总和 CREATE OR REPLACE FUNCTION get_salary( Dept_no NUMBER, Emp_count OUT NUMBER) RETURN NUMBER IS V_sum NUMBER; BEGIN SELECT SUM(SALARY), count(*) INTO V_sum, emp_count FROM EMPLOYEES WHERE DEPARTMENT_ID=dept_no; RETURN v_sum; EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('你需要的数据不存在!'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM); END get_salary;
用程序在调用函数时,可以使用以下三种方法向函数传递参数:
第一种参数传递格式:位置表示法。
即在调用时按形参的排列顺序,依次写出实参的名称,而将形参与实参关联起来进行传递。用这种方法进行调用,形参与实参的名称是相互独立,没有关系,强调次序才是重要的。
--计算某部门的工资总和: DECLARE V_num NUMBER; V_sum NUMBER; BEGIN V_sum :, v_num); DBMS_OUTPUT.PUT_LINE('部门号为:10的工资总和:'||v_sum||',人数为:'||v_num); END;
第二种参数传递格式:名称表示法。
即在调用时按形参的名称与实参的名称,写出实参对应的形参,而将形参与实参关联起来进行传递。这种方法,形参与实参的名称是相互独立的,没有关系,名称的对应关系才是最重要的,次序并不重要。
--计算某部门的工资总和: DECLARE V_num NUMBER; V_sum NUMBER; BEGIN V_sum :); DBMS_OUTPUT.PUT_LINE('部门号为:10的工资总和:'||v_sum||',人数为:'||v_num); END;
第三种参数传递格式:组合传递。
即在调用一个函数时,同时使用位置表示法和名称表示法为函数传递参数。采用这种参数传递方法时,使用位置表示法所传递的参数必须放在名称表示法所传递的参数前面。也就是说,无论函数具有多少个参数,只要其中有一个参数使用名称表示法,其后所有的参数都必须使用名称表示法。
CREATE OR REPLACE FUNCTION demo_fun( Name VARCHAR2,--注意VARCHAR2不能给精度,如:VARCHAR2(10),其它类似 Age INTEGER, Sex VARCHAR2) RETURN VARCHAR2 AS V_var ); BEGIN V_var := name||':'||TO_CHAR(age)||'岁.'||sex; RETURN v_var; END; DECLARE ); BEGIN , sex => '男'); DBMS_OUTPUT.PUT_LINE(var); , sex => '男'); DBMS_OUTPUT.PUT_LINE(var); ); DBMS_OUTPUT.PUT_LINE(var); END;
无论采用哪一种参数传递方法,实际参数和形式参数之间的数据传递只有两种方法:传址法和传值法。
传址法:指在调用函数时,将实际参数的地址指针传递给形式参数,使形式参数和实际参数指向内存中的同一区域,从而实现参数数据的传递。这种方法又称作参照法,即形式参数参照实际参数数据。输入参数均采用传址法传递数据。
传值法:指将实际参数的数据拷贝到形式参数,而不是传递实际参数的地址。默认时,输出参数和输入/输出参数均采用传值法。在函数调用时,ORACLE将实际参数数据拷贝到输入/输出参数,而当函数正常运行退出时,又将输出形式参数和输入/输出形式参数数据拷贝到实际参数变量中。
注意:在CREATE OR REPLACE FUNCTION 语句中声明函数参数时可以使用DEFAULT关键字为输入参数指定默认值。
CREATE OR REPLACE FUNCTION demo_fun( Name VARCHAR2, Age INTEGER, Sex VARCHAR2 DEFAULT '男') RETURN VARCHAR2 AS V_var ); BEGIN V_var := name||':'||TO_CHAR(age)||'岁.'||sex; RETURN v_var; END;
具有默认值的函数创建后,在函数调用时,如果没有为具有默认值的参数提供实际参数值,函数将使用该参数的默认值。但当调用者为默认参数提供实际参数时,函数将使用实际参数值。在创建函数时,只能为输入参数设置默认值,而不能为输入/输出参数设置默认值。
DECLARE ); BEGIN ); DBMS_OUTPUT.PUT_LINE(var); ); DBMS_OUTPUT.PUT_LINE(var); ); DBMS_OUTPUT.PUT_LINE(var); END;
PL/SQL 编程(二)游标、存储过程、函数的更多相关文章
- 五、PL/SQL循环、游标、函数和过程
--PL/SQL基础知识学习 --一.PL/SQL语句块,基础语法格式 DECLARE --变量声明列表 info varchar(25); --变量声明 stu_unm integer := 15; ...
- PL/SQL 编程(二)
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u011685627/article/details/26299399 1 For循环 ...
- [顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功)
原文:[顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功) [顶]ORACLE PL/SQL编程详解之二: PL/SQL块结构和组成元素(为山九仞,岂一日 ...
- ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!)
原文:ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!) ORACLE PL/SQL编程之六: 把过程与函数说透(穷追猛打,把根儿都拔起!) 继上篇:ORACLE P ...
- [推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到)
原文:[推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到) [推荐]ORACLE PL/SQL编程之四: 把游标说透(不怕做不到,只怕想不到) 继上两篇:ORACLE PL ...
- PL/SQL学习笔记_03_存储函数与存储过程
ORACLE 提供可以把 PL/SQL 程序存储在数据库中,并可以在任何地方来运行它.这样就叫存储过程或函数. 存储函数:有返回值,创建完成后,通过select function() from dua ...
- ORACLE PL/SQL编程详解
ORACLE PL/SQL编程详解 编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设 ...
- [强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!)
原文:[强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!) [强烈推荐]ORACLE PL/SQL编程详解之七: 程序包的创建与应用(聪明在于学习,天 ...
- 【强烈强烈推荐】《ORACLE PL/SQL编程详解》全原创(共八篇)--系列文章导航
原文:[强烈强烈推荐]<ORACLE PL/SQL编程详解>全原创(共八篇)--系列文章导航 <ORACLE PL/SQL编程详解> 系列文章目录导航 ——通过知识共享树立个人 ...
- ORACLE PL/SQL编程详解(转)
原帖地址:http://blog.csdn.net/chenjinping123/article/details/8737604 ORACLE PL/SQL编程详解 SQL语言只是访问.操作数据库的语 ...
随机推荐
- 【Android Developers Training】 66. 添加动画
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- linq 批量修改更新
批量修改:var values = Context.Request["values"].JsonDeserialize<Dictionary<string, objec ...
- 微信小程序的开发环境搭建(Windows版本)
前言: 小程序是指微信公众平台小程序,小程序可以帮助开发者快速的开发小程序,小程序可以在微信内被便捷地获取和传播:是一种不需要下载安装即可使用的应用小程序,和原有的三种公众号是并行的体系.2017年1 ...
- JavaScript学习笔记(二)——选项卡小结
Js制作选项卡小结 1.先构思好需要展示的页面效果,比如这样 2.需要显示的效果通过html和css制作出来,包括选项(第一课.第二课)的鼠标停留背景变色.下方选项页内容切换的内容等. 3.把此选项卡 ...
- C#窗体多语言切换(简繁)
多窗体最好继承一个父窗体,在父窗体Load事件中执行此方法 添加引用 using Microsoft.VisualBasic; #region 语言切换 /// <summary> /// ...
- (转载)Oracle10g 数据泵导出命令 expdp 使用总结(三)
原文链接:http://hi.baidu.com/edeed/item/19aa0df856da3e19a6298894 Oracle10g 数据泵导出命令 expdp 使用总结(一) 14. JOB ...
- Java 时钟
<!DOCTYPE html><html lang="zh"><head> <meta charset="UTF-8" ...
- HTML5 drag和drop的亲手实践
起因 最近在公司打杂的时候,突然分到了一个锅,就是要支持一个新的功能:用户可以通过拖曳组件来改变组件的顺序.因此,这阵子就看了一下网上的一些drag和drog的文章以及W3C的介绍,然后自己亲手实践了 ...
- Html table 合并单元格
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- docker~Dockerfile方式建立镜像HelloWorld
回到目录 Dockerfile可以便捷的建立一个image,它可以在一个镜像基础上,去构建另一个镜像,这也许就是它的特色,也是docker的本意! 我们下载一个mono的镜像 docker pull ...