我正在将GTT转换为oracle类型,如APC的优秀answer所述。但是,某些GTT正在根据另一个表中的选择查询进行更新。例如:
UPDATE my_gtt_1 c
SET (street, city, STATE, zip) = (SELECT src.unit_address,
src.unit_city,
src.unit_state,
src.unit_zip_code
FROM (SELECT mbr.ROWID row_id,
unit_address,
RTRIM(a.unit_city) unit_city,
RTRIM(a.unit_state) unit_state,
RTRIM(a.unit_zip_code) unit_zip_code
FROM table_1 b,
table_2 a,
my_gtt_1 mbr
WHERE type = 'ABC'
AND id = b.ssn_head
AND a.h_id = b.h_id
AND row_id >= v_start_row
AND row_id <= v_end_row) src
WHERE c.ROWID = src.row_id)
WHERE state IS NULL
OR state = ' ';
如果my_gtt_1
不是全局临时表而是oracle集合类型,那么是否可以对此复杂进行更新?或者在这些情况下,我们最好使用全局临时表?
答案 0 :(得分:1)
我认为APC answer to your previous question的这一部分与此相关:
全球临时表也很好 如果我们有很多中间人 处理也是如此 单一的解决很复杂 SQL查询。特别是如果那样 处理必须应用于子集 检索到的行。
您无法像使用GTT一样使用UPDATE语句更新内存数据;你需要编写程序代码来定位和更改有问题的数组元素。
答案 1 :(得分:1)
您无法对对象类型执行set UPDATE操作。您必须逐行执行此操作,如:
FOR i IN l_tab.FIRST..l_tab.LAST LOOP
SELECT src.unit_address,
src.unit_city,
src.unit_state,
src.unit_zip_code
INTO l_tab(i).street,
l_tab(i).city,
l_tab(i).STATE,
l_tab(i).zip
FROM (your_query) src;
END LOOP;
因此,您应该尝试在创建时进行所有计算(可以进行BULK COLLECT)。显然,如果您的进程需要许多步骤,您可能会发现全局临时表的性能优于内存中结构。
从您提出的最后一个问题来看,您似乎正在尝试用对象表替换所有全局临时表。我建议谨慎,因为一般来说,它们不可互换:
在我看来,您正在尝试进行的更改将对您的逻辑进行大规模改革,并且可能效果不佳。通常,您不会将GTT替换为对象表。您可以通过直接使用SET操作来删除性能显着提升的GTT(对您的数据执行大量的UPDATE / DELETE / INSERT 直接而不使用临时表)。
我建议在选择解决方案之前执行基准测试(这可能就是你现在正在做的事情:)