首页 > 解决方案 > OracleCommandBuilder.DeriveParameters() 抛出 OracleException:ORA-06564:对象不存在 ORA-06512:在“SYS.DBMS_UTILITY”

问题描述

在 .NET Framework 中使用 ADO.NET 附带的 OracleClient,我试图OracleCommandBuilder.DeriveParameters()在数据库中的过程上调用方法,但我不断收到OracleException消息:ORA-06564: object CustOrdersOrders does not exist,即使我成功创建了过程。我更熟悉 SQL Server,所以也许我在这里遗漏了一些东西。

SQL

文件 1.sql:

create or replace PACKAGE PKGENTLIB_ARCHITECTURE
IS
TYPE CURENTLIB_ARCHITECTURE IS REF CURSOR;
END PKGENTLIB_ARCHITECTURE;
/

文件 2.prc:

CREATE OR REPLACE PROCEDURE "CustOrdersOrders"(VCUSTOMERID IN Orders.CustomerID%TYPE := 1, CUR_OUT OUT PKGENTLIB_ARCHITECTURE.CURENTLIB_ARCHITECTURE)
    AS

BEGIN
    OPEN cur_OUT FOR
    SELECT
        OrderID,
        OrderDate,
        RequiredDate,
        ShippedDate
    FROM Orders
    WHERE CustomerID = vCustomerId;
END;
/

文件 3.prc

CREATE OR REPLACE PROCEDURE ADDCOUNTRY
(vCountryCode IN Country.CountryCode%TYPE,
 vCountryName IN Country.CountryName%TYPE
)
AS
BEGIN
    INSERT INTO Country (CountryCode,CountryName)
    VALUES (vCountryCode,vCountryName);
END;
/

所有这些文件都在 SQL*Plus 中以@"path\to\file1.sql".

应用程序配置

<configuration>
  <connectionStrings>
    <add name="OracleTest" connectionString="Data Source=(DESCRIPTION=(CID=xe)(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))(CONNECT_DATA=(SID=xe)(SERVER=DEDICATED)));User Id=SYSTEM;Password=oracle;" providerName="System.Data.OracleClient" />
  </connectionStrings>
</configuration>

代码

private DbConnection connection;
private OracleCommand command;

[TestInitialize]
public void Initialize()
{
    String connectionString = ConfigurationManager.ConnectionStrings["OracleTest"].ConnectionString;
    connection = new OracleConnection(connectionString);
    command = connection.CreateCommand() as OracleCommand;
    command.CommandType = CommandType.StoredProcedure;
    connection.Open();
}

[TestMethod]
public void DeriveParametersWithoutUserDefinedTypes()
{            
    command.CommandText = "AddCountry";
    OracleCommandBuilder.DeriveParameters(command);
    Assert.AreEqual(2, command.Parameters.Count); // fails because Count = 0
}

[TestMethod]
public void DeriveParametersWithUserDefinedTypes()
{
    command.CommandText = "CustOrdersOrders";
    OracleCommandBuilder.DeriveParameters(command); //throws 'ORA-06564: object CustOrdersOrders does not exist\nORA-06512: at "SYS.DBMS_UTILITY", line 156\nORA-06512: at line 1'
    Assert.AreEqual(2, command.Parameters.Count);
}

[TestCleanup]
public void Cleanup()
{
    connection?.Dispose();
}

更多细节

这发生在我为企业库数据访问应用程序块创建的一个分支,试图恢复这个库。这就是它使用System.Data.OracleClientODP.NET 而不是 ODP.NET 的原因。

测试在我本地安装的 Oracle 数据库 XE 上运行。

标签: c#oracleado.netoracle18csystem.data.oracleclient

解决方案


从我的Oracle角度来看,这是你的巨大错误:

CREATE OR REPLACE PROCEDURE "CustOrdersOrders"
                            -                -
                            these double quotes

因为,默认情况下,Oracle 将所有对象名称以大写形式存储到字典中,但是您可以以任何您想要的方式引用它,例如custordersorders, CUSTordERsordERS, CUSTORDERSORDERS, CustOrdersOrders- 没问题。但是,如果您将任何名称(过程、表、列...)括在双引号中,则在引用该对象时必须使用双引号,括在相同的双引号中并匹配您在创建时使用的字母大小写那个物体。

所以:要么重新创建过程CREATE OR REPLACE PROCEDURE CustOrdersOrders(这是我的建议),要么使用双引号。


推荐阅读