手动地,我可以使用下面的第一个代码块在内部查询中选择分区。有没有办法通过循环以更优雅的方式做到这一点?我在这里显示3个分区,但是我大约有200个分区,并且这些分区是基于日期列的,因此当我在以后的日期再次运行此查询时,分区名称将需要更改。
SELECT *
FROM (
SELECT * FROM RSS_ACQ.TRX_ARQ PARTITION("SYS_P211048") UNION ALL
SELECT * FROM RSS_ACQ.TRX_ARQ PARTITION("SYS_P210329") UNION ALL
SELECT * FROM RSS_ACQ.TRX_ARQ PARTITION("SYS_P176323")
) TRX_ARQ
;
使用此语句,我创建了一个输出UNION ALL
语句的循环。
BEGIN
FOR ALL_TAB_PARTITIONS IN
(
SELECT PARTITION_NAME
FROM ALL_TAB_PARTITIONS
where TABLE_OWNER = 'TABLEOWNER'
AND TABLE_NAME = 'TABLENAME'
AND PARTITION_POSITION > 123
ORDER BY partition_position DESC
)
LOOP
DBMS_OUTPUT.PUT_LINE( 'SELECT * FROM RSS_ACQ.TRX_ARQ PARTITION(\"'
|| ALL_TAB_PARTITIONS.PARTITION_NAME || '\") UNION ALL');
END LOOP;
END;
在此块中,我尝试使用内部查询中的循环。它的格式尚未正确,我需要避免在最后一个分区使用UNION ALL
。
SELECT *
FROM (
BEGIN
FOR ALL_TAB_PARTITIONS IN
(
SELECT PARTITION_NAME
FROM ALL_TAB_PARTITIONS
where TABLE_OWNER = 'TABLEOWNER'
AND TABLE_NAME = 'TABLENAME'
AND PARTITION_POSITION > 123
ORDER BY partition_position DESC
)
LOOP
DBMS_OUTPUT.PUT_LINE( 'SELECT * FROM RSS_ACQ.TRX_ARQ PARTITION(\"'
|| ALL_TAB_PARTITIONS.PARTITION_NAME || '\") UNION ALL');
END LOOP;
END;
) TRX_ARQ
;
这是一些错误,但还有更多错误。它们是语法错误,指向查询的其他部分,因此我希望转义引号时遇到问题。
Error starting at line : 99 in command -
END LOOP
Error report -
Unknown Command
Error starting at line : 100 in command -
END
Error report -
Unknown Command
Error starting at line : 101 in command -
)
Error report -
Unknown Command
Error starting at line : 102 in command -
) TABLENAME
Error report -
Unknown Command
答案 0 :(得分:2)
我们无法在SELECT语句中执行匿名PL / SQL块。
您需要做的是将ALL_TAB_PARTITIONS循环的输出假脱机到一个文件(或SQL工作表(如果您使用的是SQL Developer这样的IDE))。这将为您提供一个脚本,您可以在编辑后单独运行该脚本(您需要从最终生成的SELECT中修剪UNION ALL。
也许有更多优雅的方法可以实现相同的目的,但是这项任务似乎很错误,以至于我不值得为此付出努力。您要在单个语句中查询200个分区。这是蛮力的操作,查询命名块不会带来任何麻烦。实际上,产生200个独立查询的并集可能比单个查询更昂贵。那么为什么不尝试这样的事情呢?
select * from RSS_ACQ.TRX_ARQ
where partition_key_col >= date '2018-08-01' -- or whatever
“我认为您忽略了在WITH子句中使用PL / SQL的12c功能”
该12c功能用于功能而不是过程,因此它不会帮助OP运行其代码。可以使用WITH子句函数,但这需要:
table()
调用来调用函数可以对WITH子句函数进行流水线处理吗?我在文档中找不到任何不能说的内容(目前无法访问12c进行测试)。
答案 1 :(得分:2)
这有点猜测,但是评论太久了。
我假设您的表是间隔分区的。在这种情况下,从> 123的分区位置获取所有数据与获取比123的最高日期具有更高日期的所有行相同。
您可以从ALL_TAB_PARTITIONS
获取该日期,然后将其用于查询表。像这样:
WITH FUNCTION get_high_value RETURN DATE IS
l_high_val_expr ALL_TAB_PARTITIONS.HIGH_VALUE%TYPE;
l_high_value DATE;
BEGIN
SELECT high_value
INTO l_high_val_expr
FROM all_tab_partitions
WHERE table_owner = 'RSS_ACQ'
AND table_Name = 'TRX_ARQ'
and partition_position = 123;
EXECUTE IMMEDIATE 'SELECT ' || l_high_val_expr || ' FROM DUAL' INTO l_high_value;
RETURN l_high_value;
END;
SELECT * FROM rss_acq.trx_arq
-- Replace "partitioned_date_column" with the name of the column on which the
-- table is interval partitioned.
WHERE partitioned_date_column > get_high_value;