OracleCommandBuilder.DeriveParameters() 抛出 OracleException: ORA-06564: 对象不存在 ORA-06512: 在 "SYS.DBMS_UTILITY"
OracleCommandBuilder.DeriveParameters() throws OracleException: ORA-06564: object does not exist ORA-06512: at "SYS.DBMS_UTILITY"
在 .NET Framework 中使用 ADO.NET 附带的 OracleClient,我试图在数据库中的过程上调用 OracleCommandBuilder.DeriveParameters()
方法,但我不断收到 OracleException
消息:ORA-06564: object CustOrdersOrders does not exist
,即使我成功创建了过程。我对 SQL 服务器比较熟悉,所以我可能在这里遗漏了一些东西。
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"
。
App.config
<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();
}
更多详情
这发生在我为企业图书馆数据访问应用程序块 here 制作的一个分支中,试图恢复这个图书馆。这就是为什么它使用 System.Data.OracleClient
而不是 ODP.NET.
测试是在我本地安装的 Oracle 数据库 XE 上进行的运行。
从我的 Oracle-ish 观点来看,这是你的大错:
CREATE OR REPLACE PROCEDURE "CustOrdersOrders"
- -
these double quotes
因为,默认情况下,Oracle 将所有对象名称以大写形式存储到字典中,但您可以按需要以任何方式引用它,例如custordersorders
、CUSTordERsordERS
、CUSTORDERSORDERS
、CustOrdersOrders
- 没问题。但是,如果您将任何名称(过程、table、列、...)括在双引号中,您 必须 在任何时候引用该对象时使用双引号,包括在与创建该对象时完全相同的双引号和匹配的字母大小写。
因此:要么将过程重新创建为 CREATE OR REPLACE PROCEDURE CustOrdersOrders
(这是我的建议),要么使用双引号。
在 .NET Framework 中使用 ADO.NET 附带的 OracleClient,我试图在数据库中的过程上调用 OracleCommandBuilder.DeriveParameters()
方法,但我不断收到 OracleException
消息:ORA-06564: object CustOrdersOrders does not exist
,即使我成功创建了过程。我对 SQL 服务器比较熟悉,所以我可能在这里遗漏了一些东西。
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"
。
App.config
<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();
}
更多详情
这发生在我为企业图书馆数据访问应用程序块 here 制作的一个分支中,试图恢复这个图书馆。这就是为什么它使用 System.Data.OracleClient
而不是 ODP.NET.
测试是在我本地安装的 Oracle 数据库 XE 上进行的运行。
从我的 Oracle-ish 观点来看,这是你的大错:
CREATE OR REPLACE PROCEDURE "CustOrdersOrders"
- -
these double quotes
因为,默认情况下,Oracle 将所有对象名称以大写形式存储到字典中,但您可以按需要以任何方式引用它,例如custordersorders
、CUSTordERsordERS
、CUSTORDERSORDERS
、CustOrdersOrders
- 没问题。但是,如果您将任何名称(过程、table、列、...)括在双引号中,您 必须 在任何时候引用该对象时使用双引号,包括在与创建该对象时完全相同的双引号和匹配的字母大小写。
因此:要么将过程重新创建为 CREATE OR REPLACE PROCEDURE CustOrdersOrders
(这是我的建议),要么使用双引号。