用于截断和重新填充表的 PLSQL 过程

Posted

技术标签:

【中文标题】用于截断和重新填充表的 PLSQL 过程【英文标题】:PLSQL Procedure to Truncate and Re-populate table 【发布时间】:2018-08-01 19:59:11 【问题描述】:

我的架构中有一些表和视图,我正在尝试创建一个存储过程,该过程将采用 2 个参数(table_name、view_name)来截断表并从视图中重新填充它。

这是我的程序代码:

CREATE OR REPLACE 
PROCEDURE PROC_NAME (TABLE_NAME IN VARCHAR2, VIEW_NAME IN VARCHAR2) 
IS 
BEGIN 
EXECUTE IMMEDIATE 'TRUNCATE TABLE TABLE_NAME'; 

EXECUTE IMMEDIATE 'INSERT INTO TABLE_NAME
                   SELECT * FROM VIEW_NAME';
END; 
/

现在当我运行以下代码时:

BEGIN
    PROC_NAME('SOME_TABLE', 'SOME_VIEW');
END;
/

我收到以下错误:

ORA-00942: table or view does not exist
ORA-06512: at "SCHEMA.PROC_NAME", line 4
ORA-06512: at line 2
00942. 00000 -  "table or view does not exist"

你们觉得问题出在哪里?

提前致谢!

【问题讨论】:

有什么理由不为此目的使用物化视图? 【参考方案1】:

试试:

CREATE OR REPLACE 
PROCEDURE PROC_NAME (TABLE_NAME IN VARCHAR2, VIEW_NAME IN VARCHAR2) 
IS 
BEGIN 
EXECUTE IMMEDIATE 'TRUNCATE TABLE '||TABLE_NAME; 

EXECUTE IMMEDIATE 'INSERT INTO '||TABLE_NAME||'
                   SELECT * FROM '||VIEW_NAME;
END; 
/

您的基本问题是您正确传递了参数但没有在过程中使用它们。修复方法是在EXECUTE IMMEDIATE 使用的字符串中使用串联运算符|| 将参数组合到正在执行的字符串中。

另一个选项是使用DELETE FROM 而不是TRUNCATE TABLE。当 Oracle 首次实现 Materialized Views 时,这是您尝试实现的成熟版本,他们犯了同样的错误。 TRUNCATE TABLE 非常快,但在 Oracle 实现中它是一个 DDL(数据定义语言)语句,这意味着它将以隐式提交完成。因此,在INSERT 完成(并已提交)之前的一段时间内,您的表将为空。如果 Oracle 认为改变他们的底层技术足够重要,那么您应该考虑这样做。

如果您不更改为DELETE 技术,那么您应该在程序结束时添加COMMIT。使用TRUNCATE TABLE 将保证已提交数据的删除,因此如果您的INSERT 成功,那么您也应该提交该语句。

我对 Materialized Views 的引用是相关的,因为它可能是您尝试为自己编写的内容的内置替代品。它的问题是它有太多的花里胡哨,很难找到一篇关于如何在你的简单用例中使用它的文章。我欢迎评论引用此类文章。

【讨论】:

您还需要将TABLE_NAME 移出第二个EXECUTE IMMEDIATE 中的字符串文字。 您好,感谢您的回复。我试过了,但仍然遇到同样的错误! 是的,将它从​​字符串文字中取出,现在它正在按预期工作!谢谢!

以上是关于用于截断和重新填充表的 PLSQL 过程的主要内容,如果未能解决你的问题,请参考以下文章

截断所有 MySql 表的 shell 脚本

MYSQL 清空表和截断表

填充空格后 Tailwind CSS 截断

在 HSQLDB 中截断模式

使用“锁定”截断/填充从 Oracle 中的视图填充表

截断表的正确 LINQtoSQL 方式是啥?