2017-12-25 20 views
0

npgsql 쿼리에 대한 신속한 응답을 얻는 것이 좋습니다. 그 주인 덕분에! 비슷한 추상화/의미론을 가진 배열에 가치있는 매개 변수를 가져온 sproc을 포팅하려고합니다. 어떻게 하나의 pgsql sproc 모양과 전화를 npgsql API를 사용하여 궁금 해서요. 나는 우리의 추상 추상화 위에 또 다른 응용 프로그램 추상화 계층을 가지고있다. 우리는 데이터 어댑터를 사용하여 SQL Server, assoc 배열을 oracle로 이동하고 npgsql을 사용하여 postgres에 대해 매핑 할 수있는 것을 파악하려고합니다. 우리는 sproc을 형성 할 여지가 있지만 여전히 입력 매개 변수의 수를 동일하게 유지합니다. 우리는 확실히 많이 다른이의 sproc를 만들 수 있지만오라클 연관 배열을 Postgres로 이식하고 npgsql을 사용하여 데이터 액세스를 래핑

create or replace PROCEDURE InsNetworkDataBatch2 
    (
    -- Add the parameters for the stored procedure here 
    v_endPointID  IN arrays.t_number , 
    v_insertedDateTime IN arrays.t_date , 
    v_recordTypeID  IN arrays.t_number , 
    v_recordValue  IN arrays.t_number , 
    v_packetSize  IN arrays.t_number) 
AS 
BEGIN 
    DECLARE 
    BEGIN 
    FORALL i IN v_endpointID.FIRST..v_endpointID.LAST SAVE EXCEPTIONS 
     INSERT 
     INTO STGNETWORKSTATS 
     (
      INSERTEDDATE, 
      ENDPOINTID, 
      RECORDTYPEID, 
      RECORDVALUE, 
      PACKETSIZE 
     ) 
     VALUES 
     (
      v_insertedDateTime(i), 
      v_endPointID(i), 
      v_recordTypeID(i), 
      v_recordValue(i), 
      v_packetSize(i) 
     ); 

    END; 
END; 
-- END PL/SQL BLOCK (do not remove this line) ---------------------------------- 

을 다음과 같이 오라클 sproc에 쓴

public static void Flush2OraWithAssocArrayInsnetworkdatabatch(string dbKey ,int?[] ENDPOINTID,DateTime?[] INSERTEDDATETIME,int?[] RECORDTYPEID,long?[] RECORDVALUE,int?[] PACKETSIZE) 
    { 
     Database db = Helper.GetDatabase(dbKey); 
      using (DbConnection con = db.CreateConnection()){ 
       con.Open(); 
       using (DbCommand cmd = con.CreateCommand()){ 
        cmd.CommandText = "Insnetworkdatabatch"; 
        Helper.InitializeCommand(cmd, 300, "Insnetworkdatabatch"); 
        BuildInsnetworkdatabatchOracleAssocArrayCommandParameters(cmd ,ENDPOINTID,INSERTEDDATETIME,RECORDTYPEID,RECORDVALUE,PACKETSIZE); 
        try { 
         Helper.ExecuteNonQuery(cmd, cmd.CommandText); 
         con.Close(); 
        } catch (DALException) { 
         throw; 
        } 
      } 
     } 
    } 

아래와 같이 우리는 여전히 입력 배열의 일부 세트를 제공하는 동일한 응용 프로그램 API를 뒤에 필요 여기에 오라클 여기

create or replace PACKAGE Arrays AS 

type t_number is table of number index by binary_integer; 
type t_date is table of date index by binary_integer; 
END Arrays; 

에서 ASSOC 어레이 패키지는 우리가 오라클 PARM 궁금를 구축하는 방법입니다 무엇의 상당 가능한 모든 포스트 그레스와하려고하는 경우 npgsql 그것이

public override void CreateAssociativeArrayParameter(DbCommand cmd, string parameterName, object parameterValue, string dbType, ParameterDirection direction) 
    { 
     OracleDbType oracleDbType = dbSpecificTypesMap[dbType]; 
     OracleParameter param = new OracleParameter(parameterName, oracleDbType, direction); 
     param.CollectionType = OracleCollectionType.PLSQLAssociativeArray; 
     param.Value = parameterValue; 
     cmd.Parameters.Add(param); 
    } 

답변

0

내가 오라클 배열이나 연관 배열에 대해 아무것도 몰라 지원하는 방법을 참조하십시오. 그러나 PostgreSQL은 복잡한 유형을 지원합니다. PostgreSQL arrays은 열에 값 배열을 저장하는 좋은 방법이며 PostgreSQL은 배열 작업을위한 인덱싱 및 데이터베이스 측 함수도 제공합니다.

사전 유형 (연관 배열?)을 찾으려면 hstore 또는 json을 확인하십시오.

EDITED : 연관 영역에 고정 스키마가있는 경우 (즉, 필드가 변경되지 않는 경우) PostgreSQL composite을 고려할 수 있습니다.

+0

PARAMS 명령에 응용 프로그램을 결합하려고하는 방법입니다 수 배열에서 .NET 형식 'System.Int32'를 PostgreSQL '숫자'로 변환합니다. proc에는 int [] 및 timestamp []가 있고 내 코드는 배열 param을 만들었으며 그 오류는 npgsql 내부의 executenonquery에서 나온 것입니다. –

+0

' 누구나 정확히 무엇을하고 있는지 이해할 수있는 코드를 게시해야합니다. –

0

다음은 Postgres 저장 프로 시저의 시도입니다. 이제 작동 중입니다. 나는 postgres에서 sproc 매개 변수 데이터 형식과 호환되지 않는 .net 형식의 결과 인 npgsql 내부에서 던져진 캐스팅 문제를 해결했습니다. 여기

Here is how i am trying to add the param value 

create or replace FUNCTION InsNetworkDataBatch 
    (
    -- Add the parameters for the stored procedure here 
    v_endPointID  IN int[] , 
    v_insertedDateTime IN timestamp[] , 
    v_recordTypeID  IN int[] , 
    v_recordValue  IN bigint[] , 
    v_packetSize  IN int[]) RETURNS void 
     LANGUAGE 'plpgsql' 

AS $$ 
BEGIN 
    DECLARE 
    BEGIN 

FOR i IN array_lower(v_endPointID, 1) .. array_upper(v_endPointID, 1) 
    loop 
    INSERT INTO STGNETWORKSTATS 
     (
      INSERTEDDATE, 
      ENDPOINTID, 
      RECORDTYPEID, 
      RECORDVALUE, 
      PACKETSIZE 
     ) 
     VALUES 
     (
      v_insertedDateTime[i], 
      v_endPointID[i], 
      v_recordTypeID[i], 
      v_recordValue[i], 
      v_packetSize[i] 
     ); 
    end loop; 

    END; 
END; 
$$ 

내가 포스트 그레스의 SPROC를 다시 시도했지만 npgsql provider..System.InvalidCastException에 오류로 실행

public override void CreateAssociativeArrayParameter(DbCommand cmd, string parameterName, object parameterValue, string dbType, ParameterDirection direction) 
     { 
      NpgsqlDbType npgsqlDbType; 
      if (dbSpecificTypesMap.ContainsKey(dbType)) 
      { 
       npgsqlDbType = dbSpecificTypesMap[dbType]; 
      } 
      else 
      { 
       throw new ApplicationException($"The db type {dbType} could not be parsed into the target NpgsqlDbType. Please check the underlying type of the parameter"); 
      } 
      NpgsqlParameter param = new NpgsqlParameter(parameterName.ToLower(), NpgsqlDbType.Array | npgsqlDbType); 
      param.Value = parameterValue; 
      cmd.Parameters.Add(param); 
     }