PL/SQL 使用表变量作为查询表

Posted

技术标签:

【中文标题】PL/SQL 使用表变量作为查询表【英文标题】:PL/SQL Use table variable as query table 【发布时间】:2021-08-03 04:45:54 【问题描述】:

在 PL/SQL 中是否可以使用变量作为查询表?

试过了:

declare
   TYPE t_name IS TABLE OF varchar(50) INDEX BY PLS_INTEGER;
   v_names t_name;
begin
select name bulk collect into v_names from my_table;

select name from v_names where name = 'Max';
end;

【问题讨论】:

【参考方案1】:

是的……但不是你的做法,原因有两个:

首先,您没有集合(您称之为表变量),因为您使用了INDEX BY PLS_INTEGER,所以您拥有的是关联数组。 其次,您只能在 SQL 查询中使用集合,其中数据类型已在 SQL 范围内声明(并且您的数据类型已在 PL/SQL 中声明)。

所以,首先你需要创建类型:

CREATE TYPE t_name IS TABLE OF VARCHAR2(50);

然后你就可以运行 PL/SQL 块了:

DECLARE
  v_names t_name;
  v_name  VARCHAR2(50);
BEGIN
  SELECT name
  BULK COLLECT INTO v_names
  FROM my_table;

  SELECT COLUMN_VALUE
  INTO   v_name
  FROM   TABLE(v_names)
  WHERE  COLUMN_VALUE = 'Max';
  
  DBMS_OUTPUT.PUT_LINE( v_name );
END;
/

(注意:第二个查询中的表集合表达式具有伪列COLUMN_VALUE,而不是表中的任何特定标识符。)

db小提琴here

【讨论】:

谢谢!我不明白他们为什么让这变得如此复杂,我不想到处乱扔类型的数据库:/只是想让它工作!如果有人放弃了我的类型,它会破坏系统,该死的。 @user5507535 如果要过滤集合以找到单个值,则可以在初始 SELECT 中执行此操作以仅获取单个值,或者您可以使用 FOR 循环进行迭代PL/SQL 中的集合,然后您不需要尝试将其放回 SQl 范围。 @user5507535。它并不复杂,只是你不熟悉。就破坏数据库而言,这不是问题。在 20 年里,我从来没有掉过一个类型。毕竟 varchar2、integer、date 在包 STANDARD 中都被定义为 TYPE(主要是子类型)。所以这样做是一致的。只是不同。 @Belayer 我理解你,但是这个设计决定没有意义,就像在你不需要的时候要求你创建一个全局变量。我只会在那个非常特定的文件和范围上使用类型,那么为什么需要在整个系统中全局共享? PL/SQL 和 SQL 中有很多这样的东西,在我看来,这是糟糕的设计,对程序员来说不符合人体工程学。 @user5507535 如果您认为它们是两种不同的语言,那是完全有道理的。这就像编写一个包装了一些低级 C 代码的 Java 程序,并问为什么当我在 Java 中声明一个数据类型时,我不能在 C 代码中使用它?您不能,因为它们是两种不同的语言,并且包装是从 Java 到 C 而不是相反。 PL/SQL 和 SQL 也一样;您可以在 PL/SQL 中使用 SQL 类型,但不能在 SQL 中使用 PL/SQL 类型。

以上是关于PL/SQL 使用表变量作为查询表的主要内容,如果未能解决你的问题,请参考以下文章

变量作为 Oracle PL/SQL 中 where 子句中的列名

带有 where 条件的 PL/SQL 更新查询作为带有一些空值的选择查询

列名作为 PL/SQL ORACLE 中的变量

声明变量的 PL/SQL 编译错误

PL/SQL的变量

使用 pl/sql 中的 xmlelement 获取所有关系表数据