Я конвертирую устаревшее приложение из устаревшего поставщика данных Microsoft .Net для Oracle (Sql.Data.OracleClient.dll) в собственный поставщик Oracle .Net ODP (OracleManagerDataAccess.dll) с использованием последней версии пакета Nuget. Сервер базы данных - Oracle 11g
Проблема, которую я не понимаю, заключается в том, что когда приложение вызывает хранимую процедуру с использованием поставщика Microsoft, это нормально, но когда я переключаюсь на использование Oracle ODP, я получаю следующую ошибку при вызове хранимой процедуры:
ORA-06502: PL/SQL: numeric or value error: character to number conversion error\nORA-06512: at line 1
Я преобразовал код в очень простое консольное приложение, которое демонстрирует ту же проблему (см. Ниже), но я не могу понять, что мне нужно делать по-другому с Oracle ODP. Выполнение «нормального» sql, созданного из приложения, кажется нормальным.
Вызывающий объект IDbCommand передает 4 параметра, два из которых являются строковыми, а два - целыми. Заголовок хранимой процедуры
PROCEDURE CreateSampleResults(varSampleCode SampleResults.SampleCode%TYPE, varTestPosition SampleResults.TestPosition%TYPE, varTestCode TestComponents.TestCode%TYPE, varTestVersion TestComponents.AuditNumber%TYPE)
Ничего в базе данных не изменилось, только поставщик данных в приложении .Net. Коллекции параметров команды идентичны независимо от того, используются ли поставщики данных Microsoft или Oracle.
Вот простое приложение, демонстрирующее проблему:
using Oracle.ManagedDataAccess.Client;
using System;
using System.Collections.Generic;
using System.Data;
//using System.Data.OracleClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace oracleconnect
{
class Program
{
static void Main(string[] args)
{
try
{
InitializeDBConnection();
CreateSampleResults("S0106", "a", 2, 1);
}
finally
{
if (_con.State==System.Data.ConnectionState.Open)
_con.Close();
}
}
static private OracleConnection _con;
private const string connectionString =
"Data Source = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = oracledbserver2)(PORT = 1521))(CONNECT_DATA = (SERVICE_NAME = orcdb10g))); User ID = myDatabasenameHere; Password=myPasswordhere";
private static void InitializeDBConnection()
{
_con = new OracleConnection();
_con.ConnectionString = connectionString;
_con.Open();
}
public static IDbCommand CreateCommand(IDbConnection cn, string procedureName)
{
IDbCommand command = cn.CreateCommand();
command.CommandTimeout = 30;
command.Connection = cn;
command.CommandType = System.Data.CommandType.StoredProcedure;
command.CommandText = procedureName;
return command;
}
public static void CreateSampleResults(string sampleCode, string testCode, short testVersion, short testPosition)
{
{
using (IDbCommand cmd = CreateCommand(_con, "CreateSampleResults"))
{
SetParameter("Oracle", cmd, "SampleCode", sampleCode);
SetParameter("Oracle", cmd, "TestCode", testCode);
SetParameter("Oracle", cmd, "TestVersion", testVersion);
SetParameter("Oracle", cmd, "TestPosition", testPosition);
cmd.ExecuteNonQuery();
}
}
}
public static void SetParameter(string databaseType, IDbCommand command, string name, object value)
{
System.Data.IDataParameter commandParameter = command.CreateParameter();
commandParameter.ParameterName = string.Format("var{0}", name);
commandParameter.Value = value;
var x = commandParameter.DbType;
command.Parameters.Add(commandParameter);
}
public enum DatabaseType { DBError, OLEDB, SQLServer, Oracle, /*SQLite,*/ Odbc };
}
}
Я подозреваю, что проблема может быть связана с использованием предполагаемых типов данных в хранимой процедуре (т.е. имя таблицы% TYPE), но это предположение. Кто-нибудь знает, что нужно сделать, чтобы вызовы хранимых процедур работали с Oracle ODP?
TIA
SetParameter
, чтобы они соответствовали параметрам SP. - person Ivan Stoev   schedule 19.12.2016