【问题标题】:Call a stored procedure, into another stored procedure调用一个存储过程,进入另一个存储过程
【发布时间】:2013-03-08 05:45:33
【问题描述】:

我有一个程序,可以在我的一张表中插入一行。

过程中的INSERT之后,我想把所有的行找出到另一个表中,然后,调用第二个表的插入过程。

所以我的第一个程序可以正常工作

P_INSERT_TABLE1

INSERT INTO TABLE1

...
COMMIT;

FOR record_po IN (SELECT C3, ...
                    FROM T_TABLE2
                    WHERE id = v_id)
LOOP
      P_INSERT_TABLE2(record_po.C3, ...);
END LOOP;

P_INSERT_TABLE2 的所有“in 参数”都是 VARCHAR2,所以我为每一列都创建了一个“to_char”不是 varchar2:

P_INSERT_TABLE2(pi_id,
                      record_po.C3,
                      record_po.C4,
                      record_po.C5,
                      record_po.C6,
                      record_po.C7,
                      to_char(record_po.C8, 'DD/MM/YYYY');

这里,pi_id 是 P_INSERT_TABLE1 的 in 参数之一,在 VARCHAR2 中。

所以现在,我收到了这个错误信息:

Erreur(357,1): PLS-00306: number or args types wrong in the call of P_INSERT_TABLE2

我不明白,为什么 P_INSERT_TABLE2 不接受参数,而所有好的类型都按好顺序?

如果我调用像“call P_INSERT_TABLE2(...)”这样的过程,我会遇到如下错误:

Erreur(357,9): PLS-00103: Symbol "P_INSERT_TABLE2" instead one of this symbols :     := . ( @ % ; immediate Symbole ":=" 

create or replace
PROCEDURE P_INSERT_TABLE2 (
  pi_id          IN VARCHAR2
  ,pi_C3         IN VARCHAR2
  ,pi_C4         IN VARCHAR2
  ,pi_C5         IN VARCHAR2
  ,pi_C6         IN VARCHAR2
  ,pi_C7         IN VARCHAR2
  ,pi_C8         IN VARCHAR2
  ,pmessage      OUT NOCOPY VARCHAR2  
) 

感谢您的帮助。

【问题讨论】:

  • 能否添加 P-INSERT-TABLE2 的声明,好吗?顺便说一句:请不要在过程名称中使用“-” - 这非常令人困惑;我不相信这是您的真实代码,因为除非正确引用,否则 Oracle 不会接受包含“-”的表名和过程名。
  • 是的,代码太长了,所以我用 C1 等替换了名称列...并将表名和过程替换为通用名称。
  • 你的 OUT 参数怎么样?当您从 P_INSERT_TABLE1 调用时,您是否发送该信息?
  • 我还有 P_INSERT_TABLE1 的输出参数。它没有被调用。我只是在里面放了一段文字。我在 P_INSERT_TABLE2 中有 7 个 IN 参数,当我调用 IT 时我给出了 7 个 IN 参数;
  • @Jean 无论您是否要实际使用它,都必须在对 P_INSERT_TABLE2 的函数调用中定义它。

标签: sql oracle stored-procedures oracle-sqldeveloper


【解决方案1】:

P_INSERT_TABLE2 的声明无效。不能有 5 个输入参数都命名为 pi_C4。由于您在创建该过程时没有遇到编译错误,我猜这是在此处发布问题时引入的错误,而不是代码中实际存在的问题。

根据P_INSERT_TABLE2的声明,该过程有7个输入参数和1个输出参数。在您发布的代码中,您似乎传递了 7 个输入参数,但您没有传递输出参数的变量。看来您需要类似的东西

P_INSERT_TABLE2(pi_id,
                record_po.C3,
                record_po.C4,
                record_po.C5,
                record_po.C6,
                record_po.C7,
                to_char(record_po.C8, 'DD/MM/YYYY'),
                <<some local variable for the output parameter>> );

除了语法错误之外,当我看到有人使用非常好的DATE,将其转换为字符串,然后将其传递给程序时,我非常怀疑。这意味着P_INSERT_TABLE2 将转身并将字符串转换回日期,这意味着您正在做额外的工作并引入了转换可能失败的额外点,或者您将要编写字符串将日期表示为表格。这些影响都不好。

我也高度怀疑任何具有名为pMessageOUT 参数的过程。这往往意味着您没有正确使用异常,并且如果您的代码遇到错误,您将返回错误消息而不是抛出异常。与使用适当的异常相比,这几乎总是会导致更脆弱的代码更难调试。

【讨论】:

  • 确实,我之后将字符串转换回来,但这是因为在其他情况下我需要 P_INSERT_TABLE2 。所以我必须这样做。我使用异常,但 pmessage 可能是好是错,所以我将它显示到我的 silverlight 视图中(成功消息或失败消息)。这就是我使用 OUT 参数和 Exception 的原因。
  • 谢谢你现在工作正常。我在想我不需要在通话中使用 OUT 参数。现在我会知道的。
猜你喜欢
  • 2014-09-17
  • 1970-01-01
  • 2010-11-14
  • 1970-01-01
  • 2011-05-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多