2016-12-19 3 views
0

Je convertis une application héritée d'utiliser le fournisseur de données Microsoft .Net obsolète pour Oracle (Sql.Data.OracleClient.dll) au propre fournisseur .Net ODP Oracle (OracleManagerDataAccess.dll) en utilisant le dernier paquet Nuget. Le serveur de base de données est Oracle 11gOracle ODP types de données erreur appelant des procédures stockées

Un problème que je ne comprends pas est que lorsque l'application appelle une procédure stockée en utilisant le fournisseur Microsoft, c'est correct, mais quand je passe à l'utilisation de l'ODP Oracle, j'obtiens l'erreur suivante lors de l'appel la procédure stockée:

ORA-06502: PL/SQL: numeric or value error: character to number conversion error\nORA-06512: at line 1 

Je distillé le code jusqu'à une application console très simple qui présente le même problème (voir ci-dessous), mais je ne peux pas travailler ce que je dois faire différemment avec l'Oracle ODP . L'exécution de sql 'normal' émis par l'application semble bien.

L'objet IDbCommand appelant transmet 4 paramètres, dont deux sont des chaînes, deux sont des ints. L'en-tête de procédure stockée est

PROCEDURE CreateSampleResults(varSampleCode SampleResults.SampleCode%TYPE, varTestPosition SampleResults.TestPosition%TYPE, varTestCode TestComponents.TestCode%TYPE, varTestVersion TestComponents.AuditNumber%TYPE) 

Rien dans la base de données a changé, que le fournisseur de données dans l'application .Net. La commande Paramètres collections est identique que vous utilisiez les fournisseurs de données Microsoft ou Oracle.

est ici la simple application présentant le problème:

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 }; 

    } 
} 

Je soupçonne que le problème peut être lié à l'utilisation de types de données inférées dans la procédure stockée (c.-à-tablename% TYPE), mais qui est une supposition. Est-ce que quelqu'un sait ce qui doit être fait pour obtenir des appels de procédures stockées pour travailler avec Oracle ODP?

TIA

+0

pas 100% sûr, mais ont des souvenirs qui ODP.Net par défaut se fixe des paramètres par la position plutôt que par son nom. Vous pouvez essayer de réorganiser les appels 'SetParameter' pour faire correspondre les paramètres SP. –

+1

Yay! C'est tout, sur l'ongle. Merci, et bien fait Oracle pour être si bête. Si vous remplacez quelque chose, faites-le au moins de la même manière. :-( –

Répondre