截断并重新填充表的PLSQL过程

时间:2018-08-01 19:59:12

标签: sql database oracle plsql

我的架构中有一些表和视图,我试图创建一个存储过程,该过程将使用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 个答案:

答案 0 :(得分:2)

尝试:

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首次实现 Materialised Views (这是您要实现的目标的成年版本)时,他们犯了同样的错误。 TRUNCATE TABLE非常快,但是在Oracle实现中,它是DDL(数据定义语言)语句,这意味着它将使用隐式提交来完成。因此,在INSERT完成(并提交)之前的一段时间内,您的表将为空。如果Oracle认为更改其基础技术足够重要,那么您应该考虑这样做。

如果不更改为DELETE技术,则应在过程结束时添加一个COMMIT。使用TRUNCATE TABLE将保证已删除数据,因此,如果INSERT成功,则还应提交该语句。

我对 Materialised Views 的引用很有意义,因为它可能是您自己尝试编写的内容的内置替代品。它的问题在于它有很多麻烦,很难在简单的用例中找到有关如何使用它的文章。我欢迎引用此类文章的评论。