sql循环假脱机脚本

0s0u357o  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(349)

我在oracle数据库中有一个大表,我想将它提取到csv中,这样我就可以将它移到另一个系统上(理想情况下,这两个系统之间会有一个直接连接,但如果没有这个连接,这是下一个最佳解决方案)。
因为表很大,我当时提取了一个月的数据。因此查询如下所示:

set termout off;
set echo off;
set verify off;
spool "C:\output_path\&&1. events.csv";
select /*csv*/ * from my_database.events
where my_date between to_date(&&1,'yyyy-mm-dd') and to_date(&&2,'yyyy-mm-dd');
spool off
set termout on;
set echo on;

然后我从另一个脚本中调用它,如下所示:

@my_script.sql "'2020-01-01'" "'2020-01-31'"

这将使“2020-01-01”和“2020-01-31”分别取代&&1和&&2,并将1月份的数据输出到 C:\output_path\'2020-01-01' events.csv .
理想情况下,我想把它变成一个循环,这样我就可以有这样一个函数(伪python):

def scrape_range_of_months(start_date, end_date)
    date_range = make_date_range(start_date, end_date)
    for date in date_range:
        scrape_month(date, end_of_month(date))

其中make\ date\ range()和end\ of\ month()是独立的函数。
pl/sql是一种比python更为神秘的语言,所以虽然我可以找到解决方案的各个部分,但还不清楚是否有可能像我想的那样在循环上运行脚本。

9cbw7uwe

9cbw7uwe1#

@justincave是对的,一个完整的解决方案将使用utl\u文件直接从pl/sql编写文件。
在本例中,我编写了一些pl/sql来生成逐月提取的代码。我将“between”改为“>=”和“<”,因为如果有时间成分,您将错过当月最后一天的记录。

DECLARE
    l_date    DATE := DATE '2020-01-01';
    c_spool   VARCHAR2( 512 ) := Q'[spool "C:\output_path\YMD.events.csv";
select /*csv*/ * from my_database.events
where my_date >= to_date('YMD','yyyy-mm-dd') and my_date < add_months(to_date('YMD','yyyy-mm-dd'),1);
]';
BEGIN
    WHILE l_date < SYSDATE
    LOOP
        DBMS_OUTPUT.put_line( REPLACE( c_spool
                                     , 'YMD'
                                     , TO_CHAR( l_date, 'yyyy-mm-dd' ) ) );
        l_date   := ADD_MONTHS( l_date, 1 );
    END LOOP;
END;

输出示例:

spool "C:\output_path\2020-02-01.events.csv";
select /*csv*/ * from my_database.events
where my_date >= to_date('2020-02-01','yyyy-mm-dd') and my_date < 
add_months(to_date('2020-02-01','yyyy-mm-dd'),1);

相关问题