问题
Using the OracleClient that comes with ADO.NET in .NET Framework, I'm trying to call OracleCommandBuilder.DeriveParameters()
method on a procedure in the database, but I keep getting an OracleException
with the message: ORA-06564: object CustOrdersOrders does not exist
, even though I created the procedure successfully. I'm more familiar with SQL Server, so perhaps I'm missing something here.
SQL
file 1.sql:
create or replace PACKAGE PKGENTLIB_ARCHITECTURE
IS
TYPE CURENTLIB_ARCHITECTURE IS REF CURSOR;
END PKGENTLIB_ARCHITECTURE;
/
file 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;
/
file 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;
/
All of these files were executed in SQL*Plus as @"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>
Code
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();
}
More Details
This is happening in a fork I made for the Enterprise Library Data Access Application Block here in an attempt to revive this library. That's why it's using the System.Data.OracleClient
and not the ODP.NET.
The tests are running on an Oracle Database XE I installed locally.
回答1:
From my Oracle-ish point of view, this was your huge mistake:
CREATE OR REPLACE PROCEDURE "CustOrdersOrders"
- -
these double quotes
Because, by default Oracle stores all object names into the dictionary in upper case, but you can reference it any way you want, e.g. custordersorders
, CUSTordERsordERS
, CUSTORDERSORDERS
, CustOrdersOrders
- no problem. But, if you enclose any name (procedure, table, column, ...) into double quotes, you must use double quotes any time you reference that object, enclosed into same double quotes and matching letter case exactly as you used it when creating that object.
So: either recreate the procedure as CREATE OR REPLACE PROCEDURE CustOrdersOrders
(which is what I'd suggest), or use double quotes.
来源:https://stackoverflow.com/questions/62732305/oraclecommandbuilder-deriveparameters-throws-oracleexception-ora-06564-objec