- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Oracle学习记录之使用自定义函数和触发器实现主键动态生成由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
很早就想自己写写Oracle的函数和触发器,最近一个来自课本的小案例给了我这个机会。现在把我做的东西记录下来,作为一个备忘或者入门的朋友们的参考.
案例介绍:
招投标管理系统(数据库设计)。 数据表有以下两张: 招标书(招标书编号、项目名称、招标书内容、截止日期、状态)。 投标书(投标书编号、招标书编号、投标企业、投标书内容、投标日期、报价、状态)。 “招标书编号”为字符型,编号规则为 ZBYYYYMMDDNNN, ZB是招标的汉语拼音首字母,YYYYMMDD是当前日期,NNN是三位流水号。 “投标书编号”为字符型,编号规则为TB[11位招标书编号]NNN.
经过分析,我们可以得知两张表的关系。我们先创建数据结构,比如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
CREATE
TABLE
TENDER
(
TENDER_ID VARCHAR2(50)
PRIMARY
KEY
,
PROJECT_NAME VARCHAR2(50)
NOT
NULL
UNIQUE
,
CONTENT BLOB,
END_DATE
DATE
NOT
NULL
,
STATUS
INTEGER
NOT
NULL
);
CREATE
TABLE
BID
(
BID_ID VARCHAR2(50)
PRIMARY
KEY
,
TENDER_ID VARCHAR2(50)
NOT
NULL
,
COMPANY VARCHAR2(50)
NOT
NULL
,
CONTENT BLOB,
BID_DATE
DATE
NOT
NULL
,
PRICE
INTEGER
NOT
NULL
,
STATUS
INTEGER
NOT
NULL
);
ALTER
TABLE
BID
ADD
CONSTRAINT
FK_BID_TENDER_ID
FOREIGN
KEY
(TENDER_ID)
REFERENCES
TENDER(TENDER_ID);
|
然后是生成招标的函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
CREATE
OR
REPLACE
FUNCTION
"createZBNo"
RETURN
VARCHAR2
AS
hasCount NUMBER(11,0);
lastID VARCHAR2(50);
lastTime VARCHAR2(12);
lastNo NUMBER(3,0);
curNo NUMBER(3,0);
BEGIN
-- 查询表中是否有记录
SELECT
"COUNT"
(TENDER_ID)
INTO
hasCount
FROM
TENDER;
IF hasCount > 0
THEN
-- 查询必要信息
SELECT
TENDER_ID
INTO
lastID
FROM
TENDER
WHERE
ROWNUM = 1
ORDER
BY
to_number(to_char(scn_to_timestamp(ORA_ROWSCN),
'yyyyMMddhh24mmss'
),
'99999999999999'
)
DESC
;
SELECT
"SUBSTR"
(lastID, 3, 8)
INTO
lastTime
FROM
dual;
-- 分析上一次发布招标信息是否是今日
IF (
"TO_CHAR"
(SYSDATE,
'YYYYMMDD'
) = lastTime)
THEN
SELECT
"TO_NUMBER"
(
"SUBSTR"
(lastID, 11, 13),
'999'
)
INTO
lastNo
FROM
dual;
-- 如果是今日且流水号允许新增招标信息
IF lastNo < 999
THEN
SELECT
lastNo + 1
INTO
curNo
FROM
dual;
RETURN
'ZB'
||lastTime||
"LPAD"
(
"TO_CHAR"
(curNo), 3,
'0'
);
END
IF;
-- 流水号超出
RETURN
'NoOutOfBounds!Check it!'
;
END
IF;
-- 不是今日发布的招标信息,今日是第一次
RETURN
'ZB'
||
"TO_CHAR"
(SYSDATE,
'YYYYMMDD'
)||
'001'
;
END
IF;
-- 整个表中的第一条数据
RETURN
'ZB'
||
"TO_CHAR"
(SYSDATE,
'YYYYMMDD'
)||
'001'
;
END
;
|
然后是投标书的编号生成函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
CREATE
OR
REPLACE
FUNCTION
"createTBNo"
(ZBNo
IN
VARCHAR2)
RETURN
VARCHAR2
AS
hasCount NUMBER(11,0);
lastID VARCHAR2(50);
lastNo NUMBER(3,0);
curNo NUMBER(3,0);
BEGIN
-- 查看是否已经有了对于该想招标的投标书
SELECT
"COUNT"
(BID_ID)
INTO
hasCount
FROM
BID
WHERE
BID_ID
LIKE
'TB'
||ZBNo||
'___'
AND
ROWNUM = 1
ORDER
BY
to_number(to_char(scn_to_timestamp(ORA_ROWSCN),
'yyyyMMddhh24mmss'
),
'99999999999999'
)
DESC
;
IF hasCount > 0
THEN
-- 有了
SELECT
BID_ID
INTO
lastID
FROM
BID
WHERE
BID_ID
LIKE
'TB'
||ZBNo||
'___'
AND
ROWNUM = 1
ORDER
BY
to_number(to_char(scn_to_timestamp(ORA_ROWSCN),
'yyyyMMddhh24mmss'
),
'99999999999999'
)
DESC
;
SELECT
"TO_NUMBER"
(
"SUBSTR"
(lastID, 16,18),
'999'
)
INTO
lastNo
FROM
dual;
-- 流水号没超出
IF lastNo < 999
THEN
SELECT
lastNo + 1
INTO
curNo
FROM
dual;
RETURN
'TB'
||ZBNo||
"LPAD"
(
"TO_CHAR"
(curNo),3,
'0'
);
END
IF;
RETURN
'NoOutOfBounds!Check it!'
;
END
IF;
-- 没有投标书对该招标书
RETURN
'TB'
||ZBNo||
'001'
;
END
;
|
然后在两个表中注册触发器,当新增数据的时候动态生成编号! 。
招标书触发器,用于动态生成招标书编号:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
CREATE
OR
REPLACE
TRIGGER
newTender
BEFORE
INSERT
ON
TENDER
FOR
EACH ROW
BEGIN
-- 如果生成编号失败
IF (LENGTH(
"createZBNo"
) <> 13)
THEN
-- 此处根据我的提示信息报错可以直接如下操作
-- :NEW.TENDER_ID := NULL;
RAISE_APPLICATION_ERROR(-20222,
"createZBNo"
);
END
IF;
-- 如果生成编号成功,将编号注入查询语句中
:NEW.tender_id :=
"createZBNo"
;
END
;
|
然后是投标书的触发器:
1
2
3
4
5
6
7
8
9
10
11
|
CREATE
OR
REPLACE
TRIGGER
newBid
BEFORE
INSERT
ON
BID
FOR
EACH ROW
BEGIN
IF (LENGTH(
"createTBNo"
(:NEW.TENDER_ID)) <> 18)
THEN
RAISE_APPLICATION_ERROR(-20222,
"createTBNo"
(:NEW.TENDER_ID));
END
IF;
:NEW.BID_ID :=
"createTBNo"
(:NEW.TENDER_ID);
END
;
|
然后插入数据测试吧:
。
。
以上只是个人的一些观点,如果您不认同或者能给予指正和帮助,请不吝赐教.
最后此篇关于Oracle学习记录之使用自定义函数和触发器实现主键动态生成的文章就讲到这里了,如果你想了解更多关于Oracle学习记录之使用自定义函数和触发器实现主键动态生成的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我听说过两种数据库架构。 大师级 主从 master-master不是更适合现在的web吗,因为它就像Git一样,每个单元都有整套数据,如果一个宕机也无所谓。 主从让我想起了 SVN(我不喜欢它),你
我们当前将 MySQL 配置为支持故障转移:Site1 Site2。当它们被设置为主/主时。在给定时间点,应用程序服务器仅主动写入一个站点。我们想要设置一个新的故障转移站点。然后我们将拥有 Site
我听说过两种数据库架构。 大师-大师 主从 master-master 不是更适合当今的网络吗,因为它就像 Git,每个单元都有整套数据,如果其中一个发生故障,也没关系。 主从让我想起 SVN(我不喜
我正在创建一个标记为类别的表,其中主类别(父列)包含 0,子类别包含父类别的 ID。我听说这叫引用。我的问题:这张表的结构正确吗?或者是否有更好的方法,例如实现遍历树或类似方法? CREATE TAB
我正在阅读一份关于 C++ 与 C 的文档。该文档说与 C 相比,C++ 编写得非常紧凑。一个例子是,C 允许 main() 函数类型为 void。另一方面,C++ 不允许这样做,他给出了标准中的以下
C main函数和Java main函数有什么区别? int main( int argc, const char* argv[] ) 对比 public static void main(Strin
我一直摸不着头脑,但运气不好。设计器有一个包含 3 栏的站点、两个侧边栏和一个主要内容区域。 专为桌面设计,左栏、主要内容、右栏。但是,在较小的设备上,我们希望首先堆叠主要内容。 所以通常情况下,你可
我一直在阅读有关 Jenkins 主/从配置的信息,但我仍然有一些问题: 是不是真的没有像 Jenkins 主站那样安装和启动从站 Jenkins?我假设我会以相同的方式安装一个主 Jenkins 和
据我了解,Viemodel中MVVM背后的概念包括业务逻辑和/或诸如暴露于 View 的数据的主/明细关系之类的事物 因此,正如我发现的那样,有很多ORM生成器,例如模型的telerik a.o以及另
我们有一个群集,其中包含3个主分区,每个主分区有2个副本。主/副本分片的总文档数相同;但是,对于同一查询/文档,我们得到3个不同的分数。当我们将preference = primary添加为查询参数时
我有一个非常大/旧/长时间运行的项目,它使用相对于启动目录的路径访问文件资源(即应用程序仅在从特定目录启动时才工作)。当我需要调试程序时,我可以从 eclipse 启动它并使用“运行配置”->->“工
谁能向我解释一下为什么我在这段代码上遇到段错误?我一直试图弄清楚这一点,但在各种搜索中却一无所获。当我运行代码而不调用 main(argc, argv) 时,它会运行。 Slave 仅将 argv 中
使用 xcode 中的默认项目作为主从应用程序,如果我在折叠委托(delegate)中放置 print 调试语句,当我旋转设备时它似乎永远不会被触发(事实上我永远无法触发它)。 我编辑的代码位于 Ap
是否有任何产品可以使 mysql 主/从故障转移过程更容易?一些可以自动发生的事情,而不是手动修复它。 最佳答案 [...稍后...;) 你所说的“更容易”是什么?MySQL 有很多解决方案: MyS
我有两个 mysql 数据库。我想做主/主复制。 复制以一种方式进行。然而,反过来说却不然。该错误表明它无法与用户“test@IPADDRESS”连接。 如何将用户名更改为 repl?从未进行过测试,
我正在尝试在 MySQL 中运行以下查询: GRANT REPLICATION SLAVE ON *.* TO 'replication'@’10.141.2.%’ IDENTIFIED BY ‘sl
我正在尝试使用 Android 提供的主/详细流程模板创建一个应用程序,并且我正在尝试将多个操作栏菜单项添加到操作栏的主要部分和详细信息部分。这就是我要实现的目标: (来源:softwarecrew.
我正在寻找一个跨平台的 C++ master/worker 库或工作队列库。一般的想法是我的应用程序将创建某种任务或工作对象,将它们传递给工作主机或工作队列,这将依次在单独的线程或进程中执行工作。为了
我似乎看到很多人在他们的 MySQL 模式中任意分配大尺寸的主/外键字段,例如 INT(11) 甚至 WordPress 使用的 BIGINT(20)。 如果我错了,请纠正我,但即使是 INT(4)
如果我有一个可以与多个键相关联的用户,正确的表设置应该是: 一个表有两列,例如: UserName | Key 没有主键且用户可以有多行,或者: 具有匹配标识符的两个表 Table 1 Us
我是一名优秀的程序员,十分优秀!