我必须执行Oracle存储
来自vba(Excel)的过程,包含大约38个输入参数。该
存储过程将插入一些
执行后,目标表中的值。当通过VBA执行时,插入的字段数较少
而不是直接执行
来自后端(oracle)。
例如,它在执行时创建大约17个记录字段 直接从后端。 (我有 在。中创建了一个包装类 后端和传递相同 后端的参数值。它创造了大约15个领域 从执行中执行记录 excel目的地表中的VBA。
请让我知道可能的原因是什么。
答案 0 :(得分:0)
调试我们自己的代码很难,远程调试别人的代码实际上是不可能的。我们可以做的是为您提供一些指导,帮助您调试代码。
基本上,当从具有相同参数的不同客户端调用时,相同的代码以两种不同的方式运行。最可能的解释是VBA调用没有传递您认为的参数值 - 可能存在错误命名的单元格或隐式数据类型转换 - 但唯一的方法是在代码中构建一些跟踪。这意味着只需从代码内部编写调试消息。
令人遗憾的常见方法是使用DBMS_OUTPUT,AKA The Devil's Debugger。这将写入屏幕,该屏幕会根据您的方案对其进行规则,因为您要从VBA调用该过程。因此,您可以使用UTL_FILE或LOG_TABLE写入文件。使用日志表可能比写入操作系统文件更具性能,但它更容易使用(至少如果您对SQL比sed
和grep
更满意。)< / p>
粗略的跟踪实现看起来像这样。使用AUTONOMOUS_TRANSACTION是可选的,但它保证了在主程序抛出异常的情况下的跟踪记录;它还允许您实时监控输出。
create or replace procedure your_proc
(p1 in number
, p2 in varchar2
...
, p38 in date)
is
....
procedure write_log
(p_action in varchar2
, p_add_text in varchar2 := null)
is
pragma autonomous_transaction;
begin
insert into log_table
(id, ts, action, add_text)
values
(log_seqno.nextval, systimestamp, p_action, p_add_text);
commit;
end write_log ;
begin
write_log ('YOUR_PROC::START', user);
write_log ('YOUR_PROC::PARAM', 'P1='||to_char(p1));
write_log ('YOUR_PROC::PARAM', 'P2='||p2);
....
write_log ('YOUR_PROC::PARAM', 'P32='||to_char(p32));
...
-- main body of procedure happens here
...
write_log ('YOUR_PROC::END');
exception
when some_exception then
write_log ('YOUR_PROC::EXCEPTION='||some_exception);
raise;
end your_proc;
除了记录参数的值之外,您还需要记录程序流中的阶段,尤其是注意循环和条件;开关(IF .. ELSE,CASE等)。
两次运行程序,一次从VBA运行,一次从SQL * Plus运行。然后比较两组输出。如果它们不同,那就是你回答。
答案 1 :(得分:0)
我最好的猜测是,您从VBA发送的命令与您在运行SQLPlus或其他任何内容时发送的命令不同。 我要做的是让你正在运行的任何VBA程序调用Oracle Stored Procedure输出它发送的实际命令。 我在发送命令时遇到了愚蠢的问题: storedproc(p1,p2,p3) 从一个工具和 storedproc(p1,p2,p3,p4) 从另一个或 storedproc(p1,p3,p2) 因为我错误地建立了我的命令(或类似的原因)。 您也可能会发送不同的值 无论如何,如果您可以接受VBA发送的命令并将其与您“手动”运行的任何命令进行比较,您应该看到问题。 (另外,你是否在两种情况下都以同一个用户身份连接?)