Ошибка типов данных Oracle ODP при вызове хранимых процедур
Я преобразовываю устаревшее приложение из устаревшего поставщика данных Microsoft .Net для Oracle (Sql.Data.OracleClient.dll) в собственный поставщик OTP Oracle.Net (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?
ТИА
1 ответ
Вы должны добавить в свой commandParameter
база данных DbType. Ошибка связана с преобразованием типов в oracle, когда вызывается эта последняя команда. Эта ошибка вызвана преобразованием commandParameter.Value
к окончательному типу базы данных.
https://msdn.microsoft.com/en-us/library/system.data.idataparameter.dbtype(v=vs.110).aspx