DB2数据库中的序列和触发器??
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DB2数据库中的序列和触发器??相关的知识,希望对你有一定的参考价值。
在DB2数据库中创建表userinfo,给表中的userid字段创建一个序列seq_userinfo,现在需要创建一个触发器实现向表useinfo中添加用户信息时会自动创建userid序列号?实现该功能的SQL语句是什么??
参考技术A Berkeley DB (DB)是一个高性能的,嵌入数据库编程库,和C语言,C++,Java,Perl,Python,php,Tcl以及其他很多语言都有绑定。Berkeley DB可以保存任意类型的键/值对,而且可以为一个键保存多个数据。Berkeley DB可以支持数千的并发线程同时操作数据库,支持最大256TB的数据,广泛用于各种操作系统包括大多数Unix类操作系统和Windows操作系统以及实时操作系统。 2.0版本或以上的Berkeley DB由Sleepycat Software公司开发,并使用基于自由软件许可协议/私有许可协议的双重授权方式提供[1],附有源代码。开发者如果想把Berkeley DB嵌入在私有软件内需要得到Sleepycat公司的许可,若将软件同样遵循GPL发布,则不需许可即可使用。而2.0版本以下的则使用BSD授权,可自由作商业用途。 Berkeley DB最初开发的目的是以新的HASH访问算法来代替旧的hsearch函数和大量的dbm实现(如AT&T的dbm,Berkeley的 ndbm,GNU项目的gdbm),Berkeley DB的第一个发行版在1991年出现,当时还包含了B+树数据访问算法。在1992年,BSD UNIX第4.4发行版中包含了Berkeley DB1.85版。基本上认为这是Berkeley DB的第一个正式版。在1996年中期,Sleepycat软件公司成立,提供对Berkeley DB的商业支持。在这以后,Berkeley DB得到了广泛的应用,成为一款独树一帜的嵌入式数据库系统。2006年Sleepycat公司被Oracle 公司收购,Berkeley DB成为Oracle数据库家族的一员,Sleepycat原有开发者继续在Oracle开发Berkeley DB,Oracle继续原来的授权方式并且加大了对Berkeley DB的开发力度,继续提升了Berkeley DB在软件行业的声誉。Berkeley DB的当前最新发行版本是4.7.25。 值得注意的是DB是嵌入式数据库系统,而不是常见的关系/对象型数据库,对SQL语言不支持,也不提供数据库常见的高级功能,如存储过程,触发器等。 Berkeley DB的体系结构 Berkeley DB以拥有比Microsoft SQL Server和Oracle等数据库系统而言更简单的体系结构而著称。例如,它不支持网络访问—程序通过进程内的API访问数据库。 他不支持SQL或者其他的数据库查询语言,不支持表结构和数据列。 访问数据库的程序自主决定数据如何储存在记录里,Berkeley DB不对记录里的数据进行任何包装,每个记录有且只有两部分:键、值,所以在Berkeley DB的背景下通常用key/data pair指代一个记录。记录和它的键都可以达到4G字节的长度。 尽管架构很简单,Berkeley DB却支持很多高级的数据库特性,比如ACID 数据库事务处理,细粒度锁,XA接口,热备份以及同步复制。 Berkeley DB包含有与某些经典Unix数据库编程库兼容的接口,包括:dbm,ndbm和hsearch。 Berkeley DB的核心数据结构 数据库环境句柄DB_ENV: 每个DB_ENV相当于一个数据库,它包含了数据库全局信息,比如缓冲区大小、以及对事务、日志、锁等子系统的全局配置信息。 数据库句柄结构DB:每个DB相当于关系数据库的一个表,其中存储了很多key/data pair。DB句柄代表了一个包含了若干描述数据库表属性的参数,如数据库访问方法类型、逻辑页面大小、数据库名称等;同时,DB结构中包含了大量的数据库处理函数指针,大多数形式为 (*dosomething)(DB *, arg1, arg2, …)。其中最重要的有open,close,put,get等函数。 数据库记录结构DBT:DB中的记录由关键字和数据构成,关键字和数据都用结构DBT表示。实际上完全可以把关键字看成特殊的数据。结构中最重要的两个字段是 void * data和u_int32_t size,分别对应数据本身和数据的长度。 数据库游标结构DBC:游标(cursor)是数据库应用中常见概念,其本质oracle DB 中的自动增量替代方案
【中文标题】oracle DB 中的自动增量替代方案【英文标题】:Auto increment alternatives in oracle DB 【发布时间】:2013-12-07 17:57:47 【问题描述】:我对 Oracle 比较陌生,过去几个小时一直在浏览网页,但仍然无法找到困扰我的问题的明确答案。
我来自软件工程背景,通过为每个表创建 AI 序列来重复代码的数量让我感到沮丧。无论如何我可以定义一个 AI 函数来获取序列和表的名称,这样我就可以在触发器中调用该函数,还是需要对每个序列进行硬编码?
我目前对我拥有的 12 个表中的每一个都有这样的序列
CREATE OR REPLACE TRIGGER trg_site_addr
BEFORE INSERT OR UPDATE ON site_addr FOR EACH ROW
BEGIN
IF INSERTING THEN
IF :NEW.site_addr_id IS NULL THEN
SELECT seq_site_addr_id.nextval
INTO :NEW.site_addr_id
FROM sys.dual;
END IF;
END IF;
END;
理想情况下,我希望能够做到以下几点
CREATE OR REPLACE TRIGGER trg_site_addr
BEFORE INSERT OR UPDATE ON site_addr FOR EACH ROW
BEGIN
IF INSERTING THEN
IF :NEW.site_addr_id IS NULL THEN
-- Param 1 = sequence name, Parm 2 = table name
auto_increment(seq_site_addr_id, site_addr);
END IF;
END IF;
END;
我将如何去做,任何指针将不胜感激。
亚历克斯。
* 编辑 * 为了消除任何混淆,我想创建一个函数,但我不知道是否可以在函数中嵌入序列然后使用参数,即
CREATE FUNCTION auto_increment( seq_name, table_col_id)
SELECT seq_name.nextval
INTO :NEW.table_col_id
FROM sys.dual;
END;
这样,它将在触发器中为每个表动态创建增量序列,而无需我对每个表的 AI 触发器进行硬编码。
如果这不可能,那么硬编码没什么大不了的,这只是我的一个查询。
【问题讨论】:
您是否尝试过实际的SEQUENCE
?见***.com/questions/7681122/… 和docs.oracle.com/cd/B28359_01/server.111/b28286/…
所以你想创建类似 for 循环的东西?
升级到12c(如果可以的话)并使用identity columns
为什么不对所有表格使用相同的顺序?
“Oracle”的方式是直接在INSERT
语句中调用你的序列:insert into mytable (id, ... ) values (myseq.nextval, ...)
。就我个人而言,我发现这比自动增量列好得多。而且触发器很臭,除非我没有更明智的选择,否则我不会使用它们......
【参考方案1】:
另一种方法是使用一个表来存储其他表的 ID。 喜欢:
对于应用程序的任何表(如客户表),我们都需要执行以下操作:
insert into ID_Table (table_name, current_id) values ('CUSTOMER', 0);
获取新 id 的函数是:
CREATE OR REPLACE FUNCTION fetch_new_id(p_table_name Varchar2) return number
IS
result_value number;
BEGIN
SELECT ID_Tbale.current_id + 1
INTO result_value
FROM ID_Table where trim(upper(ID_Table.table_name)) = trim(upper(p_table_name))
for update;
UPDATE ID_Tbale set current_id = current_id + 1
where trim(upper(ID_Table.table_name)) = trim(upper(p_table_name));
COMMIT;
RETURN result_value ;
-- exception handling, etc
END;
【讨论】:
如果你要走这条路,我认为使用RETURNING
: update id_table set current_id = current_id + 1 where table_name = p_table_name returning current_id into result_value
的单个更新更干净
@gpeche 我故意使用for update
来保持并发性并防止丢失更新。
@Moshen Yedari 我知道,我的意思是,如果你在一个 UPDATE ... RETURNING ...
中完成所有操作,它会更干净,它还保持并发性并通过单个 SQL 语句防止丢失更新。
这个答案让我身体不适。
@clever-idea-widgetry 让我们考虑一下 Oracle 如何在内部实现序列?或者考虑一个不支持自动增量概念的数据库。你的解决方案是什么?【参考方案2】:
我不推荐它,但这样的事情应该或多或少地做你想要的:
CREATE FUNCTION auto_increment(seq_name in varchar2) RETURN NUMBER IS
next_seq number;
BEGIN
-- WARNING: use with care, possible SQL injections?
execute immediate 'select ' || seq_name || '.nextval from dual' into next_seq;
return next_seq
END auto_increment;
-- In trigger code
...
if inserting then
if :new.id is null then
:new.id := auto_increment('myseq');
end if;
end if;
...
最好的方法是在INSERT
语句中嵌入序列调用。如果INSERT
语句无法修改,我只会使用触发器(也许它们是某些第 3 方软件的一部分,假设世界上每个数据库都支持自动增量列)。
【讨论】:
以上是关于DB2数据库中的序列和触发器??的主要内容,如果未能解决你的问题,请参考以下文章