【发布时间】:2014-03-28 09:05:18
【问题描述】:
我在 Oracle 中开发触发器时遇到了这个问题:ORA-01403: no data found。我做了一些研究并了解了问题的根源。不过handling the error exception 阻止了上述错误,但并没有解决我的问题。
我目前正在寻找的是一种最佳解决方法,以执行较少的查询量/尽可能实现最佳性能。我将尝试描述为真实结构创建简单示例的场景。
场景
我有一个“日期参考”表来确定时间段,比如:
CREATE TABLE DATE_REFERENCE (
DATE_START DATE NOT NULL,
DATE_END DATE NOT NULL,
-- Several other columns here, this is just a silly example
CONSTRAINT PK_DATE_REFERENCE PRIMARY KEY(DATE_START, DATE_END)
);
当触发器被触发时,我将有一个 DATE 字段 - 例如 DATE_GIVEN(例如缘故)。我需要的是:
- 找到
DATE_REFERENCE所在的行DATE_GIVEN BETWEEN DATE_START AND DATE_END(简单); 或 - 如果上一个选项返回无数据,我需要找到下一个最接近
DATE_START的DATE_GIVEN。
在这两种情况下,我都需要从表 DATE_REFERENCE 中检索包含所有列的行,无论它是否匹配选项 1 或 2。这正是我遇到所描述问题的地方。 p>
我把这个测试块写到 test 并试图找到一个解决方案。我知道,下面的示例不起作用; 但这正是我想要完成的(在概念上)。我添加了像 -- Lots of code 这样的 cmets,以明确这将成为更复杂触发器的一部分:
DECLARE
DATE_GIVEN DATE;
RESULTROW DATE_REFERENCE%ROWTYPE;
BEGIN
-- Lots of code
-- Lots of code
-- Lots of code
DATE_GIVEN := TO_DATE('2014-02-26 12:30:00', 'YYYY-MM-DD HH24:MI:SS');
-- This one throws the ORA-01403 exception if no data was found
SELECT
* INTO RESULTROW
FROM
DATE_REFERENCE
WHERE
DATE_GIVEN BETWEEN DATE_START AND DATE_END;
-- If the above didn't throw exceptions, I would continue like so:
IF RESULTROW IS NULL THEN
SELECT
* INTO RESULTROW
FROM
DATE_REFERENCE
WHERE
DATE_START > DATE_GIVEN
AND ROWNUM = 1
ORDER BY DATE_START ASC;
END IF;
-- Now RESULTROW is populated, and the rest of the trigger code gets executed ~beautifully~
-- Lots of code
-- Lots of code
-- Lots of code
END;
问题
知道上面的 PL/SQL 块更多的是一个概念而不是工作代码,什么是获得RESULTROW 填充、注意性能和尽可能少的查询的最佳方式?
抱歉这个问题太长了,但我认为情景解释是必要的。提前感谢您的任何帮助/想法!
【问题讨论】:
标签: sql oracle plsql triggers oracle11g