【问题标题】:PLS-00312: a positional parameter association may not follow a named associationPLS-00312:位置参数关联可能不遵循命名关联
【发布时间】:2019-03-06 06:01:18
【问题描述】:

有谁知道我可以如何避免这里的 PLS-00312 错误?

“PLS-00312:位置参数关联可能不遵循命名关联”

我得到这个是因为下面一行:

AttachList=> v_est_proc_name||'_EST_PROC.csv',v_prd_segs||'_PRD_SEGS.csv',

在以下过程中:

create or replace procedure send_csv as

v_tomail varchar2(40);
v_est_proc_name varchar2(40);
v_prd_segs varchar2(40); 

cursor c1 is
SELECT email_address
INTO v_tomail
FROM mail where
mdate = (select max(mdate) FROM blah)
group by email_address  
order by max(mdate) desc;

begin
open c1;
fetch c1 into v_tomail;

SELECT tablename into v_est_proc_name
FROM blah_blah
WHERE
CREATED_AT = (select MAX(CREATED_AT) from blah);

SELECT tablename into v_prd_segs
FROM blah_blah
WHERE
CREATED_AT = (select MAX(CREATED_AT) from blah);

mail.send_mail.send(
ToList=> v_tomail,
Subject=> 'see attachments',
Body=> 'Please action the attached files for this request.',
FromEmail=> 'donotreply@mail.com', 
FromHost=> 'host',
SMTPServer=> 'host',
AttachList=> v_est_proc_name||'_EST_PROC.csv',v_prd_segs||'_PRD_SEGS.csv',

Directory=> 'CSV_DIR');
End;

我只是不知道如何摆脱它......一定有办法。

【问题讨论】:

    标签: sql database oracle plsql


    【解决方案1】:

    该消息是不言自明的。

    假设你有一个过程或一个函数(具体说是一个过程)my_proc,有四个参数:

    my_proc(param1, param2, param3, param4)
    

    给定四个参数的值arg1, arg2, arg3, arg4,您可以像这样调用该过程:

    my_proc(arg1, arg2, arg3, arg4)
    

    -- 这使用 positional 参数关联。参数的顺序是有意义的。

    你也可以这样称呼它:

    my_proc(param1 => arg1, param3 => arg3, param2 => arg2, param4 => arg4)
    

    -- 这使用 named 参数关联。 “关联”的顺序不再有意义 - 只要您将正确的参数与正确的参数名称配对,您就可以按照您喜欢的任何顺序放置分配(关联)。

    您也可以混合使用它们,但您只能先使用位置关联,然后再使用命名关联。这是合法的:

    my_proc(arg1, arg2, param4 => arg4, param3 => arg3)
    

    但这是非法的:

    my_proc(arg1, param3 => arg3, param2 => arg2, arg4)
    

    这有很好的理由,但理由无关紧要;这是您的代码必须遵循的语法要求,即使没有充分的理由。

    在你的代码中,所有的关联都被命名了,除了参数(值)

    v_prd_segs||'_PRD_SEGS.csv'
    

    没有分配给特定的命名参数。

    要修复它,请使用应接受此参数的参数名称,就像对所有其他参数所做的那样。

    【讨论】:

    • 在我的代码中,我尝试使用变量 v_prd_segs 和 v_est_proc_name,但只是带有一些文本标记......从这里的解释看来(谢谢!!)我不能在这里的 pl/sql 中执行此操作,我必须使用整个声明的变量。有没有办法真正声明整个事情,例如 v_est_proc_name||'_EST_PROC.csv' 作为变量并这样做?
    【解决方案2】:

    在此处查看您所说的:

    AttachList=> v_est_proc_name||'_EST_PROC.csv',v_prd_segs||'_PRD_SEGS.csv',

    粗体部分被视为 mail.send_mail.send() 的单个参数,但它前面没有参数名称,就像所有其他参数一样,所以 oracle 不知道哪个参数应该是为了

    提供该数据应该是哪个参数的名称。如果您尝试发送多个附件,我认为它应该是一个逗号分隔的字符串,但您的逗号不在任何字符串之外,oracle 认为它是一个分隔函数参数列表(两个参数)的逗号

    尝试类似:

    AttachList=> v_est_proc_name||'_EST_PROC.csv,'||v_prd_segs||'_PRD_SEGS.csv',
    

    这会将逗号分隔字符串内的文件名

    这个错误基本上意味着“如果你把位置参数放在第一位然后切换到命名,你只能混合位置参数和命名参数”

    对于函数:

    F(a, b, c)
    
    --these are ok
    F(1,2,3). --positional arguments go in order
    F(c=> 3, b=> 2, a=> 1) --named arguments any order
    F(1. c=> 3, b=> 2) --mixed, a is 1 in order, other two are any order
    
    --going back to using positional after you started using names is not ok
    F(b=> 2, 1, 3)
    

    在最后一个例子中这是一个错误,因为 oracle 无法自行决定 A 是 1 还是 3(因此 C 是 3 或 1)

    编辑:

    好的,可能我使用 SQLS 太久了,忘记了我的 Oracle。如果你断言你不能将 concat 值串在一起作为一个参数(即你必须先将它们存储在一个变量中),为什么不试试这个:

    SELECT tablename||'_EST_PROC.csv,' into v_est_proc_name
    FROM blah_blah
    WHERE
    CREATED_AT = (select MAX(CREATED_AT) from blah);
    
    SELECT v_est_proc_name||tablename||'_PRD_SEGS.csv' into v_est_proc_name
    FROM blah_blah
    WHERE
    CREATED_AT = (select MAX(CREATED_AT) from blah);
    
    mail.send_mail.send(
    ToList=> v_tomail,
    Subject=> 'see attachments',
    Body=> 'Please action the attached files for this request.',
    FromEmail=> 'donotreply@mail.com', 
    FromHost=> 'host',
    SMTPServer=> 'host',
    AttachList=> v_est_proc_name,
    

    您可能还可以考虑更大的字符串(40 有点小?)和更好的名称。我已经尝试对此进行测试,但我没有实时的 oracle 实例,并且在使各种小提琴站点创建功能方面没有任何成功..

    【讨论】:

    • 感谢您的解释。欣赏它!我用逗号试过,不被接受
    • 进行了编辑以尝试提供帮助,但我不太清楚“不接受”是什么意思
    • Ps 我用这个网站oracletool.com/blog/?p=64 断言附加的多个文件是用逗号分隔的——我自己从来没有使用过这个包,只是从那篇文章中获得了如何附加多个文件的知识
    【解决方案3】:

    再试试看这一行:

    AttachList=> v_est_proc_name||'_EST_PROC.csv',v_prd_segs||'_PRD_SEGS.csv',
    

    它的两个参数不是一个。

    AttachList=> v_est_proc_name||'_EST_PROC.csv',
    ????      => v_prd_segs||'_PRD_SEGS.csv',
    

    尝试找到应该与???匹配的参数名称在 mail.send_mail.send 过程中。

    【讨论】:

      猜你喜欢
      • 2018-06-11
      • 2020-11-18
      • 2017-06-29
      • 1970-01-01
      • 2022-11-03
      • 2017-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多