oracle - 在oracle中触发以防止插入重复数据
问题描述
我正在学习 Oracle,但遇到了问题。我有我的“聊天”表:
CREATE TABLE chat (
id_chat NUMBER,
id_user NUMBER,
start_chat DATE,
end_chat DATE
);
现在,我创建了一个触发器,这样如果旧的触发器已经使用相同的 id_user 注册,它就不允许我输入“聊天”。这是我的触发器:
create or replace trigger distChat
before insert on Chat
for each row
begin
if :new.id_user = :old.id_user then
Raise_Application_Error(-20099,'YOU CAN'T INSERT DUPLICATED DATA.');
end if;
end distChat;
但它仍然允许我使用相同的用户代码输入聊天。任何改进我的触发器的帮助或建议都不起作用。
谢谢你。
解决方案
不要使用触发器。
两个原因:
- Oracle 提供了防止重复的机制
- 触发器很昂贵,并且需要维护另一个数据库对象
做这个
ALTER table CHAT ADD CONSTRAINT xpk_chat PRIMARY KEY ( ID_CHAT );
我不知道您的数据模型,但我认为您希望 ID_CHAT 来区分聊天。如果您为 ID_USER 执行此操作,那么一个用户永远不会有多个聊天......谁会想要使用该系统?如果我错了,只需更改上面 ALTER 命令中引用的列。
现在,您的表将有一个约束来防止 ID_CHAT 列上的重复值。这称为主键(文档)
此外,您将拥有一个 INDEX,因此通过 ID 值查询您的 CHAT 可能会更快。
PS你的触发器没有做你想做的事。如果您要使用触发器来执行此操作,则需要在 :new.id_user in (select distinct id_user from chat) 时引发异常......所以基本上如果在表中已经找到导致 INSERT 的 ID,就会例外。PK 约束的美妙之处在于,数据库为您执行此操作。
推荐阅读
- node.js - 无法在 Node.js 中解析 HTTP 响应正文
- java - 未选中的方法 'sort(List
)' 在 Java 11 中使用泛型调用 - sql - 如何解决 db2 代码:-104,SQL 状态:42601
- html - 如何在不使用背景图像属性的情况下覆盖图像英雄?
- javascript - 使用基于标题搜索的 JavaScript 修改 JSON 对象
- highcharts - 如何更改highchart中区域多边形的线宽?
- amazon-web-services - 应用程序负载均衡器 AWS 的 400 握手错误(Flask 和 Socket.io)
- tiles - 将 rasterize=True 与 datashader 一起使用时,如何在 count=0 的情况下获得透明度以查看底层图块?
- reactjs - 避免使用 Styled Components 和 Typescript 传递 props
- sql - 如何在 SQL 中每 5 秒获取一次数据?