Oracle程序-PLS-00306:参数的数量或类型错误
我在执行过程时遇到以下错误:Oracle程序-PLS-00306:参数的数量或类型错误,oracle,stored-procedures,Oracle,Stored Procedures,我在执行过程时遇到以下错误: Error starting at line : 1 in command - exec p_matrika(2010,2.5,'26311330') Error report - ORA-06550: line 1, column 7: PLS-00306: wrong number or types of arguments in call to 'P_MATRIKA' ORA-06550: line 1, column 7: PL/SQL: Statement
Error starting at line : 1 in command -
exec p_matrika(2010,2.5,'26311330')
Error report -
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'P_MATRIKA'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
过程编译时没有错误。我还检查了SQL语句,它正常工作,返回1行,所以过程本身肯定有问题。很抱歉,SQL语句的格式有点混乱。我复印粘贴的时候不知怎么搞砸了
create or replace PROCEDURE P_MATRIKA
(
leto IN NUMBER,
rating IN NUMBER,
davcna IN VARCHAR2,
unsec_out OUT NUMBER,
supp_out OUT NUMBER,
sec_out OUT NUMBER,
unsec_limit OUT NUMBER,
supp_limit OUT NUMBER,
sec_limit OUT NUMBER,
unsec_tenor OUT NUMBER,
supp_tenor OUT NUMBER,
sec_tenor OUT NUMBER
)
AS
out_unsec NUMBER;
out_supp NUMBER;
out_sec NUMBER;
limit_unsec NUMBER;
limit_supp NUMBER;
limit_sec NUMBER;
tenor_unsec NUMBER;
tenor_supp NUMBER;
tenor_sec NUMBER;
BEGIN
with
matrika_osnova
as
(
select distinct a.par_davcna, nvl(a.unsecured,0) unsec_out,
nvl(a.supported,0) supp_out, nvl(a.secured,0) sec_out,
x.tip_sub, x.cispri, x.kraban, x.dolfinobv,
y.ltv_tip, y.rating, y.unsec_pct, q.supp_pct,
w.sec_pct, p.unsec_maxznes, s.sec_maxznes,
case when y.unsec_pct * nvl(x.cispri,0) > nvl(p.unsec_maxznes,0) then
nvl(p.unsec_maxznes,0) - nvl(x.kraban,0) + (nvl(x.dolfinobv,0)/5)
else
case when y.unsec_pct * nvl(x.cispri,0) -
nvl(x.kraban,0) + (nvl(x.dolfinobv,0)/5) < 0 then
0
else
y.unsec_pct * nvl(x.cispri,0) - nvl(x.kraban,0) +
(nvl(x.dolfinobv,0)/5)
end
end unsec_max,
case when q.supp_pct * nvl(x.cispri,0) > nvl(s.sec_maxznes,0) then
nvl(s.sec_maxznes,0) - nvl(x.kraban,0) + (nvl(x.dolfinobv,0)/5)
else
case when q.supp_pct * nvl(x.cispri,0) - nvl(x.kraban,0) +
(nvl(x.dolfinobv,0)/5) < 0 then
0
else
q.supp_pct * nvl(x.cispri,0) - nvl(x.kraban,0) +
(nvl(x.dolfinobv,0)/5)
end
end supp_max,
case when w.sec_pct * nvl(x.cispri,0) > nvl(s.sec_maxznes,0) then
nvl(s.sec_maxznes,0) - nvl(x.kraban,0) + (nvl(x.dolfinobv,0)/5)
else
case when w.sec_pct * nvl(x.cispri,0) - nvl(x.kraban,0) +
(nvl(x.dolfinobv,0)/5) < 0 then
0
else
w.sec_pct * nvl(x.cispri,0) - nvl(x.kraban,0) +
(nvl(x.dolfinobv,0)/5)
end
end sec_max,
d.unsec_tenor, e.supp_tenor, f.sec_tenor
from sco_matrika_banka a
inner join
(select b.tip_sub, b.par_davcna, b.cispri, b.kraban, b.dolfinobv
from scoring_gvin b
where b.leto = leto) x --IN parameter
on a.par_davcna = x.par_davcna
inner join
(select a.tip_sub, a.ltv_tip,
a.max_znesek unsec_maxznes
from sco_sif_ltv_maxznes a
where a.ltv_tip = 1) p
on x.tip_sub = p.tip_sub
inner join
(select a.tip_sub, a.ltv_tip,
a.max_znesek sec_maxznes
from sco_sif_ltv_maxznes a
where a.ltv_tip = 3) s
on x.tip_sub = s.tip_sub
inner join
(select a.tip_sub, a.ltv_tip,
a.rating, a.ltv_pct unsec_pct
from sco_sif_ltv_pct a
where a.ltv_tip = 1
and a.rating = rating) y --IN parameter
on x.tip_sub = y.tip_sub
inner join
(select a.tip_sub, a.ltv_tip,
a.rating, a.ltv_pct supp_pct
from sco_sif_ltv_pct a
where a.ltv_tip = 2
and a.rating = rating) q --IN parameter
on x.tip_sub = y.tip_sub
inner join
(select a.tip_sub, a.ltv_tip,
a.rating, a.ltv_pct sec_pct
from sco_sif_ltv_pct a
where a.ltv_tip = 3
and a.rating = rating) w --IN parameter
on x.tip_sub = y.tip_sub
inner join
(select a.tip_sub, a.tenor unsec_tenor
from sco_sif_ltv_tenor a
where a.ltv_tip = 1) d
on x.tip_sub = d.tip_sub
inner join
(select a.tip_sub, a.tenor supp_tenor
from sco_sif_ltv_tenor a
where a.ltv_tip = 2) e
on x.tip_sub = e.tip_sub
inner join
(select a.tip_sub, a.tenor sec_tenor
from sco_sif_ltv_tenor a
where a.ltv_tip = 3) f
on x.tip_sub = f.tip_sub
where a.par_davcna = davcna) --IN parameter
select a.unsec_out, a.supp_out, a.sec_out,
case when a.unsec_max - a.unsec_out < 0 then
0
else
a.unsec_max - a.unsec_out
end unsec_limit,
case when a.supp_max - a.supp_out < 0 then
0
else
a.supp_max - a.supp_out
end supp_limit,
case when a.sec_max - a.sec_out < 0 then
0
else
a.sec_max - a.sec_out
end sec_limit,
a.unsec_tenor, a.supp_tenor, a.sec_tenor
into
out_unsec, out_supp, out_sec, limit_unsec, limit_supp,
limit_sec, tenor_unsec, tenor_supp, tenor_sec
from matrika_osnova a;
unsec_out := out_unsec;
supp_out := out_supp;
sec_out := out_sec;
unsec_limit := limit_unsec;
supp_limit := limit_supp;
sec_limit := limit_sec;
unsec_tenor := tenor_unsec;
supp_tenor := tenor_supp;
sec_tenor := tenor_sec;
END P_MATRIKA;
调用中的参数数量必须与过程规范中的形式参数数量相同,除非参数中有任何默认参数,但这里的情况并非如此。每个OUT参数都必须具有来自调用者的相应变量,才能将值放入。您的过程有12个形式参数。目前,您正在为三个IN参数提供值,但没有提供变量来接受九个OUT参数 您可以使用在与调用相同的匿名块中声明的本地PL/SQL变量,或者-可能更有用,更接近于您的C调用-绑定变量,在SQL*Plus或SQL Developer中,基于您对exec的使用,您可以使用variable命令定义: 例如,您可以在以后的脚本代码中使用bind变量,它们可以通过您在那里的调用在C中使用 虽然SQL开发人员可以半自动化地进行测试,但为测试设置起来有点混乱。它还假设始终只有一个结果,您已经说过是这样,但是如果没有结果或有多个结果,您将从过程中得到一个异常 顺便说一句,您的过程中不需要局部变量;您的查询可以选择直接进入unsec\u out,您不需要单独的中间输出unsec。如果决定保留命名约定,您可能还需要考虑命名约定,例如形式参数的p_out_unsec,局部变量的ans l_out_unsec。使您更容易看到正在使用和修改的内容,您当前的名称很容易混淆 另一种方法是使用ref游标:
create or replace PROCEDURE P_MATRIKA
(
leto IN NUMBER,
rating IN NUMBER,
davcna IN VARCHAR2,
p_refcur OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN p_refcur FOR
... your query
END;
然后,您可以执行以下操作:
var refcur refcursor
exec p_matrika(2010, 2.5, '26311330', :refcur);
print refcur
或者您可以将其设置为返回ref游标的函数。然后,您的C代码可以像对待任何其他结果集一样对待绑定的ref游标。好的,我设法解决了我的问题。或者更好地说,亚历克斯·普尔解决了这个问题,所以他很荣幸:- Oracle存储过程:
create or replace PROCEDURE P_MATRIKA
(
p_leto IN NUMBER,
p_rating IN NUMBER,
p_davcna IN VARCHAR2,
p_refcur OUT SYS_REFCURSOR
)
IS
BEGIN
OPEN p_refcur FOR
with
matrika_osnova
as
(
select distinct a.par_davcna, nvl(a.unsecured,0) unsec_out,
nvl(a.supported,0) supp_out, nvl(a.secured,0) sec_out,
x.tip_sub, x.cispri, x.kraban, x.dolfinobv,
y.ltv_tip, y.rating, y.unsec_pct, q.supp_pct,
w.sec_pct, p.unsec_maxznes, s.sec_maxznes,
case when y.unsec_pct * nvl(x.cispri,0) > nvl(p.unsec_maxznes,0) then
nvl(p.unsec_maxznes,0) - nvl(x.kraban,0) + (nvl(x.dolfinobv,0)/5)
else
case when y.unsec_pct * nvl(x.cispri,0) -
nvl(x.kraban,0) + (nvl(x.dolfinobv,0)/5) < 0 then
0
else
y.unsec_pct * nvl(x.cispri,0) - nvl(x.kraban,0) +
(nvl(x.dolfinobv,0)/5)
end
end unsec_max,
case when q.supp_pct * nvl(x.cispri,0) > nvl(s.sec_maxznes,0) then
nvl(s.sec_maxznes,0) - nvl(x.kraban,0) + (nvl(x.dolfinobv,0)/5)
else
case when q.supp_pct * nvl(x.cispri,0) - nvl(x.kraban,0) +
(nvl(x.dolfinobv,0)/5) < 0 then
0
else
q.supp_pct * nvl(x.cispri,0) - nvl(x.kraban,0) +
(nvl(x.dolfinobv,0)/5)
end
end supp_max,
case when w.sec_pct * nvl(x.cispri,0) > nvl(s.sec_maxznes,0) then
nvl(s.sec_maxznes,0) - nvl(x.kraban,0) + (nvl(x.dolfinobv,0)/5)
else
case when w.sec_pct * nvl(x.cispri,0) - nvl(x.kraban,0) +
(nvl(x.dolfinobv,0)/5) < 0 then
0
else
w.sec_pct * nvl(x.cispri,0) - nvl(x.kraban,0) +
(nvl(x.dolfinobv,0)/5)
end
end sec_max,
d.unsec_tenor, e.supp_tenor, f.sec_tenor
from sco_matrika_banka a
inner join
(select b.tip_sub, b.par_davcna, b.cispri, b.kraban, b.dolfinobv
from scoring_gvin b
where b.leto = p_leto) x --IN parameter
on a.par_davcna = x.par_davcna
inner join
(select a.tip_sub, a.ltv_tip,
a.max_znesek unsec_maxznes
from sco_sif_ltv_maxznes a
where a.ltv_tip = 1) p
on x.tip_sub = p.tip_sub
inner join
(select a.tip_sub, a.ltv_tip,
a.max_znesek sec_maxznes
from sco_sif_ltv_maxznes a
where a.ltv_tip = 3) s
on x.tip_sub = s.tip_sub
inner join
(select a.tip_sub, a.ltv_tip,
a.rating, a.ltv_pct unsec_pct
from sco_sif_ltv_pct a
where a.ltv_tip = 1
and a.rating = p_rating) y --IN parameter
on x.tip_sub = y.tip_sub
inner join
(select a.tip_sub, a.ltv_tip,
a.rating, a.ltv_pct supp_pct
from sco_sif_ltv_pct a
where a.ltv_tip = 2
and a.rating = p_rating) q --IN parameter
on x.tip_sub = y.tip_sub
inner join
(select a.tip_sub, a.ltv_tip,
a.rating, a.ltv_pct sec_pct
from sco_sif_ltv_pct a
where a.ltv_tip = 3
and a.rating = p_rating) w --IN parameter
on x.tip_sub = y.tip_sub
inner join
(select a.tip_sub, a.tenor unsec_tenor
from sco_sif_ltv_tenor a
where a.ltv_tip = 1) d
on x.tip_sub = d.tip_sub
inner join
(select a.tip_sub, a.tenor supp_tenor
from sco_sif_ltv_tenor a
where a.ltv_tip = 2) e
on x.tip_sub = e.tip_sub
inner join
(select a.tip_sub, a.tenor sec_tenor
from sco_sif_ltv_tenor a
where a.ltv_tip = 3) f
on x.tip_sub = f.tip_sub
where a.par_davcna = p_davcna) --IN parameter
select a.unsec_out, a.supp_out, a.sec_out,
case when a.unsec_max - a.unsec_out < 0 then
0
else
a.unsec_max - a.unsec_out
end unsec_limit,
case when a.supp_max - a.supp_out < 0 then
0
else
a.supp_max - a.supp_out
end supp_limit,
case when a.sec_max - a.sec_out < 0 then
0
else
a.sec_max - a.sec_out
end sec_limit,
a.unsec_tenor, a.supp_tenor, a.sec_tenor
from matrika_osnova a;
END;
您的过程有12个参数,您只通过了3个。“你认为输出值会去哪里?”阿列克斯普尔感谢你的迅速回复。我对PL/SQL非常陌生。我的目标是得到一个指定了9个OUT参数的行。您的过程有多个标量OUT参数,您根本不会得到“row”。您计划如何处理通话结果;您将如何使用这些值?您的过程中的查询实际返回多少行—始终是一行?我完全不知道为什么要在这里使用过程,而不是直接运行查询。它假设将值返回到我的C应用程序。是的,总是正好一排。我可以使用内嵌式SQL,但这样SQL每次运行时都必须编译,而存储过程只编译一次,这是不正确的。如果SQL不在缓存中,则对其进行硬解析,如果在缓存中,则进行更快的软解析。该过程的PL/SQL只编译一次,它调用的SQL与直接调用一样,仍然会得到软解析。但是,出于其他原因,比如可维护性等,您可能仍然希望在程序中使用它。Alex,谢谢您的详细回答。很明显,你很有知识,对我来说可能太有知识了:-。我反复阅读了你的答案好几次,试图使用你的解决方案,但都无法奏效。可能-由于我缺乏知识-我没有正确使用您建议的实现。在你的帮助下,我还是不能让它工作。我不明白在我的C代码中,带1个OUT参数的过程是如何像预期的那样工作的,但当我包含超过1个OUT参数时,它就不工作了。在C语言中,我只是在CommandText中使用SP,设置输入和输出参数,它就可以工作了。在SQL*Plus/SQL Developer中它对您有用吗?在C语言中,您需要设置所有9个输出参数(方向正确),并在命令文本中为它们设置正确数量的绑定占位符。如果它在SQL*Plus中使用wotk,但在C中仍然无法正确调用,那么最好提出一个新问题,说明过程规范和您在C代码方面的最佳尝试,以及您仍然遇到的错误。设置正确的标记不,我无法在SQL Developer中工作,也无法在C中工作。也许我的方法从一开始就是错误的。本质上,我需要的是一个过程或函数,将我的SQL语句结果返回给我的C应用程序,即:1行9个字段,如OUT参数中指定的。但是亚历克斯,尽管如此,我还是要感谢你为帮助我所做的一切努力。非常感谢。当心。@Flin-如果您想返回一行,请使用ref游标方法 . 作为过程put参数或函数返回值。。。
create or replace PROCEDURE P_MATRIKA
(
p_leto IN NUMBER,
p_rating IN NUMBER,
p_davcna IN VARCHAR2,
p_refcur OUT SYS_REFCURSOR
)
IS
BEGIN
OPEN p_refcur FOR
with
matrika_osnova
as
(
select distinct a.par_davcna, nvl(a.unsecured,0) unsec_out,
nvl(a.supported,0) supp_out, nvl(a.secured,0) sec_out,
x.tip_sub, x.cispri, x.kraban, x.dolfinobv,
y.ltv_tip, y.rating, y.unsec_pct, q.supp_pct,
w.sec_pct, p.unsec_maxznes, s.sec_maxznes,
case when y.unsec_pct * nvl(x.cispri,0) > nvl(p.unsec_maxznes,0) then
nvl(p.unsec_maxznes,0) - nvl(x.kraban,0) + (nvl(x.dolfinobv,0)/5)
else
case when y.unsec_pct * nvl(x.cispri,0) -
nvl(x.kraban,0) + (nvl(x.dolfinobv,0)/5) < 0 then
0
else
y.unsec_pct * nvl(x.cispri,0) - nvl(x.kraban,0) +
(nvl(x.dolfinobv,0)/5)
end
end unsec_max,
case when q.supp_pct * nvl(x.cispri,0) > nvl(s.sec_maxznes,0) then
nvl(s.sec_maxznes,0) - nvl(x.kraban,0) + (nvl(x.dolfinobv,0)/5)
else
case when q.supp_pct * nvl(x.cispri,0) - nvl(x.kraban,0) +
(nvl(x.dolfinobv,0)/5) < 0 then
0
else
q.supp_pct * nvl(x.cispri,0) - nvl(x.kraban,0) +
(nvl(x.dolfinobv,0)/5)
end
end supp_max,
case when w.sec_pct * nvl(x.cispri,0) > nvl(s.sec_maxznes,0) then
nvl(s.sec_maxznes,0) - nvl(x.kraban,0) + (nvl(x.dolfinobv,0)/5)
else
case when w.sec_pct * nvl(x.cispri,0) - nvl(x.kraban,0) +
(nvl(x.dolfinobv,0)/5) < 0 then
0
else
w.sec_pct * nvl(x.cispri,0) - nvl(x.kraban,0) +
(nvl(x.dolfinobv,0)/5)
end
end sec_max,
d.unsec_tenor, e.supp_tenor, f.sec_tenor
from sco_matrika_banka a
inner join
(select b.tip_sub, b.par_davcna, b.cispri, b.kraban, b.dolfinobv
from scoring_gvin b
where b.leto = p_leto) x --IN parameter
on a.par_davcna = x.par_davcna
inner join
(select a.tip_sub, a.ltv_tip,
a.max_znesek unsec_maxznes
from sco_sif_ltv_maxznes a
where a.ltv_tip = 1) p
on x.tip_sub = p.tip_sub
inner join
(select a.tip_sub, a.ltv_tip,
a.max_znesek sec_maxznes
from sco_sif_ltv_maxznes a
where a.ltv_tip = 3) s
on x.tip_sub = s.tip_sub
inner join
(select a.tip_sub, a.ltv_tip,
a.rating, a.ltv_pct unsec_pct
from sco_sif_ltv_pct a
where a.ltv_tip = 1
and a.rating = p_rating) y --IN parameter
on x.tip_sub = y.tip_sub
inner join
(select a.tip_sub, a.ltv_tip,
a.rating, a.ltv_pct supp_pct
from sco_sif_ltv_pct a
where a.ltv_tip = 2
and a.rating = p_rating) q --IN parameter
on x.tip_sub = y.tip_sub
inner join
(select a.tip_sub, a.ltv_tip,
a.rating, a.ltv_pct sec_pct
from sco_sif_ltv_pct a
where a.ltv_tip = 3
and a.rating = p_rating) w --IN parameter
on x.tip_sub = y.tip_sub
inner join
(select a.tip_sub, a.tenor unsec_tenor
from sco_sif_ltv_tenor a
where a.ltv_tip = 1) d
on x.tip_sub = d.tip_sub
inner join
(select a.tip_sub, a.tenor supp_tenor
from sco_sif_ltv_tenor a
where a.ltv_tip = 2) e
on x.tip_sub = e.tip_sub
inner join
(select a.tip_sub, a.tenor sec_tenor
from sco_sif_ltv_tenor a
where a.ltv_tip = 3) f
on x.tip_sub = f.tip_sub
where a.par_davcna = p_davcna) --IN parameter
select a.unsec_out, a.supp_out, a.sec_out,
case when a.unsec_max - a.unsec_out < 0 then
0
else
a.unsec_max - a.unsec_out
end unsec_limit,
case when a.supp_max - a.supp_out < 0 then
0
else
a.supp_max - a.supp_out
end supp_limit,
case when a.sec_max - a.sec_out < 0 then
0
else
a.sec_max - a.sec_out
end sec_limit,
a.unsec_tenor, a.supp_tenor, a.sec_tenor
from matrika_osnova a;
END;
public void LoadMatrika(string davcna)
{
using (OracleConnection conn = CreateConnection())
{
using (OracleCommand cmd = new OracleCommand())
{
cmd.Connection = conn;
cmd.CommandText = "P_MATRIKA";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new OracleParameter("p_leto", Util.letoc));
cmd.Parameters.Add(new OracleParameter("p_rating", Score.Rating));
cmd.Parameters.Add(new OracleParameter("p_davcna", davcna));
cmd.Parameters.Add(new OracleParameter("p_refcur", OracleDbType.RefCursor, ParameterDirection.Output));
cmd.BindByName = true;
using (OracleDataReader dr = cmd.ExecuteReader())
{
if (dr.HasRows)
{
dr.Read();
Matrika.UnsecuredOut = dr.GetDecimal(0);
Matrika.SupportedOut = dr.GetDecimal(1);
Matrika.SecuredOut = dr.GetDecimal(2);
Matrika.UnsecuredLimit = dr.GetDecimal(3);
Matrika.SupportedLimit = dr.GetDecimal(4);
Matrika.SecuredLimit = dr.GetDecimal(5);
Matrika.UnsecuredTenor = dr.GetDecimal(6);
Matrika.SupportedTenor = dr.GetDecimal(7);
Matrika.SecuredTenor = dr.GetDecimal(8);
}
}
}
}
}