Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >关于trigger过滤最大值的问题(54天)

关于trigger过滤最大值的问题(54天)

作者头像
jeanron100
发布于 2018-03-13 10:33:11
发布于 2018-03-13 10:33:11
8580
举报

今天碰到一个问题,开发有一个比较紧的需要,想问问我数据库这边能不能帮上忙。 如果开发那边来做,需要改代码,如果数据库这边能临时支持,代码就可以多做些测试,然后再打补丁了。 需求的情况大体是这样:有一个表的字段是number(11,4),意味着数据保持4为精度,总共长度支持11位,最大值位9999999.9999 如果超过了那个最大值(比如99999999,有8个9),想在update语句update之前能够把那个值改成9999999就可以了。 听起来好像可以使用trigger来做。简单做了个测试。 新建一个表,字段last_threshold的数据类型为number(11,4) SQL> create table test_number(last_threshold number(11,4),content varchar2(100)); Table created. 然后插入一些数据,可以看到,我插入的小数点后是5个9,也可以插入。 SQL> insert into test_number values(1.99999,''); 1 row created. SQL> insert into test_number values(9999999.9999,'a'); 1 row created. SQL> insert into test_number values(9999999.9998,'b'); 1 row created. SQL> insert into test_number values(9.999999,'c'); 1 row created. SQL> commit; Commit complete. 查看插入的数据情况,看到现实是下面的样子,有些疑惑,全都自作主张做了4舍5入了。 select *from test_number; LAST_THRESHOLD CONTENT -------------- ------------------------------ 2 10000000 a 10000000 b 10 c 设置一下精度 SQL> col last_threshold format 99999999.99999 SQL> / LAST_THRESHOLD CONTENT --------------- ------------------------------ 2.00000 9999999.99990 a 9999999.99980 b 10.00000 c SQL> col last_threshold format 9999999.9999 SQL> / LAST_THRESHOLD CONTENT -------------- ------------------------------ 2.0000 9999999.9999 a 9999999.9998 b 10.0000 c 想直接创建一个语句级的trigger,可惜失败了。 SQL> CREATE TRIGGER maxvalue_test before UPDATE of LAST_THRESHOLD ON test_number begin dbms_output.put_line(:old.last_threshold); dbms_output.put_line(:new.last_threshold); end; / 2 3 4 5 6 7 8 CREATE TRIGGER maxvalue_test * ERROR at line 1: ORA-04082: NEW or OLD references not allowed in table level triggers 重头再来,先写一个trigger来测试一下是不是好使。 SQL> CREATE TRIGGER maxvalue_test before UPDATE of LAST_THRESHOLD ON test_number for each row begin dbms_output.put_line(:old.last_threshold); dbms_output.put_line(:new.last_threshold); end; / 2 3 4 5 6 7 8 Trigger created. SQL> update test_number set last_threshold=9293.9999 where content='c'; 10 9293.9999 1 row updated. SQL> rollback; Rollback complete. SQL> select *from test_number; LAST_THRESHOLD CONTENT -------------- ------------------------------ 2.0000 9999999.9999 a 9999999.9998 b 10.0000 c 可以看到行级的触发器做了多少的处理。 验证了3条记录。 SQL> update test_number set last_threshold=9999 where content is not null; 9999999.9999 9999 9999999.9998 9999 10 9999 3 rows updated. SQL> commit; Commit complete. SQL> select *from test_number; LAST_THRESHOLD CONTENT -------------- ------------------------------ 2.0000 9999.0000 a 9999.0000 b 9999.0000 c 尝试改成最大值 SQL> update test_number set last_threshold=9999999.9999 where content is null; 2 9999999.9999 1 row updated. SQL> commit; Commit complete. SQL> select *from test_number; LAST_THRESHOLD CONTENT -------------- ------------------------------ 9999999.9999 9999.0000 a 9999.0000 b 9999.0000 c 然后开始正式的测试。 drop trigger maxvalue_test; CREATE TRIGGER maxvalue_test before UPDATE of LAST_THRESHOLD ON test_number for each row begin dbms_output.put_line('old: '||:old.last_threshold); dbms_output.put_line('new: '||:new.last_threshold); if (:new.last_threshold>9999999) then :new.last_threshold:=9999999; dbms_output.put_line('change to: '||:new.last_threshold); end if; end; / 但是测试的时候发现还是不行。 SQL> update test_number set last_threshold=99999999.9999 where content is null; update test_number set last_threshold=99999999.9999 where content is null * ERROR at line 1: ORA-01438: value larger than specified precision allowed for this column drop trigger maxvalue_test; 那改成合理范围的值呢。比如改成100. CREATE TRIGGER maxvalue_test before UPDATE of LAST_THRESHOLD ON test_number for each row begin dbms_output.put_line('old: '||:old.last_threshold); dbms_output.put_line('new: '||:new.last_threshold); if (:new.last_threshold<9999999) then :new.last_threshold:=100; dbms_output.put_line('change to: '||:new.last_threshold); end if; end; / SQL> update test_number set last_threshold=999999.9 where content is null; old: 999999.9999 new: 999999.9 change to: 100 1 row updated. SQL> commit; Commit complete. SQL> select *from test_number; LAST_THRESHOLD CONTENT -------------- ------------------------------ 100.0000 9999.0000 a 9999.0000 b 9999.0000 c 可以看到trigger的数据校验一定是在数据类型在合理范围之内。不过反过来一想也是合情合理。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2014-04-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 杨建荣的学习笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
PL/SQL 联合数组与嵌套表
      通常情况下,在PL/SQL中,处理单行单列的数据可以使用标量变量,而处理单行多列的数据则使用PL/SQL记录是不错的选择。单列多行数据 则由联合数组或嵌套表来完成,其特点是类似于单列数据库表。在Oracle 9i 之前称为PL/SQL索引表,9i 之后称之为联合数组。嵌套表也是集合 类型中的一种,下面分别介绍这两种集合数据类型的使用方法。
Leshami
2018/08/14
1.4K0
通过闪回事务查看数据dml的情况 (r2笔记69天)
昨天有一个网友问我,怎么能够查询一个表中最后一条插入的记录,我大概回复了,可以通过闪回事务来实现,但是得看什么时候插入的数据,也需要一定的运气。 如果通过闪回事务来得到对应的undo_sql,可能多个dml语句对应一个事务,所以我们需要得到的是一个完整的事务的信息,里面包括对应的Undo_sql,这样才算得到比较完整的sql语句。 我在本地自己做了一个测试。 创建一个test表,然后插入一些记录,然后尝试修改一些数据。 SQL> DROP TABLE TEST; Table dropped. SQL>
jeanron100
2018/03/14
5350
ORA-06502 assigning values from SQL to PL/SQL variables
    最近SQL查询返回的结果给PL/SQL变量出现ORA-06502错误。这个错误的描述是ORA-06502: PL/SQL: numeric or value error: character string buffer too small. 显而易见的是字符变量定义的长度不够,加到20,到100,继续06502,汗,咋回事呢?
Leshami
2018/08/14
7870
深入解析:你听说过Oracle数据库的更新重启动吗?
杨廷琨 云和恩墨高级咨询顾问, ITPUB Oracle 数据库管理版版主 ,人称 “杨长老”,十数年如一日坚持进行 Oracle 技术研究与写作,号称 “Oracle 的百科全书”。迄今已经在自己的博客上发表了超过 3000 篇技术文章。2010 年,与 Eygle 共同主编出版了《Oracle DBA 手记》一书,2007 年被 Oracle 公司授予 ACE 称号。
数据和云
2018/07/27
7140
深入解析:你听说过Oracle数据库的更新重启动吗?
【DB笔试面试811】在Oracle中,什么是闪回事务查询(Flashback Transaction Query)?
在Oracle中,什么是闪回事务查询(Flashback Transaction Query)?
AiDBA宝典
2020/06/04
6440
ORA-60死锁的实验
SQL> create table tbl_ora_60 (      id number(5),      name varchar2(5)      ); SQL> insert into tbl_ora_60 values(1, 'a'); 1 row created. SQL> insert into tbl_ora_60 values(2, 'b'); 1 row created. SQL> commit; Commit complete. SQL> select * from tbl_ora_60;         ID NAME ---------- -----          1 a          2 b 实验开始 Session1: SQL> update tbl_ora_60 set name='c' where id=1; 1 row updated. Session2: SQL> update tbl_ora_60 set name='d' where id=2; 1 row updated. Session1: SQL> update tbl_ora_60 set name='e' where id=2; hang住 Session2: SQL> update tbl_ora_60 set name='f' where id=1; hang住 此时,Session1: SQL> update tbl_ora_60 set name='e' where id=2; update tbl_ora_60 set name='e' where id=2        * ERROR at line 1: ORA-00060: deadlock detected while waiting for resource 说明: Session1                                            Session2 获取id=1的资源锁                                                         获取id=2的资源锁 等待id=2的资源锁                                                         等待id=1的资源锁 id=2的SQL报ORA-60,自动rollback 1、因为id=2的资源锁是Session2先获取的,因此Oracle会自动rollback产生死锁时后需要资源锁的SQL,Session1的更新id=2操作被rollback。 2、从中可以发现,真正报ORA-60错误的SQL获取的资源(此例中id=2),并不是触发死锁产生的那个资源(此例中id=1),此例用的是同一个表的不同行,对不同表的相同行也如此,也可以解释之前夜维出现ORA-60时显示的SQL之间表是不同的原因,因为夜维执行的某个表更新与当前应用执行的某个表更新之间存在互锁的情况,因此可能导致夜维SQL报ORA-60或应用报ORA-60的错误。 此时,Session1: SQL> select * from tbl_ora_60;         ID NAME ---------- -----          1 c          2 b 说明:此处可以证明产生报错后,Oracle自动执行的rollback操作是基于单条SQL,不是整个事务的,所以这里只有id=2的记录被rollback,id=1的执行仍正常。 Session2: SQL> update tbl_ora_60 set name='f' where id=1; hang住 继续,Session1: SQL> commit; Commit complete. Session2: SQL> update tbl_ora_60 set name='f' where id=1; 1 row updated. Session1: SQL> select * from tbl_ora_60;         ID NAME ---------- -----          1 c          2 b 只有id=1更新成功。 Session2: SQL> select * from tbl_ora_60;         ID NAME ---------- -----          1 f          2 d id=1和id=2都更新成功,但未COMMIT。 SQL> commit; Commit complete. Sess
bisal
2019/01/29
5000
SQL在DBA手里-变装篇(9亿+表自关联)
在每天的AWR报告巡检中发现一性能SQL情况,发现 db file sequential read等待事件消耗在User I/O,再看SQL有个UPDATE语句16.81%的IO消耗,然后再查看这张表的数据达到了9亿+,大表还自关联,头痛来袭。
布衣530
2025/01/26
921
SQL在DBA手里-变装篇(9亿+表自关联)
Oracle 触发器详解(trigger)「建议收藏」
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/157665.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/14
4K0
PL/SQL变长数组
  PL/SQL变长数组时PL/SQL集合数据类型中的一种,其使用方法与PL/SQL嵌套表大同小异,唯一的区别则是变长数组的元素的最大个数是有限 制的。也即是说变长数组的下标固定下限等于1,上限可以扩展。下面给出具体的描述及其使用方法。
Leshami
2018/08/14
9340
ORACLE触发器具体解释
触发器是很多关系数据库系统都提供的一项技术。在ORACLE系统里,触发器类似过程和函数,都有声明,运行和异常处理过程的PL/SQL块。
全栈程序员站长
2022/07/13
1.2K0
Oracle 20c 新特性:区块链表提供基于 Oracle 的集中式区块应用
导读:区块链表是仅插入表(Only-Insert),将行组织成许多链。通过使用加密哈希将链中除第一行之外的每一行链接到链中的前一行。
数据和云
2020/02/24
8220
Oracle 20c 新特性:区块链表提供基于 Oracle 的集中式区块应用
Oracle PL/SQL入门语法点
PL_SQL:带有分支和循环,面向过程 匿名块: declare(可选,声明各种变量和游标的地方) begin(必要的,从此开始执行) exception(抓取到异常后执行的) end; [sql] view plaincopy set serveroutput on;(默认是关闭) --最简单的PL/SQL语句块 begin dbms_output.put_line('HelloWorld!'); end; --最简单的语句块 declare v_name varchar2(20); be
java干货
2021/02/19
5050
PL/SQL --> INSTEAD OF 触发器
INSTEAD OF 触发器常用于管理编写不可更新的视图,INSTEAD-OF触发器必须是行级的。
Leshami
2018/08/07
6450
NULL 值与索引(一)
    NULL值是关系数据库系统布尔型(true,false,unknown)中比较特殊类型的一种值,通常称为UNKNOWN或空值,即是未知的,不确定的。由于 NULL存在着无数的可能,因此NULL值也不等于NULL值,所以与NULL值相关的操作同样都为NULL值。正是基于这样一个特性,对于NULL值列上的B 树索引导致了is null/is not null不走索引的情形,下面描述了NULL值与索引以及索引NULL列上的执行计划,如何使得NULL值走索引的情形。 注:本文仅仅讨论的是B树索引上的NULL值,位图索引不在此范围之内。 一、null值与索引的关系
Leshami
2018/08/14
1.6K0
一道SQL考题的思考
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
bisal
2019/12/10
3950
一道SQL考题的思考
Oracle数据库之第四篇
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
海仔
2019/10/22
9810
变与不变: Undo构造一致性读的例外情况
嘉年华听了恩墨学院的一个主题:《重现ORA-01555 细说Oracle 12c Undo数据管理》,吕星昊老师介绍了UNDO的概念以及ORA-1555的产生,并介绍了12c以来Oracle的UNDO相关的新特性。
数据和云
2018/12/18
4340
变与不变: Undo构造一致性读的例外情况
plsql编程语言_编程语言有哪些
–pl/sql编程语言 –pl/sql编程语言是对sql语言的扩展,是的sql语言具有过程化编程的特性 –pl/sql编程语言比一般的过程化编程语言,更加灵活高效 –pl/sql编程语言主要用来编写存储过程和存储函数等。
全栈程序员站长
2022/09/27
14.1K0
对比 PL/SQL profiler 剖析结果
      使用PL/SQL PROFILER 剖析PL/SQL代码是快速定位PL/SQL代码段最有效的方法。在上一篇文章使用PL/SQL PROFILER 定位 PL/SQL 瓶颈代码中描述了安装PROFILER,并给出了剖析的示例。本文参照了Tom大师的代码来对比剖析前后的性能并附上其代码。
Leshami
2018/08/13
5860
关于字符串匹配查找的总结(43天)
判断一个字符型字段中出现某个字符超过3次的数据行,如果为了简单达到目的,可以直接使用Like来做, SQL> select content from clob_test where content like '%is%is%is%'; CONTENT -------------------------------------------------------------------------------- this is a test,and it is very useful 但是可能在实际应用中,
jeanron100
2018/03/13
9340
相关推荐
PL/SQL 联合数组与嵌套表
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档