Oracle生成流水号函数
一、参考
1:日期范围上 smalldatetime的有效时间范围1900/1/1~2079/6/6 datetime的有效时间范围1753/1/1~9999/12/31 2:精准度上 smalldatetime只精准到分,而datetime则可精准到3位的毫秒。 3:存储空间上 smalldatetime占用4个字节,前2个字节存储base date(1900年1月1日)之后的天数。后2个字节存储午夜后的分钟数。 datetime占用8个字节,前4个字节存储base date(即1900年1月1日)之前或之后的天数,后4个字节存储午夜后的毫秒数 Oracle生成流水号函数(5位流水号)
CREATE OR REPLACE FUNCTION fn_no_make(v_type VARCHAR2, v_number_col VARCHAR2, v_table_name VARCHAR2) /* * 参数说明: * v_type: 编码前缀 * v_number_col:编码所在列名 * v_table_name:编码所在表名 */ RETURN VARCHAR2 IS v_old_no VARCHAR2(50); --原编码 v_old_num NUMBER; -- 原编码后五位编号 v_new_num VARCHAR2(10); --新编码后五位编号 v_maked_no VARCHAR2(50); --新编码 v_date_no VARCHAR2(20); --当前日期编号 v_sql VARCHAR2(4000); BEGIN v_sql := 'SELECT MAX(' || v_number_col || ') FROM ' || v_table_name; EXECUTE IMMEDIATE v_sql INTO v_old_no; v_sql := 'SELECT SUBSTR(TO_CHAR(SYSDATE,''YYMMDD''), 1, 6) AS DATE_NO FROM DUAL'; EXECUTE IMMEDIATE v_sql INTO v_date_no; v_old_num := to_number(substr(v_old_no, 11, 5)); v_new_num := to_char(v_old_num + 1); WHILE length(v_new_num) < 5 LOOP v_new_num := '0' || v_new_num; END LOOP; IF v_old_no IS NULL OR substr(v_old_no, 5, 6) <> v_date_no THEN v_maked_no := v_type || v_date_no || '00001'; ELSE v_maked_no := v_type || v_date_no || v_new_num; END IF; RETURN(v_maked_no); EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLERRM); END fn_no_make; --调用 --SELECT fn_no_make(v_type=>'', v_number_col=>'SEQNO_SELF',v_table_name=>'I_YCSQJFYJS') AS SEQNO_SELF FROM DUAL;
1.数据库导入,导出命令 数据导出: a. 将数据库TEST完全导出,用户名system 密码manager 导出到D:\daochu.dmp中 exp test/test@ORACLE_192.168.28.1 file=d:\daochu.dmp full=y b. 将数据库中system用户与sys用户的表导出 exp test/test@ORACLE_192.168.28.1 file=d:\daochu.dmp owner=(system,sys) 数据导入: a 将D:\daochu.dmp 中的数据导入 TEST数据库中。 imp dev/dev@ORACLE_192.168.28.2 file=d:\daochu.dmp imp dev/dev@ORACLE_192.168.28.2 full=y file=file= d:\data\newsmgnt.dmp ignore=y 上面可能有点问题,因为有的表已经存在,然后它就报错,对该表就不进行导入。 在后面加上 ignore=y 就可以了。 b 将d:\daochu.dmp中的表table1 导入 imp dev/dev@TEST file=d:\daochu.dmp tables=(table1) 2.数据库表中Clob,Blob 导入导出命令 exp 数据库用户名/密码@配置名称 file=输出文件路径 log=日志文件路径 tables=(数据库表名) query=\"查询条件\" imp 数据库用户名/密码@配置名称 file=输入文件路径 log=日志文件路径 tables=(数据库表名) ignore=y exp test/test@ORACLE_192.168.28.1 file=c:\11.dmp log=c:\11.log tables=(table1) query=\"where createdby='sysadmin' and to_char(createtime,'YYYY-MM-DD')='2012-05-17'\" imp dev/dev@ORACLE_192.168.28.2 file=c:\11.dmp log=c:\121.log tables=(table1) ignore=y 用cmd.exe 执行就可以,注意的地方就是query 地方 \" 先执行exp 后执行imp
二、需求完成(参考一)
流水号格式改为20170215 1234567(年月日+7位数字),依次递增,每月1号后7位重置为0000001
CREATE OR REPLACE FUNCTION fn_no_make(v_type VARCHAR2, v_number_col VARCHAR2, v_table_name VARCHAR2) /* * 参数说明: * v_type: 编码前缀 * v_number_col:编码所在列名 * v_table_name:编码所在表名 */ RETURN VARCHAR2 IS v_old_no VARCHAR2(50); --原编码 v_old_num NUMBER; -- 原编码后五位编号 v_new_num VARCHAR2(10); --新编码后五位编号 v_maked_no VARCHAR2(50); --新编码 v_date_no VARCHAR2(20); --当前日期编号 v_start_no VARCHAR2(20);--流水号重新计算(按月份) v_type_len INT; --编码前缀 长度 v_sql VARCHAR2(4000); BEGIN --编码前缀 长度 int v_sql := 'select decode(length('''||v_type||'''),NULL,0,length('''||v_type||''')) from DUAL'; EXECUTE IMMEDIATE v_sql INTO v_type_len; --取最大流水号的值 IF v_type_len=0 THEN v_sql := 'SELECT MAX(' || v_number_col || ') FROM ' || v_table_name ||' WHERE 1=1 AND LENGTH('||v_number_col||')=15'; EXECUTE IMMEDIATE v_sql INTO v_old_no; ELSE v_sql := 'SELECT MAX(' || v_number_col || ') FROM ' || v_table_name || ' WHERE 1=1 AND SUBSTR(' || v_number_col || ',1,'||v_type_len||')='''||v_type||''' '; EXECUTE IMMEDIATE v_sql INTO v_old_no; END IF; --当前日期编号 v_sql := 'SELECT SUBSTR(TO_CHAR(SYSDATE,''YYYYMMDD''), 1, 8) AS DATE_NO FROM DUAL'; EXECUTE IMMEDIATE v_sql INTO v_date_no; --当前年月编号 v_sql := 'SELECT SUBSTR(TO_CHAR(SYSDATE,''YYYYMMDD''), 1, 6) AS START_NO FROM DUAL'; EXECUTE IMMEDIATE v_sql INTO v_start_no; v_old_num := to_number(substr(v_old_no,v_type_len+9, 7)); v_new_num := to_char(v_old_num + 1); WHILE length(v_new_num) < 7 LOOP v_new_num := '0' || v_new_num; END LOOP; IF v_old_no IS NULL OR substr(v_old_no, v_type_len+1, 6) <> v_start_no THEN v_maked_no := v_type || v_date_no || '0000001'; ELSE v_maked_no := v_type || v_date_no || v_new_num; END IF; RETURN(v_maked_no); EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLERRM); END fn_no_make; --调用 --BEGIN --dbms_output.put_line(fn_no_make(v_type=>'A', v_number_col=>'SEQNO_SELF',v_table_name=>'I_YCSQJFYJS')); --END; --SELECT fn_no_make(v_type=>'', v_number_col=>'SEQNO_SELF',v_table_name=>'I_YCSQJFYJS') AS SEQNO_SELF FROM DUAL;
参考:Oracle生成流水号函数