我'继承'了一个数据库应用程序(基于Oracle 10g数据库,用Delphi编写),必须做出如下决定:
Do Query1.
If the result set is empty, do Query2.
查询是SELECT
个查询,它们具有相同的输出列,有时类似(案例1),有时不同(案例2)输入(FROM)和条件(WHERE)。
案例1:有时差异是:col like 'x'
(或col ='x')变为col like '%'
。
col = 'x'
,而不使用其他查询)。col like :param
更好,因为它不需要2个查询AND (col = 'x' OR :param = 1)
案例2:如果Query1的结果集中没有数据,我还需要使用完全不同的Query2。
从搜索stackoverflow和互联网上我知道我的问题的几个解决方案:
使用两个SQL查询:让程序执行工作而不是数据库(但需要查询数据库两次而不是一次)
result = executeQuery(Query1)
if (isEmpty(result))
result = executeQuery(Query2)
使用UNION:让Oracle完成所有工作(但需要执行两次Query1):
Query1 UNION ALL Query 2 WHERE NOT EXISTS (Query 1)
使用PL / SQL:让Oracle完成大部分工作(但我在某处读到每次都以这种方式编译查询)
begin
Query1;
exception when no_data_found then
Query2;
end;
我的问题是:
答案 0 :(得分:1)
在许多情况下,您可以通过使用较不严格的UNION
子句来避免WHERE
,但包含ORDER BY
子句,以便首先显示更好的匹配结果。如有必要,您可以使用ROWNUM
伪列将结果限制为第一个。
例如,而不是
BEGIN
SELECT * INTO myrec FROM mytable WHERE xxx = 'x';
EXCEPTION
WHEN NO_DATA_FOUND THEN
SELECT * INTO myrec FROM mytable WHERE xxx like '%x%';
END;
你可以写
SELECT * INTO myrec FROM (
SELECT * FROM mytable WHERE X like '%x%'
ORDER BY CASE when xxx='x' THEN 1 ELSE 2 END
) WHERE ROWNUM=1;
注意嵌套的SELECT
语句;这是必要的,否则,WHERE ROWNUM=1
子句将限制ORDER BY
发生之前的结果集。