PL/SQL:在创建表之前检查模式中是不是有足够的空间

Posted

技术标签:

【中文标题】PL/SQL:在创建表之前检查模式中是不是有足够的空间【英文标题】:PL/SQL: Check if there is sufficient space in schema before creating tablePL/SQL:在创建表之前检查模式中是否有足够的空间 【发布时间】:2019-12-30 16:52:55 【问题描述】:

我正在使用一个使用繁重查询(运行约 1 小时)创建表的过程。查询类似于“从表中选择 *”,表中的列可以更改。 经常发现 schema 中没有可用空间来创建表,所以我得到一个异常,时间是徒劳的,我需要再次进行相同的计算。

我得到的错误:

ORA-01536: 超出表空间的空间配额 ORA-06512:在“UPDATE_REPORT”,第 37 行

我想做的事: - 将查询结果存储在游标中的临时段中; - 尝试使用游标创建表。在异常情况下(空间不足),删除一个特殊的空间保持表以释放模式中的表空间; - 尝试从光标重新创建表格。

我尝试使用动态 SQL 来解决这个问题,但它会导致过于复杂,而问题似乎有一个简单的解决方案。我面临的主要问题是没有明显的方法可以使用游标创建表。

有什么我错过的简单解决方案吗?也许光标是解决这个问题的错误方法?

【问题讨论】:

这听起来像是一个设计问题。为什么要重复创建这个表?一种选择是使用外部表并将查询结果写入该表。它仍会占用磁盘空间,但由操作系统而不是数据库占用。然后,您可以检查 db 大小,并从外部表中执行“select into..”。 请使用标签下方的edit 按钮编辑您的问题,并包含有关您遇到的错误的信息 - ORA- 编号和文本。谢谢。 重新创建的原因是它是数据实验室中的分析数据表,需求经常变化,因此提供灵活性和快速变化的最简单方法。 我不确定外部表是否可以工作。它的大小约为 4 GB,我想导出表需要更多时间。但无论如何感谢您的建议,它在某些任务中可能非常有用。 为什么物化视图不起作用? 【参考方案1】:

我能想到的两件事:

让数据库做脏活 又名享受您的 DBA 工作,只需查看 Oracle 的自我管理方式 怎么样?让表空间自动扩展 将该表空间上的无限配额授予用户

方法如下(以特权用户身份连接):

SQL> select file_name, tablespace_name From dba_data_files;

FILE_NAME                                        TABLESPACE_NAME
------------------------------------------------ -----------------------------
C:\ORACLEXE\APP\ORACLE\ORADATA\XE\USERS.DBF      USERS
C:\ORACLEXE\APP\ORACLE\ORADATA\XE\SYSAUX.DBF     SYSAUX
C:\ORACLEXE\APP\ORACLE\ORADATA\XE\UNDOTBS1.DBF   UNDOTBS1
C:\ORACLEXE\APP\ORACLE\ORADATA\XE\SYSTEM.DBF     SYSTEM

SQL> alter database datafile 'C:\ORACLEXE\APP\ORACLE\ORADATA\XE\USERS.DBF'
  2  autoextend on
  3  maxsize unlimited;

Database altered.

SQL> alter user scott quota unlimited on users;

User altered.

SQL>

【讨论】:

【参考方案2】:

我想要做的: - 将查询的结果存储在游标中的临时段中; - 尝试使用游标创建表。在异常情况下(空间不足),删除一个特殊的空间保持表以释放模式中的表空间; - 尝试从光标重新创建表格。

不要自找麻烦。告诉 Oracle 不要因为空间问题而死。

您可以使您的会话“可恢复”,这样,Oracle 将暂停您的会话,直到问题得到纠正(然后自动继续),而不是在您用完空间时给您一个错误。

假设您拥有所需的所有权限(特别是 GRANT RESUMABLE TO yourschema),您可以这样启用它:

alter session enable resumable timeout 1800 name 'your process name, can be anything';

1800 数字以秒为单位,让您的 DBA 有 30 分钟的时间在会话超时之前解决问题。 “我的流程”将显示在 V$RESUMABLE 中,用于查询和自动警报。

您的 DBA 可以监控 V$RESUMABLE 和/或您可以在 AFTER SUSPEND 事件上创建架构级数据库触发器,以便在他们需要介入时向他们发送电子邮件。

【讨论】:

这就是我想要的!希望它对我有用。非常感谢!【参考方案3】:

我同意@OldProgrammer - 这是一个设计问题。删除和重新创建表是一种反模式。

目前尚不清楚您要解决的确切问题,但更明智的方法可能是:

    创建一次表。使用 INITIAL EXTENT 参数确保表具有所需的所有空间(您可能必须运行一些查询来确定该图应该是什么)。 请与您的 DBA 确认表空间设置为 AUTOEXTEND,以防出现超出您计算的恶意结果集。也许为模式所有者协商更多的表空间配额。 填充表一次。 在后续运行之前,使用 REUSE STORAGE 子句 TRUNCATE 表以保留分配的空间。

【讨论】:

以上是关于PL/SQL:在创建表之前检查模式中是不是有足够的空间的主要内容,如果未能解决你的问题,请参考以下文章

检查数据库中是不是存在表 - PL SQL

PL/SQL 触发器在插入语句之前检查值

检查表是不是重复的过程 - Oracle PL/SQL

oracle创建存储过程时,提示错误是:错误(5,18): PL/SQL: ORA-00947: 没有足够的值?代码如下:

PL/SQL 存储过程创建表

Oracle PL / SQL触发器,在UPDATE之前/之后仅用于识别表中已修改的列