You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

无需Java实现Oracle测试自动化及存储过程每日求和对比方案

问题1:不使用Java实现Oracle测试自动化的方案

其实不用Java也有不少靠谱的方式,我给你整理几个实用的:

  • PL/SQL + Oracle Scheduler 做内部自动化测试
    你可以直接用PL/SQL写测试逻辑,比如验证数据完整性、存储过程输出是否符合预期,然后用Oracle自带的Scheduler(DBMS_SCHEDULER)来定时执行这些测试脚本。比如写一个测试包,里面包含断言逻辑,跑完还能把结果写到日志表或者用UTL_MAIL发邮件告警,完全在Oracle内部搞定,不需要外部工具。

  • SQL*Plus 脚本结合系统调度
    如果需要更灵活的外部触发,SQL*Plus是个原生好选择。把测试逻辑写成.sql脚本,比如执行查询、对比结果、输出测试报告,然后用Linux的Cron或者Windows的任务计划定时调用sqlplus username/password@db @test_script.sql就行。这种方式纯靠Oracle自带工具,完全不需要Java环境。

  • UTPLSQL 单元测试框架
    这是Oracle生态里专门的PL/SQL单元测试工具,完全基于PL/SQL开发,和Java一点关系都没有。你可以用它写结构化的测试用例,比如测试存储过程的输入输出、边界条件,还能生成清晰的测试报告。安装就是在Oracle里部署几个包,上手很快。

  • Shell/PowerShell 脚本调用Oracle客户端
    要是需要和其他系统集成,比如测试后把结果推送到监控工具,用Shell或者PowerShell脚本配合Oracle客户端工具(比如sqlplus、sqlcl)也很方便。脚本里可以处理测试逻辑,对比预期值和实际值,然后输出结果或者触发告警,灵活度很高。


问题2:存储过程sum_daily的自动化结果对比方案

当然可以在Oracle内部实现!我给你一个亲测好用的具体思路:

步骤1:创建测试日志表(可选但推荐)

先建个日志表用来记录每次测试的时间、结果和错误详情,方便后续排查:

CREATE TABLE sum_daily_test_log (
    test_id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    test_timestamp TIMESTAMP DEFAULT SYSTIMESTAMP,
    test_result VARCHAR2(20) CHECK (test_result IN ('PASS', 'FAIL', 'ERROR')),
    error_details CLOB
);

步骤2:编写PL/SQL对比逻辑

写一个存储过程,先执行sum_daily,再对比它生成的结果和实时计算的预期值:

CREATE OR REPLACE PROCEDURE sum_daily_test_proc AS
    v_mismatch_count NUMBER;
    v_error_msg CLOB;
BEGIN
    -- 执行目标存储过程
    EXECUTE sum_daily;

    -- 对比存储过程生成的结果与实时计算的分组求和
    SELECT COUNT(*)
    INTO v_mismatch_count
    FROM (
        -- 存储过程插入的当日结果(假设结果表是sum_daily_result,字段为sum_val、value_type、create_time)
        SELECT sum_val, value_type
        FROM sum_daily_result
        WHERE TRUNC(create_time) = TRUNC(SYSDATE)
        MINUS
        -- 实时计算的预期结果(假设源表是your_source_table,日期字段是record_date)
        SELECT SUM(value_tx) AS sum_val, value_type
        FROM your_source_table
        WHERE TRUNC(record_date) = TRUNC(SYSDATE - 1) -- 假设统计前一天数据,根据业务调整
        GROUP BY value_type
        UNION ALL
        SELECT SUM(value_tx) AS sum_val, value_type
        FROM your_source_table
        WHERE TRUNC(record_date) = TRUNC(SYSDATE - 1)
        GROUP BY value_type
        MINUS
        SELECT sum_val, value_type
        FROM sum_daily_result
        WHERE TRUNC(create_time) = TRUNC(SYSDATE)
    );

    -- 判断测试结果
    IF v_mismatch_count = 0 THEN
        INSERT INTO sum_daily_test_log (test_result) VALUES ('PASS');
        DBMS_OUTPUT.PUT_LINE('测试通过:sum_daily结果与预期完全一致');
    ELSE
        -- 收集不匹配的详细信息
        SELECT LISTAGG('Value_Type: ' || value_type || ' | 预期值: ' || NVL(TO_CHAR(expected_sum), '无') || ' | 实际值: ' || NVL(TO_CHAR(actual_sum), '无'), CHR(10))
        INTO v_error_msg
        FROM (
            SELECT 
                COALESCE(e.value_type, s.value_type) AS value_type,
                e.sum_val AS expected_sum,
                s.sum_val AS actual_sum
            FROM (
                SELECT SUM(value_tx) AS sum_val, value_type
                FROM your_source_table
                WHERE TRUNC(record_date) = TRUNC(SYSDATE - 1)
                GROUP BY value_type
            ) e
            FULL OUTER JOIN (
                SELECT sum_val, value_type
                FROM sum_daily_result
                WHERE TRUNC(create_time) = TRUNC(SYSDATE)
            ) s ON e.value_type = s.value_type
            WHERE e.sum_val != s.sum_val OR e.sum_val IS NULL OR s.sum_val IS NULL
        );

        INSERT INTO sum_daily_test_log (test_result, error_details) VALUES ('FAIL', v_error_msg);
        DBMS_OUTPUT.PUT_LINE('测试失败:存在结果不匹配,详情请查看sum_daily_test_log表');
        -- 可选:发送告警邮件(需配置UTL_MAIL)
        -- UTL_MAIL.SEND(sender => 'db_admin@yourcompany.com', recipients => 'your_email@yourcompany.com', subject => 'sum_daily测试失败', message => v_error_msg);
    END IF;

    COMMIT;
EXCEPTION
    WHEN OTHERS THEN
        INSERT INTO sum_daily_test_log (test_result, error_details) VALUES ('ERROR', '测试过程出错:' || SQLERRM);
        COMMIT;
        DBMS_OUTPUT.PUT_LINE('测试过程出错:' || SQLERRM);
END;
/

步骤3:用Oracle Scheduler定时执行

把上面的测试过程做成定时任务,比如每天凌晨1点执行(假设sum_daily在凌晨0点运行,测试在之后):

BEGIN
    DBMS_SCHEDULER.CREATE_JOB (
        job_name        => 'SUM_DAILY_AUTO_TEST_JOB',
        job_type        => 'STORED_PROCEDURE',
        job_action      => 'sum_daily_test_proc',
        start_date      => SYSTIMESTAMP,
        repeat_interval => 'FREQ=DAILY;BYHOUR=1;BYMINUTE=0;BYSECOND=0',
        enabled         => TRUE,
        comments        => '每日自动验证sum_daily存储过程的结果正确性'
    );
END;
/

注意事项

  • 请把代码中的sum_daily_result替换成存储过程实际插入结果的表名,your_source_table替换成源数据表名,record_date替换成源表中记录业务日期的字段。
  • 如果存储过程是统计当日数据,就把SYSDATE - 1改成SYSDATE,根据你的实际业务逻辑调整日期条件。
  • 要是不需要日志表,也可以直接在PL/SQL里输出结果或者发送告警,但日志表能帮你留存历史记录,方便回溯问题。

内容的提问来源于stack exchange,提问作者John Wick

火山引擎 最新活动