PL/SQL:如何从表中选择数据并输入到包接受数组类型?

Posted

技术标签:

【中文标题】PL/SQL:如何从表中选择数据并输入到包接受数组类型?【英文标题】:PL/SQL: How select data from table and input into package accepting array type? 【发布时间】:2013-05-08 15:06:37 【问题描述】:

我有一个 PL/SQL 电子邮件包,如下所示:

create or replace package mail_pkg 
as
PRAGMA SERIALLY_REUSABLE; -- this avoids ORA-04068 error
type array is table of varchar2(255);

procedure send( p_sender_email in varchar2,
            p_from         in varchar2 default null,
            p_to           in array default array(),
            p_cc           in array default array(),
            p_bcc          in array default array(),
            p_subject      in varchar2 default null,
            p_body         in clob default null);

示例用法如下:

 begin
    mail_pkg.send( p_sender_email => 'tim@company1.com',
               p_from => 'John Smith <johns@company2.com>',
               p_to => mail_pkg.array( 'greg@company3.com','sarah@company4.com'),
               p_cc => mail_pkg.array( 'admin@company5.com' ), 
               p_bcc => mail_pkg.array( 'sue@company5.com' ), 
               p_subject => 'This is my subject', 
               p_body => 'Hello, this is the mail you requested.' );
    end;

[注意:对于任何寻找电子邮件包的人,这是我从中获得的链接: http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:255615160805]

我想用它来发送电子邮件,但是p_to输入中的电子邮件地址必须是动态输入的。也就是说,我不能像上面那样对它们进行硬编码。它们需要来自 SELECT 语句。我熟悉编写 select 语句,但我不知道如何将 selecte 语句的结果转换为可以包含在

中的格式
p_to => mail_pkg.array( WHAT GOES HERE??? ),

代码。

有人知道我如何连接一个 SELECT 语句(返回一些电子邮件地址)来使用这个包吗?

更新:

根据以下反馈,解决方案是:

create or replace procedure send_email ( 
  in_name IN varchar2
 )

AS

v_body clob;  
v_to_array mail_pkg.array := mail_pkg.array();
v_counter int := 1;

BEGIN

FOR r IN (SELECT person_email FROM email_table WHERE company_name=in_name) LOOP
  v_to_array.extend;
  v_to_array(v_counter) := r.person_email;
  v_counter := v_counter +1;
END LOOP;

-- send email

mail_pkg.send( p_sender_email => 'sam@company2.com',
               p_from => 'admin@company2.com',
               p_to => v_to_array,
               p_bcc => mail_pkg.array( 'tim@company3.com' ), 
               p_subject => 'the subject line goes here', 
               p_body => 'This is the body message.' );  

END send_email;

【问题讨论】:

【参考方案1】:

您可以分两步完成。第一步是在循环中使用SELECT 语句并填充数组;第二步是在调用mail_pkg.send 时使用该数组,可能是这样的:

declare
  v_counter number := 1;
  v_to_arr mail_pkg.array := mail_pkg.array();
begin
  for r in Select email_address from table_of_email_addresses loop
    v_to_arr.extend;
    v_to_arr(v_counter) := r.email_address;
    v_counter := v_counter +1;
  end loop;

  mail_pkg.send(p_to => v_to_arr, ... );
  --note: this code may require some fine-tuning.
  ...
end ;

正如 cmets 中所建议的,这里可能会使用批量收集,可能很简单:

declare
  v_to_arr mail_pkg.array := mail_pkg.array();
begin

  Select email_address
  bulk collect into v_to_arr
  from table_of_email_addresses;

  mail_pkg.send(p_to => v_to_arr, ... );
  --note: this code may require some fine-tuning.
  ...
end ;

我对批量操作有点生疏,您可能想自己阅读它们。

【讨论】:

非常感谢 FrustratedWithFormsDes,我收到编译错误:PLS-00306: wrong number or types of arguments in call to 'SEND'。知道它可能是什么吗? (我将更新我上面的原始帖子以显示我当前的代码是什么样的......) @ggkmath:这可能是因为我没有完成函数调用——我懒得复制/粘贴您的所有参数。 :P @ggkmath:好的,我还更新以确保v_to_arr 的类型为mail_pkg.array。如果存在可能与mail_pkg.array 不兼容的全局定义类型array 就是这样!现在编译很好。非常感谢!!!!!我更新了 UPDATE 部分以显示最终代码。 为什么不直接SELECT ... BULK COLLECT INTO

以上是关于PL/SQL:如何从表中选择数据并输入到包接受数组类型?的主要内容,如果未能解决你的问题,请参考以下文章

创建带有 2 个游标、一个参数并从表中给出结果的 PL/SQL 脚本?

PL/SQL - 如何从连接表中返回单行

检查后从表中返回值的 PL/SQL 函数

如何使用 pl/sql 循环接受用户输入?

如何使用 pl sql 过程从结构仅在运行时知道的 oracle 表中动态获取数据?

输入对象数组作为输入并返回一个数组作为存储过程的输出