BULK COLLECT INTO 并且只是 INTO 在一个 sql 块内

Posted

技术标签:

【中文标题】BULK COLLECT INTO 并且只是 INTO 在一个 sql 块内【英文标题】:BULK COLLECT INTO and just INTO inside one sql block 【发布时间】:2019-04-10 07:55:55 【问题描述】:

我的 PL/SQL 存储过程中有一个 SQL 块。此块使用批量收集将值收集到用户定义的类型中。

TYPE risks IS TABLE OF NUMBER;
o_risks risks;

... 

SELECT DISTINCT risk
BULK   COLLECT
INTO   o_risks
FROM   schema.risks
WHERE parent_id = any_id

但我还想将此 SQL 块中的 max(other_column_name) 保存到数字变量中。使用 BULK COLLECT 时可以吗?当然,我可以创建另一个块,但它看起来不正确。

【问题讨论】:

【参考方案1】:

使用CASTCOLLECT

Oracle 设置

CREATE TYPE risks IS TABLE OF NUMBER;
/

CREATE TABLE risk_table ( risk, other_column_name, parent_id ) AS
SELECT 1, 1, 1 FROM DUAL UNION ALL
SELECT 3, 2, 1 FROM DUAL UNION ALL
SELECT 1, 4, 1 FROM DUAL UNION ALL
SELECT 2, 2, 1 FROM DUAL UNION ALL
SELECT 3, 1, 1 FROM DUAL UNION ALL
SELECT 3, 2, 1 FROM DUAL UNION ALL
SELECT 4, 5, 2 FROM DUAL;

PL/SQL

DECLARE
  o_risks             risks;
  o_other_column_name RISK_TABLE.OTHER_COLUMN_NAME%TYPE;
  any_id              RISK_TABLE.PARENT_ID%TYPE := 1;
BEGIN
  SELECT CAST( COLLECT( DISTINCT risk ) AS risks ),
         MAX( other_column_name )
  INTO   o_risks, o_other_column_name
  FROM   risk_table
  WHERE  parent_id = any_id;

  DBMS_OUTPUT.PUT_LINE( 'Max other column name: ' || o_other_column_name );
  FOR i IN 1 .. o_risks.COUNT LOOP
    DBMS_OUTPUT.PUT_LINE( 'Risk ' || i || ': ' || o_risks(i) );
  END LOOP;
END;
/

输出

Max other column name: 4
Risk 1: 1
Risk 2: 2
Risk 3: 3

db小提琴here

如果您使用的版本无法使用 COLLECT( DISTINCT ... ),那么您可以使用 SET( CAST( COLLECT( risk ) AS risks ) ) 获取不同的值。

【讨论】:

我试图弄清楚为什么我的 Oracle 说在SELECT CAST( COLLECT( DISTINCT risk ) AS risks ) 行中出现错误 ORA-00902: invalid datatype while in dbfiddle 一切正常。 似乎是因为我的类型只是在过程中声明,而你的类型是创建的 @РусланХ 是的,您不能在 SQL 范围内使用在 PL/SQL 范围内声明的类型(至少在 Oracle 11g 和更早版本中)。但是,您可以在 SQL 和 PL/SQL 范围内使用在 SQL 范围内声明的类型,因此您需要在 SQL 而不是 PL/SQL 中声明它。 我将使用您的解决方案。答案非常有用且内容丰富。谢谢!

以上是关于BULK COLLECT INTO 并且只是 INTO 在一个 sql 块内的主要内容,如果未能解决你的问题,请参考以下文章

Oracle bulk collect into 的几种用法

在 SELECT ... BULK COLLECT INTO 中使用 LIMIT 选项

2015.1.15 利用Oracle函数插入表结构 Bulk collect into 不用循环,简洁高效

BULK COLLECT INTO inside OPEN cursor FOR SELECT... 不填充集合

ORA-00947 当 UPDATE 返回 BULK COLLECT INTO 用户创建的 TYPE TABLE 时出现“没有足够的值”

ORACLEBulk Processing with BULK COLLECT and FORALL