十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
oracle存储过程生成单号
专注于为中小企业提供网站设计、成都做网站服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业林州免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了上1000+企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。
oracle存储过程生成单号,Oracle生成单据编号存储过程的实例代码

旅程1229
转载
关注
0点赞·137人阅读
Oracle生成单据编号存储过程,在做订单类似的系统都可能会存在订单编号不重复,或是流水号按日,按年,按月进行重新编号。
可以参考以下存储过程
CREATE OR REPLACE
procedure Pro_GetBillNO(TypeTable in varchar2,cur_mycursor out sys_refcursor)
as
DReceiptCode varchar2(40);
DReceiptName varchar2(50);
DPrefix1 varchar2(50);
DISO varchar2(50);
DIsAutoCreate varchar2(20);
DPrefix2 varchar2(20);
DPrefix3 varchar2(20);
DDateValue date;
DNO number;
DLength number;
DResetType number;
DSeparator varchar2(20);
DReturnValue varchar2(50);
strSql varchar2(1000);
begin
DReturnValue:='';
select "ReceiptCode","ReceiptName","Prefix1","ISO","IsAutoCreate","Prefix2","Prefix3","DateValue","NO","Length","ResetType","Separator" into
DReceiptCode,DReceiptName,DPrefix1,DISO,DIsAutoCreate,DPrefix2,DPrefix3,DDateValue,DNO,DLength,DResetType,DSeparator from
"SysReceiptConfig" where "ReceiptCode"=TypeTable;
if to_number(DResetType)0
then
if DIsAutoCreate=1 THEN
if DResetType=1 then --
在ORACLE中,单引号有两个作用,一是字符串是由单引号引用,二是转义。单引号的使用是就近配对,即就近原则。而在单引号充当转义角色时相对不好理解
1、从第二个单引号开始被视为转义符,如果第二个单引号后面还有单引号(哪怕只有一个)。 select '''' from dual ----output:' 解释:第二个单引号被作为转义符,第三个单引号被转义,可将sql写成这样更好理解: select ' '' ' from dual ----output:'
2、连接符‘||’导致了新一轮的转义:连接符号‘||’左右的单引号没有任何的关系,除非‘||’是作为字符串的一部分(这在动态SQL中很常见)。
select 'name'||'''' from dual ----output:name' 理解:||后面的作为一个字符串,即前后是',中间又是一个密集型单引号串'',因此第一个为转义功能 select 'name''''' from dual ----output:name'' 理解:第一个和最后一个单引号作为字符串引用符,中间四个单引号两两转义 。
举几个简单例子: 一个单引号,是最正常的情况,比如:'asdfas',这代表一个字符串,显示的内容是 asdfas ; 两个单引号,一般成对出现在一个单引号之内,表示一个单引号之内的单引号,比如 'sdfs''123''dfsdf',这种字符串显示的时候就是 sdfs'123'dfsdf 三个或四个单引号的情况是在一个和两个的情况之上发展出来的,比如'asd'''||输入值||'''',它显示的时候内容就是: asd'输入值'。 (把一对两个单引号分开了,一部分在||之前,一部分在||之后) (后面四个单引号分开看,中间两个是一对--代表一对单引号之内的一个单引号,外边两个是一对--代表一对单引号)
概述
通过实例 全面而深入的分析oralce的基本数据类型及它们的存储方式 以ORACLE G为基础 介绍oralce g引入的新的数据类型 让你对oracle数据类型有一个全新的认识 揭示一些不为人知的秘密和被忽略的盲点 从实用和优化的角度出发 讨论每种数据类型的特点 从这里开始oracle之旅!
第一部份 字符类型
§ char
定长字符串 会用空格来填充来达到其最大长度 最长 个字节
. 新建一个测试表test_char 只有一个char类型的列 长度为
SQL create table test_char(colA char( ));
Table created
. 向这个表中插入一些数据
SQL insert into test_char values( a );
row inserted
SQL insert into test_char values( aa );
row inserted
SQL insert into test_char values( aaa );
row inserted
SQL insert into test_char values( aaaa );
row inserted
SQL insert into test_char values( aaaaaaaaaa );
row inserted
注意 最多只能插入 个字节 否是就报错
SQL insert into test_char values( aaaaaaaaaaa );
insert into test_char values( aaaaaaaaaaa )
ORA : value too large for column PUB_TEST TEST_CHAR COLA (actual: maximum: )
. 使用dump函数可以查看每一行的内部存数结构
SQL select colA dump(colA) from test_char;
COLA DUMP(COLA)
a Typ= Len= :
aa Typ= Len= :
aaa Typ= Len= :
aaaa Typ= Len= :
aaaaaaaaaa Typ= Len= :
注意 Typ= 表示数据类型的ID Oracle为每一种数据类型都进行了编号 说明char类型的编号是
Len = 表示所在的内部存储的长度(用字节表示) 虽然第一例只存了一个字符 a 但是它还是占用了 个字节的空间
表示内部存储方式 可见oracle的内部存储是以数据库字符集进行存储的
正好是字符a的ASCII码
可以使用chr函数把ASCII码转成字符
SQL select chr( ) from dual;
CHR( )
a
要想知道一个字符的ASCII码 可以使用函数ascii
SQL select ascii( a ) from dual;
ASCII( A )
正好是空格的ascii码值
Char类型是定长类型 它总会以空格来填充以达到一个固定宽度
使用char类型会浪费存储空间
Oracle的数据类型的长度单位是字节
SQL select dump( 汉 ) from dual;
DUMP( 汉 )
Typ= Len= :
可见一个汉字在oracle中是占用了两个字节的
英文字母或符号只占用一个字节
Char( )最多可存放 个汉字
§ varchar
是一种变长的字符类型 最多可占用 字节的存储空间
创建一个表 只有一列 类型为varchar 长度为
SQL create table test_varchar( col varchar ( ));
Table created
插入一些数据
SQL insert into test_varchar values( a );
row inserted
SQL insert into test_varchar values( aa );
row inserted
SQL insert into test_varchar values( aaa );
row inserted
SQL insert into test_varchar values( aaaaaaaaaa );
row inserted
SQL insert into test_varchar values( aaaaaaaaaaa );
用dump函数查看每一行的内部存储结构
SQL select col dump(col) from test_varchar;
COL DUMP(COL)
a Typ= Len= :
aa Typ= Len= :
aaa Typ= Len= :
aaaaaaaaaa Typ= Len= :
Typ= 说明varchar 类型在oracle中的类型编号为
Len代表了每一行数据所占用的字节数
后面是具体的存储值
由此可见 varchar 是存多少就占用多少空间 比较节省空间的 不会像char那样用空格填充
§ byte 和char
在 g中 字符类型的宽度定义时 可以指定单位
Byte就是字节
Char就是字符
Varchar ( byte) 长度为 个字节
Varchar ( char) 长度为 个字符所占的长度
Char( byte)长度为 个字节
Char( char) 长度为 个字符所占的长度
一个字符占用多少个字节 是由当前系统采用的字符集来决定的
如一个汉字占用两个字节
查看当前系统采用的字符集
SQL select * from nls_database_parameters where parameter = NLS_CHARACTERSET ;
PARAMETER VALUE
NLS_CHARACTERSET ZHS GBK
如果在定义类型时 不指定单位 默认是按byte 即以字节为单位的
采用char为单位的好处是 使用多字节的字符集
比如 在ZHS GBK字符集中 一个汉字占用两个字节
把数据表的某一列长度定义为可存放 个汉字 通过下面的定义就可以了
Create table test_varchar(col_char varchar ( char));
这样相对简单一些 在数据库表设计时需要注意
继续实验 新建一个表 包含两列 一列采用byte为单位 一列采用char为单位
SQL create table test_varchar (col_char varchar ( char) col_byte varchar ( byte));
Table created
Col_char列 定义为可存放 个字符
Col_byte 列 定义为可存放 个字节的字符
当前的系统采用字符集为ZHS GBK 所以一个字符占两个字节
试着在表中插入一些数据
SQL insert into test_varchar values( a a );
row inserted
SQL insert into test_varchar values( 袁 a );
row inserted
SQL insert into test_varchar values( 袁袁袁袁袁袁袁袁袁袁 aaaaaaaaaa );
row inserted
SQL insert into test_varchar values( 袁袁袁袁袁袁袁袁袁袁 袁袁袁袁袁袁袁袁袁袁 );
insert into test_varchar values( 袁袁袁袁袁袁袁袁袁袁 袁袁袁袁袁袁袁袁袁袁 )
ORA : value too large for column PUB_TEST TEST_VARCHAR COL_BYTE (actual: maximum: )
第一次 在两列中都插入字符a
第二次 在col_char列插入字符 袁 在col_byte插入字符a
第三次 在col_char列中插入 个中文字符 袁 在col_byte插入 个字符a
第四次 在两列中都插入中文字符 袁 时 报错了 第二列长度不够
再看看每一行的存储结构
SQL select col_char dump(col_char) from test_varchar ;
COL_CHAR DUMP(COL_CHAR)
a Typ= Len= :
袁 Typ= Len= :
袁袁袁袁袁袁袁袁袁袁 Typ= Len= :
当我们在col_char列插入 个汉字时 它的长度为
尽管我们在定义的时候是采用varchar ( char)
由此可见 oracle是根据当前数据库采用的字符集 每个字符的所占字节数 X 字段长度来决定了该字段所占的字节数
在本例中 varchar ( char)相当于varchar ( )
不信 我们可以试试看
SQL desc test_varchar ;
Name Type Nullable Default Comments
COL_CHAR VARCHAR ( ) Y
COL_BYTE VARCHAR ( ) Y
当采用多字节的字符集时 定义字段长度还是采用char为单位指定为佳 因为可以避免字段长度的问题
当不知道当前数据库采用的字符集 一个字符占用多少字节时 可以使用lengthb函数
SQL select lengthb( 袁 ) from dual;
LENGTHB( 袁 )
§ char还是varchar
新建一个表 一列为char类型 一列为varchar 类型
SQL create table test_char_varchar(char_col char( ) varchar_col varchar ( ));
Table created
向该表中的两列都插入相关的数据
SQL insert into test_char_varchar values( Hello World Hello World );
row inserted
SQL select * from test_char_varchar;
CHAR_COL VARCHAR_COL
Hello World Hello World
以char_col列为条件查询
SQL select * from test_char_varchar where char_col = Hello World ;
CHAR_COL VARCHAR_COL
Hello World Hello World
以varchar_col列为条件查询
SQL select * from test_char_varchar where varchar_col = Hello World ;
CHAR_COL VARCHAR_COL
Hello World Hello World
似乎char 和varchar类型没有什么两样 再看看下面的语句
SQL select * from test_char_varchar where varchar_col =char_col;
CHAR_COL VARCHAR_COL
这已经看出他们并不一样 这涉及到字符串比较的问题
因为已经发生了隐式转换 在与char列char_col进行比较时 char_col列的内容已经转换成了char( ) 在Hello World后面以空格进行填充了 而varchar_col列并没有发生这种转换
如果要让char_col列与varchar_col列相等 有两种方法
第一种是 使用trim把char_col列的空格去掉
第二种是 使遥rpad把varchar_col列用空格进行填充长度为 的字符
SQL select * from test_char_varchar where trim(char_col) = varchar_col;
CHAR_COL VARCHAR_COL
Hello World Hello World
SQL select * from test_char_varchar where char_col = rpad(varchar_col );
CHAR_COL VARCHAR_COL
Hello World Hello World
如果使用trim函数 如果char_col列上有索引 那么索引将不可用了
lishixinzhi/Article/program/Oracle/201311/17771
是随机分组吗?如果是随机分组可以用分析函数来解决,
先用MOD 5 函数把数据分成五组,然后排序,取rownum
SELECT COL,MOD_GROUP,COL||'-'||ROW_NUMBER() OVER(PARTITION BY MOD_GROUP ORDER BY COL) RN FROM (
SELECT MOD(ROWNUM,5) MOD_GROUP,COL FROM TABLE
)ORDER BY MOD_GROUP
要是订单表中只有订单号是主键,那么你这个肯定实现不了。
可以使用联合主键,这样就没事了。
用 订单号,交易日期做联合主键,建议 交易日期取到分钟,要是取到日的话,可能还会重复
Oracle保存时可以使用序列和触发器完成自动产生编号。
1:创建序列
create sequence orderSeq;
2:创建触发器
CREATEORREPLACETRIGGER order_TRG
BEFOREINSERTORUPDATEOF PD_ID
ON Order
FOREACHROW
BEGIN
IF INSERTING THEN
if :NEW.TypeID then
//计算编号 使用 oderSeq.NEXTVAL
else
//计算编号 使用 oderSeq.NEXTVAL
endif;
SELECT 计算编号 INTO :NEW.orderID FROM DUAL;
ELSE
RAISE_APPLICATION_ERROR(-20020, '不允许更新orderID值!');
ENDIF;