1

我有这样的场景,我需要创建一个存储过程,其中列将动态出现。应基于此列创建临时表。实际上,我在 SQL Server 中做的这个场景,我已经将 SQL Server 数据库迁移到了 Oracle。

谢谢

4

2 回答 2

8

如果要动态创建表,则需要使用动态 SQL

BEGIN
  EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE table_name( col1 number, col2 number )';
END;

话虽如此,将创建临时表的 SQL Server 代码直接移植到 Oracle 几乎可以肯定是一个错误。它的工作方式与您的 SQL Server 代码不同。

  • 首先,Oracle 中的临时表对每个会话都是可见的,这与 SQL Server 不同,它们在会话中是本地的。这意味着如果您有两个会话调用您的存储过程,它们都会尝试创建临时表,而第二个会话将失败(假设您也在过程结束时删除临时表而不是让成千上万的临时表累积)。
  • 考虑到所需的锁存量,在 Oracle 中创建表是一个低效的过程。Oracle 的假设是您不是在动态创建对象。如果您的应用程序违反该假设,您将遇到一些可伸缩性问题。
  • 如果您动态创建表,则必须动态引用它们。因此,对临时表的任何查询也需要使用动态 SQL。这比静态 SQL 效率低,它使您的代码更难编写、更难调试和更难维护。
于 2013-04-05T07:21:22.657 回答
2

也许我有点话题,但尝试分析你真正想要实现的目标。我一直在与几个使用 T-TSQL 的人合作,并且 SQL Server 中使用的模式与 Oracle 的模式不同。只是不要尝试一对一地完全重写您的代码。不起作用。

例如,使用临时表在 Oracle 中被认为是一个糟糕的设计(在大多数情况下)。在 T-SQL 中使用临时表的情况下,通常会在 Oracle 中使用游标。

还要记住 SQL 和 PL/SQL 是编译语言(它不是真正的脚本)。您不能(重新)在 PL/SQL 包中创建表,然后在某些(或其他包)中使用它。当您在 Oracle 中修改一个对象时,所有依赖的代码都必须在后台重新编译。对于从 SQL Server 转向 Oracle 的人来说,这是许多挫折的根源。

这并没有更糟,只是比看起来更不一样。

于 2013-04-05T07:46:13.150 回答