【问题标题】:Oracle function call from VB6. Function is not a procedure error从 VB6 调用 Oracle 函数。函数不是过程错误
【发布时间】:2011-12-22 15:45:04
【问题描述】:

我将 Oracle 函数声明为

create or replace FUNCTION CheckScan(
  pMode IN number, 
  pAgrISN in number, 
  pAgrId in varchar2, 
  pDocISN in number, 
  pRefundId in varchar2) RETURN NUMBER IS  ...

以及以管理员身份连接到 Oracle 的客户端 Visual Basic 6 代码,例如:

...

cmd.ActiveConnection = conn
cmd.CommandText = "CheckScan"
cmd.CommandType = 4 'adCmdStoredProc

Dim pMode As Integer
Dim pAgrISN As Integer
Dim pAgrId As String
Dim pDocISN As Integer
Dim pRefundId As String

pMode = 2
pAgrISN = 12345
pAgrId = "Some-Id"
pDocISN = 12345
pRefundId = "Some-id"

cmd.Parameters.Append cmd.CreateParameter("pMode", 131, 1, 10, pMode)
cmd.Parameters.Append cmd.CreateParameter("pAgrISN", 131, 1, 10, pAgrISN)
cmd.Parameters.Append cmd.CreateParameter("pAgrId", 200, 1, 255, pAgrId)
cmd.Parameters.Append cmd.CreateParameter("pDocISN", 131, 1, 255, pDocISN)
cmd.Parameters.Append cmd.CreateParameter("pRefundId", 200, 1, 255, pRefundId)

cmd.Execute

这段代码以:

结尾
PLS-00221: "CHECKSCAN" is not a procedure or is undefined

这里有什么问题?函数编译成功。

提前感谢您!

【问题讨论】:

  • 连接到Oracle DB的用户是否对该函数有EXECUTE权限?该函数还返回一个值,您在捕获它吗?
  • 是的,这是一个管理员帐户

标签: oracle stored-procedures vb6 oledb


【解决方案1】:

既然你有一个函数(而不是一个过程),你必须对返回值做一些事情。添加以下参数:

With cmd
    .Parameters.Append .CreateParameter("pRetval", adNumeric, adParamReturnValue)
    .Parameters.Append .CreateParameter("pMode", adNumeric, adParamInput, 10, pMode)
    .Parameters.Append .CreateParameter("pAgrISN", adNumeric, adParamInput, 10, pAgrISN)
    .Parameters.Append .CreateParameter("pAgrId", adVarChar, adParamInput, 255, pAgrId)
    .Parameters.Append .CreateParameter("pDocISN", adNumeric, adParamInput, 255, pDocISN)
    .Parameters.Append .CreateParameter("pRefundId", adVarChar, adParamInput, 255, pRefundId)

    .Execute
End With

更新:

参数的顺序是相关的。它必须以返回类型开头。然后函数的所有参数必须按照它们被声明的顺序。但是,参数的名称无关紧要,因为在内部使用了位置(而不是命名)参数。如果您查看cmdCommandText 属性,这很明显:

"{ ? = call CheckScan(?, ?, ?, ?, ?) }"

【讨论】:

  • 谢谢你,@Codo!我用 4(返回值)参数重构了代码 - 现在它返回:PLS-00306(调用“CHECKSCAN”时参数的数量或类型错误)......我是否正确传递参数?
  • @AndrewFlorko:我认为你误解了我的代码。您需要五个参数:四个输入参数和一个返回值。第五个参数需要具有数字类型,因为您的函数被声明为返回 NUMBER。
  • 不,不,我现在有 6 个参数(5 个输入 + 1 个返回值)。
  • @AndrewFlorko:将返回值参数添加为第一个参数似乎很重要。我已经更新了我的答案以显示一个完整的例子。
【解决方案2】:

这仅仅是因为您将它定义为一个函数,但是却像调用一个过程一样调用它。要么将其作为函数调用(使用SELECT),要么使用IN OUT 参数代替RETURNING

【讨论】:

  • 谢谢@Gaius,我用 4(返回值)参数重构了代码 - 现在它返回:PLS-00306(调用“CHECKSCAN”时参数的数量或类型错误).. . 我是否正确传递参数?
【解决方案3】:

我不知道你是否可以自己调用一个函数。相反,我会尝试执行一个选择,例如:

select CheckScan(:pMode, :pAgrISN, :pArgId, :pDocISN, :pRefundId) from dual;

【讨论】:

  • 很好......我也打算让他这样做。
【解决方案4】:

这个函数有什么作用? Oracle 对功能有一定的限制(不允许在某些情况下进行更新等...)。 Check out this doc,并确保您没有违反用户定义函数的限制部分下的任何内容。您可能必须将其创建为存储过程(或用一个包装)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    • 2020-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多