【发布时间】:2015-09-25 11:08:14
【问题描述】:
我正在尝试在 Oracle 11g 数据库中执行包和函数。 我有以下代码,但是在第一个 .Execute 命令时出现错误。
VBA 中的 Locals 窗口给出了以下关于错误的信息:
Description : "Unspecified error" : String
Number : -2147467259 : Long
Source : "OraOLEDB" : String
哦,我已经引用了 Microsoft ActiveX 数据对象 6.1 库。
我尝试了对代码的各种更改,但是它们都返回相同的错误消息。
Sub QueryGLComb()
Dim OraCon As ADODB.Connection
Dim recset As New ADODB.Recordset
Dim cmd As New ADODB.Command
Dim objErr As ADODB.Error
Dim lngRow As Long
On Error GoTo err_test
Set OraCon = CreateObject("ADODB.Connection")
OraCon.ConnectionString = "Provider=OraOLEDB.Oracle;" & _
"Data Source=DEMO;" & _
"User ID=scott;" & _
"Password=tiger;"
OraCon.Open
Set cmd = New ADODB.Command
Set cmd.ActiveConnection = OraCon
If OraCon.State = adStateClosed Then
MsgBox "false"
End If
With cmd
.ActiveConnection = OraCon
.CommandText = "fnd_flex_keyval.validate_segs"
.CommandType = adCmdStoredProc
.CommandTimeout = 60
.Parameters.Append .CreateParameter("return", adBoolean, adParamReturnValue)
.Parameters.Append .CreateParameter("operation", adVariant, adParamInput, , "CHECK_COMBINATION")
.Parameters.Append .CreateParameter("appl_short_name", adVariant, adParamInput, , "SQLGL")
.Parameters.Append .CreateParameter("key_flex_code", adVariant, adParamInput, , "GL#")
.Parameters.Append .CreateParameter("structure_number", adNumeric, adParamInput, , "50268")
.Parameters.Append .CreateParameter("concat_segments", adVariant, adParamInput, , "67000.2400.4001.01")
.Parameters.Append .CreateParameter("validation_date", adVariant, adParamInput, , "sysdate")
.Execute
End With
Set cmd = New ADODB.Command
Set cmd.ActiveConnection = OraCon
With cmd
.ActiveConnection = OraCon
.CommandText = "begin FND_FLEX_KEYVAL.ERROR_MESSAGE"
.CommandType = adCmdStoredProc
.Parameters.Append .CreateParameter("message", adVariant, adParamReturnValue)
.Execute
End With
MsgBox "Return Message = " & cmd.Parameters(0)
OraCon.Close
err_test:
MsgBox Error$
For Each objErr In OraCon.Errors
MsgBox objErr.Description
Next
OraCon.Errors.Clear
Resume Next
End Sub
第一个“.Execute”行是发生错误的地方。
这是我在 SQLDeveloper/Toad 中使用的 Oracle 代码。我调用的包是“FND_FLEX_VALIDATE”,函数是“VALIDATE_SEGS”。这是 Oracle eBS 中的一个 Oracle 提供的软件包。如果对 fnd_flex_keyval.validate_segs 的初始调用返回 true,那么一切都很好。如果它返回错误,那么我们必须调用“FND_FLEX_KEYVAL.ERROR_MESSAGE”来检索错误消息。
DECLARE
l_return boolean;
l_message varchar2(240);
BEGIN
l_return := fnd_flex_keyval.validate_segs(operation => 'CHECK_COMBINATION'
,appl_short_name => 'SQLGL'
,key_flex_code => 'GL#'
,structure_number => 50268 --- Pass your chart of accounts id
,concat_segments => '67000.2400.4001.01' --- Pass your account combination string you want to create
,validation_date => sysdate); --- effective date by which you want the combination to be validated
l_message := FND_FLEX_KEYVAL.ERROR_MESSAGE;
If l_return THEN
dbms_output.put_line('Valid');
Else
dbms_output.put_line(l_message);
End if;
END;
我创建了一个新文件进行测试。我现在尝试执行的过程有 3 个参数:1 输入,2 输出。同样,当代码到达 .Execute 命令时,我仍然收到相同的错误。
Sub ExecutePackageP()
Dim OraCon As New ADODB.Connection
Dim recset As New ADODB.Recordset
Dim cmd As New ADODB.Command
Dim objErr As ADODB.Error
Dim lngRow As Long
On Error GoTo err_test
Set OraCon = CreateObject("ADODB.Connection")
OraCon.ConnectionString = "Provider=OraOLEDB.Oracle;" & _
"Data Source=demo;" & _
"User ID=scott;" & _
"Password=tiger;"
OraCon.Open
cmd.ActiveConnection = OraCon
If OraCon.State = adStateClosed Then
MsgBox "false"
End If
With cmd
.ActiveConnection = OraCon
.CommandType = adCmdStoredProc
.CommandText = "XXX_VALIDATE_ACCOUNT"
.CommandTimeout = 60
.Parameters.Append .CreateParameter("param1", adVariant, adParamInput, , "67000.2400.4001.01")
.Parameters.Append .CreateParameter("param2", adBoolean, adParamOutput)
.Parameters.Append .CreateParameter("param3", adVariant, adParamOutput)
.Execute
End With
MsgBox "Reurtn = P_CCID=" & cmd.Parameters(1) & "; P_RESULT=" & cmd.Parameters(2) & ";"
OraCon.Close
End sub
我将参数类型从 adVariant 更改为 adVarchar,并收到一条错误消息,指出 Parameter 对象定义不正确。只有 adVariant 似乎有效。我记得有一个网站显示了针对不同数据库执行时要使用的类型,它说 varchar2 使用 adVariant。 添加 xxx_validate_account 的过程代码:(注意,此过程调用一个名为 fnd_flex_ext.get_ccid 的内部 oracle 函数)
CREATE OR REPLACE PROCEDURE APPS."XXX_VALIDATE_ACCOUNT" (p_account_flex in varchar2,
p_valid out boolean,
p_message out varchar2) is
x_structure_id number;
x_ccid number := 0;
pragma autonomous_transaction;
begin
execute immediate 'alter session set nls_language = ''AMERICAN''';
p_valid := false;
select chart_of_accounts_id
into x_structure_id
from gl_ledgers
where short_name = 'XXX';
x_ccid := fnd_flex_ext.get_ccid(application_short_name => 'SQLGL',
key_flex_code => 'GL#',
structure_number => x_structure_id,
validation_date => to_char(sysdate,'YYYY/MM/DD HH24:MI:SS'),
concatenated_segments => p_account_flex);
if x_ccid > 0 then
p_valid := true;
commit;
else
p_valid := false;
p_message := fnd_message.get;
end if;
exception when others then
p_message := sqlerrm;
p_valid := false;
end xxx_validate_account;
/
更新:2015 年 9 月 25 日: 不幸的是,由于其他软件包和应用程序正在使用它,我无法更新该软件包。 因此,我决定创建一个具有简单功能的新包。 我确保输入和输出不是布尔值以消除该问题。 不过,对于我的生活,我仍然遇到同样的问题! 我尝试在参数字符串中使用“adVarchar,100”,但 excel 只是不断告诉我参数类型错误。认真地认为我的机器有某种问题......
要遵循的新功能和代码:
create or replace package apps.xxxx_return_username is
function return_username (p_user_id in number) return varchar2;
end xxxx_return_username;
/
create or replace package body apps.xxxx_return_username as
function return_username(p_user_id in number) return varchar2 is
x_user_name varchar2(100);
begin
select user_name into x_user_name
from apps.fnd_user where user_id = p_user_id;
return x_user_name;
exception
when no_data_found then return 'xxxxx';
end return_username;
end xxxx_return_username;
/
Sub newfunctioncall()
Dim OraCon As New ADODB.Connection
Dim recset As New ADODB.Recordset
Dim cmd As New ADODB.Command
Set OraCon = CreateObject("ADODB.Connection")
OraCon.ConnectionString = "Provider=OraOLEDB.Oracle;" & _
"Data Source=demo;" & _
"User ID=scott;" & _
"Password=tiger;"
OraCon.Open
Set cmd = New ADODB.Command
Set cmd.ActiveConnection = OraCon
If OraCon.State = adStateClosed Then
MsgBox "false"
End If
Set param1 = cmd.CreateParameter("param1", adNumeric, adParamInput, , "15483")
cmd.Parameters.Append param1
Set param2 = cmd.CreateParameter("param2", adVariant, , adParamReturnValue)
cmd.Parameters.Append param2
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "xxecu_return_username.return_username"
Set recset = cmd.Execute
MsgBox "Reurtn = USERNAME=" & cmd.Parameters(0)
OraCon.Close
End Sub
【问题讨论】:
-
如果您注释掉
On Error哪一行会引发错误? -
嗨蒂姆。第一个“.Execute”行是发生错误的地方。
-
可以添加
XXX_VALIDATE_ACCOUNT的代码吗?此外,我在回答中建议的更改之一是从adVariant切换到实际数据类型,在大多数情况下它是adVarchar。 -
刚刚想到。我使用的是 32 位的 Excel,但安装了 64 位的 Oracle 客户端。这可能是个问题吗?不确定我是否可以同时安装 32 和 64 客户端,然后以某种方式选择在 excel 中使用哪一个。
-
但是,我只是想。在同一个工作簿中,我有一个宏来执行同一个数据库的简单 sql 查询,并且可以 100% 工作。所以现在认为这可能不是驱动程序问题。
标签: excel oracle vba stored-procedures