我应该从varray还是在嵌套游标中查询?

时间:2019-10-10 12:39:37

标签: oracle plsql

我有一个表,客户可以在其中定义一些名称,他们希望将其数据复制到其他表中。时间戳将被复制以跟踪最新数据。在通常存储数据的表中,其时间戳分为day_part和time_part,它们均为RAW(3);

这些是我的桌子:

表_A

name    VARCHAR2(1000)

table_B

name    VARCHAR2(1000)
id_num  INT

table_C

id_num      INT
day_part    RAW(3)
time_part   RAW(3)
value       NUMBER(20,5)

table_D

name        VARCHAR2(1000)
time_stamp  TIMESTAMP

table_D中的时间戳是由一个以day_part和time_part作为输入的函数创建的。

我想根据table_A中的名称和table_D中的最新时间戳从table_C复制数据。这是一个庞大系统的一部分,因此我无法将两个RAW更改为单个时间戳,这会引起很多问题。

我当前的解决方案是先打开一个游标,使用

在table_A中找到给定名称的id_num
SELECT table_B.name, table_B.id_num
FROM table_A
INNER JOIN table_B
ON table_B.name = table_A.name;

将名称和id_num提取到变量(current_name,current_id)中,以在第一个游标中的第二个游标中搜索数据。在打开第二个光标之前,我将time_stamp转换为RAW:

SELECT MAX(time_stamp)
INTO stamp_variable
FROM table_D
WHERE name = current_name;

stampToRaw(last_dPart, last_tPart, stamp_variable);

现在第二个光标打开,它执行查询:

SELECT value, day_part, time_part
FROM table_C
WHERE id_num = current_id
AND ((day_part = lastdPart AND time_part > last_tPart)
    OR day_part > last_dPart);

如果找到较新的数据,则将其复制到另一个表中,并将其时间戳存储在table_D中,以在下次运行时使用。 有没有我看不到的更有效的方法? 我不习惯PL / SQL的思维方式,因此,如果对此有明显的答案,我深表歉意。

2 个答案:

答案 0 :(得分:1)

从我的角度来看,您的选择都不是“最佳”。嵌套循环可能会很慢。

为什么不简单地将这两个表连接起来,例如

 acceleroLogging.stop();
            acceleroLogging.downloadAsync(100, (nEntriesLeft, totalEntries) ->
                    Log.i("Logging@", "Progress Update = " + nEntriesLeft + "/" + totalEntries)).continueWith((Continuation<Void, Void>) task -> {
                if (task.isFaulted()) {
                    Log.e("Logging", "Error occured");
                } else {
                    Log.i("Logging", "Downloaded");
                }
                return null;
            });

现在就拥有一切,就在这里?如果必须是PL / SQL,那就去吧;将其转换为过程(或函数,无论您喜欢哪个)都没有问题。

答案 1 :(得分:1)

您可以使用简单的查询来实现:

SELECT
    A.NAME,
    A.ID_NUM,
    B.VALUE,
    B.TIMESTAMP
FROM
    TABLE_A A
    JOIN TABLE_B B ON ( A.NAME = B.NAME );

干杯!