当前位置:  开发笔记 > 后端 > 正文

PL/SQL嵌入到表中可能不存在

如何解决《PL/SQL嵌入到表中可能不存在》经验,为你挑选了2个好方法。

我更喜欢在pl/sql块中使用这种"嵌入式"样式插入(与执行立即样式动态sql相反 - 您必须在其中分隔引号等).

-- a contrived example
PROCEDURE CreateReport( customer IN VARCHAR2, reportdate IN DATE )
BEGIN

   -- drop table, create table with explicit column list
   CreateReportTableForCustomer;

   INSERT INTO TEMP_TABLE 
   VALUES ( customer, reportdate );
END;
/

这里的问题是oracle检查'temp_table'是否存在并且它具有正确的colunms数并且如果它不存在则抛出编译错误.

所以我想知道是否有任何方式围绕这个?!基本上我想使用占位符表示表名,以欺骗oracle不检查表是否存在.

编辑:

我应该提到用户能够执行任何"报告"(如上所述).一种机制,它将执行任意查询但始终写入temp_table(在用户的模式中).因此,每次运行报告proc时,它都会删除temp_table并使用最可能的不同列列表重新创建它.



1> FrustratedWi..:

您可以使用动态SQL语句插入到可能存在的temp_table中,然后捕获并处理表不存在时发生的异常.

例:

execute immediate 'INSERT INTO '||TEMP_TABLE_NAME||'  VALUES ( :customer, :reportdate )' using customer, reportdate;

请注意,在动态SQL语句中使表名有所不同,所以如果确保表名保持不变,那将是最好的.



2> Tony Andrews..:

也许你应该使用全局临时表(GTT).这些是永久表结构,用于保存Oracle会话的临时数据.许多不同的会话可以将数据插入到同一GTT中,并且每个会话只能看到自己的数据.根据GTT的定义,数据会在COMMIT或会话结束时自动删除.

你创建GTT(只有一次)像这样:

create globabal temporary table my_gtt
(customer number, report_date date) 
on commit delete/preserve* rows;

*删除适用的

然后你的程序可以像任何其他表一样使用它 - 唯一的区别是它总是从你的会话开始为空.


我不知道,在存储过程中填充GTT并对其运行表函数并不是一个坏主意.这是一个完全有效的实现,前提是OP的TEMP_TABLE中的数据不需要存在或在当前会话范围之外可见.这肯定比使用PL/SQL drop和创建表更好.我怀疑这是一个SQL Server开发模式,它实际上并不适用于Oracle.
推荐阅读
帆侮听我悄悄说星星
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有