【问题标题】:Create Procedure to Insert row & Return SYS_GUID() PK in Oracle SQL在 Oracle SQL 中创建插入行并返回 SYS_GUID() PK 的过程
【发布时间】:2021-12-23 06:14:07
【问题描述】:

我的团队有两个 Oracle 数据库表 - 一个用于捕获服务调用请求和响应,另一个用于记录某些类型的错误。目前这两个表不相关。他们都使用 DEFAULT SYS_GUID() 在插入时生成他们的 PK - 但其中一个将其存储为 raw(16),另一个存储为 varchar2(50 BYTE)。

我正在创建一个表,其中每个表都有一个 FK,并且通过一致投票,我需要使用 SYS_GUID() 作为 PK。

工作禁止在此处粘贴代码,因此以下是粗略的示例代码,假设代码/脚本中不存在拼写错误/奇怪的格式:

table SERVICE_CALLS
SERVICE_CALL_ID RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
REQUEST_DATETIME DATE NOT NULL,
RESPONSE_DATETIME DATE,
REQUEST_PAYLOAD CLOB,
RESPONSE_PAYLOAD CLOB

table ERROR_LOGS
ERROR_LOG_ID VARCHAR2(50 BYTE) DEFAULT SYS_GUID() PRIMARY KEY,
ERROR_TIMESTAMP TIMESTAMP(6) NOT NULL,
ERROR_TEXT CLOB NOT NULL

我的新表

table SERVICE_CALL_ERROR_LOG_RELATION
RELATION_ID RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
INSERT_TIMESTAMP TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP,
SERVICE_CALL_ID RAW(16) NOT NULL,
ERROR_LOG_ID CARCHAR2(50 BYTE) NOT NULL,

CONSTRAINT FK_SERVICE_CALL
FOREIGN KEY (SERVICE_CALL_ID),
REFERENCES SERVICE_CALLS(SERVICE_CALL_ID),

CONSTRAINT FK_ERROR_LOG
FOREIGN KEY (ERROR_LOG_ID)
REFERENCES ERROR_LOGS (ERROR_LOG_ID);

ERROR_LOG 将与 SERVICE_CALL 具有多对一的关系,但并非每个 ERROR_LOG 都将具有关联的 SERVICE_CALL。只有在 SERVICE_CALL_ID 可用时创建 ERROR_LOG 时,才会填充 RELATION 表;可用性将在实际应用中确定。如果没有 SERVICE_CALL_ID,我们将在 ERROR_LOGS 表中插入一条记录,而不触及 RELATION 表。

我对存储过程没有太多经验,但我的目标是创建一个存储过程,它将接受 SERVICE_CALL_ID(null 或 raw(16))和 ERROR_TEXT (CLOB)。

  • 如果 SERVICE_CALL_ID 为空,那么我将插入一条新记录 ERROR_LOGS 使用 ERROR_TEXT 和 CURRENT_TIMESTAMP。
  • 如果 SERVICE_CALL_ID 不为空,那么我想在 ERROR_LOGS 中插入一条新记录,获取自动生成的 ERROR_LOG_ID,然后使用 SERVICE_CALL_ID 和获取的 ERROR_LOG_ID 将一条新记录插入到 SERVICE_CALL_ERROR_LOG_RELATION。李>

获取 ERROR_LOG_ID 是我遇到问题的部分。如果它是一个序列,我在这里找到了一些关于获取新插入记录的 ID 的答案,但是这些显然有点不同,因为序列具有可预测的值......有没有办法在新记录上获取自动生成的 ID?

最后说明:当有一个 ERROR_LOG 插入时,往往会在几毫秒内出现多个,所以我不能依赖于获取最新记录,因为在处理时可能会插入其他记录。

【问题讨论】:

  • 也许是个愚蠢的问题,但是如果你的所有表中的 service_call_id 都不是 NULL,那么它怎么不能为 null 呢?
  • 不是每个 ERROR_LOG 都对应一个 SERVICE_CALL,所以如果我们想要插入一个 z ERROR_LOG 条目而不将其与 SERVICE_CALL 条目相关联,我们会将 SERVICE_CALL_ID 的 null 传递给过程。我已经更新了最初的问题以澄清。
  • 您是否考虑过为此使用触发器而不是过程?考虑到你描述的逻辑
  • 我没有考虑过使用触发器;我现在来看看。谢谢!
  • 请记住,无论触发器做什么,都会延迟原始事务的提交。你说的是毫秒,所以请记住这一点

标签: oracle stored-procedures guid


【解决方案1】:

好的,我仍然需要在我的实际环境中将它们放在一起,但是这个小测试程序对我有用。

INSERT INTO TABLE() RETURNING {COLUMN} INTO {VARIABLE}

下面的例子:

CREATE OR REPLACE PROCEDURE LOG_SERVICE_ERROR(
SERVICE_CALL_ID IN RAW,
ERROR_TEXT IN CLOB
)
AS
v_ERROR_LOG_ID VARCHAR2(50 BYTE);
BEGIN

INSERT INTO ERROR_LOGS(SYS_GUID(), CURRENT_TIMESTAMP, ERROR_TEXT) RETURNING ERROR_LOG_ID INTO v_ERROR_LOG_ID;

IF SERVICE_CALL_ID IS NOT NULL THEN

INSERT INTO SERVICE_CALL_ERROR_LOG_RELATION(SYS_GUID(), CURRENT_TIMESTAMP, SERVICE_CALL_ID, v_ERROR_LOG_ID);

END IF;

END;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-01
    • 2016-08-18
    • 1970-01-01
    • 2013-08-24
    • 2017-10-18
    • 1970-01-01
    相关资源
    最近更新 更多