PLS-00312:位置参数关联可能不遵循命名关联
Posted
技术标签:
【中文标题】PLS-00312:位置参数关联可能不遵循命名关联【英文标题】:PLS-00312: a positional parameter association may not follow a named association 【发布时间】:2019-03-06 06:01:18 【问题描述】:有谁知道我可以如何避免这里的 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;
我只是不知道如何摆脱它......一定有办法。
【问题讨论】:
【参考方案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 过程中。
【讨论】:
以上是关于PLS-00312:位置参数关联可能不遵循命名关联的主要内容,如果未能解决你的问题,请参考以下文章
eplan,如何让中断点关联只显示高层代号,不显示位置代号?
"当前不会命中断点,没有与此行关联的可执行代码"可能和"断点位置不准确"有关