2016-04-18 16 views
0

Ich habe mehrere Probleme beim Aufrufen gespeicherter Prozeduren von .NET/C# mit Npgsql. Ich erhalte manchmal verschiedene Fehler von der Operation, die gerade ausgeführt wird, bis die Zeile verfügbar ist, die Spalte außerhalb des Bereichs, muss zwischen 0 und 0 liegen. Dies ist jedoch der Hauptstack-Trace, den ich von NUnit sehe.Gespeicherte Npqsql-Prozedur gibt mehrere REFCURSOR zurück

System.InvalidOperationException : An operation is already in progress. 

    at Npgsql.NpgsqlConnector.StartUserAction(ConnectorState newState) 
    at Npgsql.NpgsqlConnector.ExecuteInternalCommand(SimpleFrontendMessage message, Boolean withTimeout) 
    at Npgsql.NpgsqlConnector.Rollback() 
    at Npgsql.NpgsqlTransaction.Rollback() 
    at Omega.Data.DAO.PatientShapeDao.GetShapeData(Int64 shapeId) in c:\Users\jkratz\Projects\omega\Omega\data\DAO\PatientShapeDao.cs:line 62 
    at Omega.Tests.DAO.PostgresDaoTests.TestGetShapeData() in c:\Users\jkratz\Projects\omega\Omega.Tests\DAO\PostgresDaoTests.cs:line 26 

Ich habe die folgende gespeicherte Prozedur in Postgres:

CREATE OR REPLACE FUNCTION public.getpatientshapedata(p_shapeid bigint) 
    RETURNS SETOF refcursor AS 
$BODY$ 
    DECLARE 
     v_shapecursor REFCURSOR; 
     v_shapefilecursor REFCURSOR; 
    BEGIN 

     OPEN v_shapecursor FOR 
     select * from patientshape where id = p_shapeid; 
     RETURN NEXT v_shapecursor; 

     OPEN v_shapefilecursor FOR 
     select * from patientshapefile where patientshapeid = p_shapeid; 
     RETURN NEXT v_shapefilecursor; 

    END; 
$BODY$ 
    LANGUAGE plpgsql 

Es gibt zwei refcursors im Moment.

Ich habe das folgende Dao-Objekt in meiner Anwendung.

public class PatientShapeDao 
    { 
     private NpgsqlConnection _dbHandle; 
     private readonly string _connectionString; 

     public PatientShapeDao() 
     { 
      OmegaConnectionString connectionString = Transform.getInstance.LoadOmegaConnection(); 

      _connectionString = string.Format("Server={0};User Id={1};Password={2};Database={3}", 
       connectionString.Host, connectionString.UserId, connectionString.Password, connectionString.Database); 
     } 

     public void GetShapeData(long shapeId) 
     { 
      NpgsqlTransaction transaction; 

      // open connection 
      _dbHandle = new NpgsqlConnection(_connectionString); 
      _dbHandle.Open(); 

      // begin transaction 
      transaction = _dbHandle.BeginTransaction(); 

      try 
      { 
       // call stored procedure 
       NpgsqlCommand command = new NpgsqlCommand("getpatientshapedata", _dbHandle); 
       command.Parameters.Add(new NpgsqlParameter("p_shapeid", shapeId)); 
       command.CommandType = CommandType.StoredProcedure; 
       NpgsqlDataReader dataReader = command.ExecuteReader(); 

       // read result sets 
       while (dataReader.Read()) 
       { 
        Console.WriteLine("{0}\t{1}", dataReader[0], dataReader[1]); 
       } 

       dataReader.NextResult(); 

       // read result sets 
       while (dataReader.Read()) 
       { 
        Console.WriteLine("{0}\t{1}", dataReader[0], dataReader[1]); 
       } 

       transaction.Commit(); 
      } 
      catch (Exception ex) 
      { 
       transaction.Rollback(); 
      } 
      finally 
      { 
       _dbHandle.Close(); 
      } 
     } 
    } 

Antwort

0

Ihr Stack-Trace zeigt, dass die Ausnahme von Rollback geworfen wird, was bedeutet, dass es einige frühere Ausnahme in Ihrem Code war, die Sie nicht gebucht haben.

Unabhängig davon, müssen Sie Ihre NpgsqlCommand und NpgsqlDataReader in einer Verwendung platzieren, so dass sie ordnungsgemäß entsorgt werden, bevor Sie den catch-Block erreichen.

Verwandte Themen