通过比较 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,这个设置有点复杂我帮不上忙。
备注-
- 我必须 运行 这个大约 100+ table 秒。
- 不同的 tables/ 视图有不同的日期格式。但是对于 table 和我们将用来进行比较的相应视图,它仍然是相同的。
- 在某些 table 中存在无效日期,应忽略这些记录。如果异常仍在继续,我将通过在代码中使用 TO_DATE 函数来实现此目的。
- 每个 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
但会影响性能。
也许您可以分两步完成:
- 首先插入所有缺失的日期(包括无效的)
- 然后删除包含无效日期的行
不过,我认为无论采用哪种方法,性能都会受到影响,而且 所有这些 因为您将日期存储为字符串...不好,不好想法。我不是说它是你的(可能不是)。
我必须比较 table 和视图中可用的日期列,table 中任何缺失的日期都会从视图中添加记录。 table和view都有1亿条数据。我已经编写了下面的代码,但要迭代超过 400K 行,table 和查看每行需要 2 小时。想知道我是否可以改进我的代码以进行比较。请不要问为什么我从 View 添加记录到 table,这个设置有点复杂我帮不上忙。
备注-
- 我必须 运行 这个大约 100+ table 秒。
- 不同的 tables/ 视图有不同的日期格式。但是对于 table 和我们将用来进行比较的相应视图,它仍然是相同的。
- 在某些 table 中存在无效日期,应忽略这些记录。如果异常仍在继续,我将通过在代码中使用 TO_DATE 函数来实现此目的。
- 每个 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
但会影响性能。
也许您可以分两步完成:
- 首先插入所有缺失的日期(包括无效的)
- 然后删除包含无效日期的行
不过,我认为无论采用哪种方法,性能都会受到影响,而且 所有这些 因为您将日期存储为字符串...不好,不好想法。我不是说它是你的(可能不是)。