通过比较 Table 中的两列和使用 PL/SQL 查看来查找缺失的日期

Find missing dates by comparing two columns in Table and View using PL/SQL

我必须比较 table 和视图中可用的日期列,table 中任何缺失的日期都会从视图中添加记录。 table和view都有1亿条数据。我已经编写了下面的代码,但要迭代超过 400K 行,table 和查看每行需要 2 小时。想知道我是否可以改进我的代码以进行比较。请不要问为什么我从 View 添加记录到 table,这个设置有点复杂我帮不上忙。

备注-

  1. 我必须 运行 这个大约 100+ table 秒。
  2. 不同的 tables/ 视图有不同的日期格式。但是对于 table 和我们将用来进行比较的相应视图,它仍然是相同的。
  3. 在某些 table 中存在无效日期,应忽略这些记录。如果异常仍在继续,我将通过在代码中使用 TO_DATE 函数来实现此目的。
  4. 每个 table/ 视图的日期格式都保存在 MASTER table.

不包括使用 BEGIN 和 DECLARE

读取 MASTER table 的初始代码
    query_str := 'select DISTINCT ' || date_column_name || ' as DATM FROM ' || tablename;
    OPEN c_query FOR query_str;

    LOOP
        BEGIN
            FETCH c_query INTO dateval;
            EXIT WHEN c_query%notfound;
            tmp := TO_DATE(
                dateval,
                dateformat
            );
            tabledatelist(dateval) := 'Date Val';
        EXCEPTION
            WHEN OTHERS THEN
                continue;
        END;
    END LOOP;

    CLOSE c_query;
    query_str := 'select DISTINCT ' || date_column_name || ' as DATM FROM ' || viewname;
    OPEN c_query FOR query_str;

    LOOP
        BEGIN
            FETCH c_query INTO dateval;
            EXIT WHEN c_query%notfound;
            tmp := TO_DATE(
                dateval,
                dateformat
            );
            IF
                NOT tabledatelist.EXISTS(dateval)
            THEN
                -- Code to add missing records. Using it as Insert into select col_name from table.
            END IF;

        EXCEPTION
            WHEN OTHERS THEN
                continue;
        END;
    END LOOP;

    CLOSE c_query;

数百万行的循环很慢。你为什么不完全跳过它们并做这样的事情?

insert into tablename (date_column_name)
select date_column_name from viewname
minus
select date_column_name from tablename;

我猜这段代码缺少很多信息(附加列),但是嘿 - 你也没有 post 它们。所以 - 看看这样的原则是否可行。如果它必须是动态的 SQL(因为您有 100 多个表),那就这样吧。但是,我认为并希望它会表现得更好。


截至无效日期:好吧,这就是将日期存储为字符串的成本。

一个选项可能是创建一个函数,returns 例如1(如果日期有效)或 0(如果无效)。你会用它作为

select date_column_name from viewname 
where f_date_valid(date_column_name) = 1

但会影响性能。

也许您可以分两步完成:

  • 首先插入所有缺失的日期(包括无效的)
  • 然后删除包含无效日期的行

不过,我认为无论采用哪种方法,性能都会受到影响,而且 所有这些 因为您将日期存储为字符串...不好,不好想法。我不是说它是你的(可能不是)。