2011-11-14 7 views
2

現在、パイプで区切られた連結文字列を返すoracleデータベースには、次のfuncitonがあります。これは、.net 3.5を使用するように更新されているレガシーアプリケーションです。既存のアプリケーションは、戻された結果セットをVARCHAR2データ型に連結します。私がしたいのは、結果セット全体を私の.netクライアントに戻すことです。私が達成しようとしているものと同等のMS SQLは、単純な「SELECT * FROM TBL WHERE id = @id」です。私はOracleが使用する概念のいくつかを使用していません。私はOOPとSQLの照合のeブレンドのように思えます。私はこれについて複数の例を読んだが、私が探しているものを正確に見つけることはできないようだ。あなたは助けてもらえますか?引数を取るOracle関数を使用してOracleから.Netへレコードセットを返す

CREATE OR REPLACE FUNCTION DOCSADMIN.GET_DOCS (
    RECID IN NUMBER) -- RECORD ID 
    RETURN VARCHAR2 -- CONCATENATED STRING WITH PIPES 
IS 
    RETVAL   VARCHAR2(5000) :=''; 
    DOCSTRING  VARCHAR2(5000) :='';  
    DOCNAME  VARCHAR2(5000) :=''; 
    DOCNUMBER NUMBER; 
    STATUS  VARCHAR2(5000) :=''; 
    DOCTYPE  VARCHAR2(5000) :=''; 
    EDITDATE  DATE :=''; 
/****************************************************************************** 
    NAME:  GET_DOCS 
    PURPOSE: Pulls associated docs from profile table 
******************************************************************************/ 


    CURSOR GETDOCINFO IS SELECT DOCNUMBER, DOCNAME, CUSTOM_STATUS, DOCUMENTTYPES.DESCRIPTION, LAST_EDIT_TIME 
     FROM PROFILE, DOCUMENTTYPES, FORMS WHERE NAD_APID = IN_APID AND PROFILE.FORM = FORMS.SYSTEM_ID AND 
     DOCUMENTTYPE = DOCUMENTTYPES.SYSTEM_ID AND FORM_NAME = 'DOCS_PROFILE' ORDER BY DOCNUMBER; 

BEGIN 

    OPEN GETDOCINFO; 
     --GET THE FIRST RECORD 
     FETCH GETDOCINFO INTO DOCNUMBER, DOCNAME, STATUS, DOCTYPE, EDITDATE; 
     --LOOP THROUGH ALL ASSOCIATED DOCS AND GRAB INFO 
     WHILE GETDOCINFO%FOUND LOOP 

      BEGIN 

       DOCSTRING := DOCNUMBER || '|~|' || DOCNAME || '|~|' || STATUS || '|~|' || DOCTYPE || '|~|' || WS_EDITDATE; 

       RETVAL := RETVAL || DOCSTRING || '|^|'; 

       GOTO STARTOVER; 

      END; 

      <<STARTOVER>> 

      FETCH GETDOCINFO INTO DOCNUMBER, DOCNAME, STATUS, DOCTYPE, EDITDATE; 

     END LOOP; 

    CLOSE GETDOCINFO; 

    RETURN RETVAL; 

    EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
     NULL; 
    WHEN OTHERS THEN 
     -- Consider logging 

the error and then re-raise 
     RAISE; 
END GET_DOCS; 
/

答えて

5

まあ、関数をプロシージャに変換し、OUTパラメータがSYS_REFCURSORタイプである可能性があります。 Oracleと.Netを使用すると、カーソルを戻してそれをリーダーとして反復することができます。

サンプルOracleプロシージャ:

CREATE OR REPLACE PROCEDURE TEST_SCHEMA.TEST_PROCEDURE (
    out_DATA OUT SYS_REFCURSOR; 
) AS 
BEGIN 
    OPEN out_DATA FOR 
    SELECT col1, 
     col2 
    FROM TEST_SCHEMA.TEST_TABLE; 
END test_procedure; 

サンプルの.NETエンド:

using (OracleConnection connection = new OracleConnection("connstring")) 
using (OracleCommand command = connection.CreateCommand()) { 
    command.CommandType = CommandType.StoredProcedure; 
    command.CommandText = "TEST_SCHEMA.TEST_PROCEDURE"; 
    command.Parameters.Add("out_DATA", OracleType.Cursor) 
     .Direction = ParameterDirection.Output; 

    connection.Open(); 
    command.ExecuteNonQuery(); 
    OracleDataReader reader = 
     command.Parameters["out_DATA"].Value as OracleDataReader; 

    if (reader != null) { 
    using (reader) { 
     while(reader.Read()) { 
     string col1 = reader["col1"] as string; 
     string col2 = reader["col2"] as string; 
     } 
    } 
    } 
} 

は、あなたがそれを使用して終わった後にカーソルをクローズするようにしてください(using (reader)文によって上記の達成)。

あなたのケースでは、おそらくあなたの関数の元のカーソルを出力し、上記のように.Netのカーソルを反復処理するプロシージャを作成することができます。ちょうどメモ、Oracle側からの列名は重要であり、あなたが.Netで使用しているものと一致します。

+0

どのように私は(これは腰から離れている)私は前にOPENQUERYを使用してみたことがありません、あなたがラッパーを使用することができるかもしれSQL Serverの – gsirianni

0

これまでにコンパイルしたものがあります。

CREATE OR REPLACE PROCEDURE DOCSADMIN.GET_DOCS_SP (IN_APID IN NUMBER, out_DATA OUT SYS_REFCURSOR) 

AS 
BEGIN 

OPEN out_DATA FOR 

SELECT DOCNUMBER, DOCNAME, CUSTOM_STATUS, DOCUMENTTYPES.DESCRIPTION, LAST_EDIT_TIME 
     FROM PROFILE, DOCUMENTTYPES, FORMS WHERE APID = IN_APID AND PROFILE.FORM = FORMS.SYSTEM_ID AND 
     DOCUMENTTYPE = DOCUMENTTYPES.SYSTEM_ID AND FORM_NAME = 'PROFILE' ORDER BY DOCNUMBER; 

END GET_DOCS_SP; 

/

しかし、私は別の状況に遭遇してきたし、あなたの入力をお願い申し上げます。どうすればOPENQUERYを使ってSQLデータベースから次のものを呼び出すのですか?連結された文字列を返すレガシーバージョンは次のようになりました。

SELECT * FROM OPENQUERY (TESTSERVER, 'SELECT DOCSADMIN.GET_DOCS_SP (26) AS DOCINFO FROM DUAL') 

DOCINFO FROM DUAL句を削除するだけですか?

おかげ

+1

からOPENQUERYコマンドを使用して、これを呼び出します: 'PROCEDURE DOCSADMINをCREATE .GET_DOCS_SP_OPENQUERY(IN_APID IN NUMBER)SYS_REFCURSORをそのまま返します。proc_result SYS_REFCURSOR; BEGIN DOCSADMIN.GET_DOCS_SP(IN_APID、proc_result); RETURN proc_result; END GET_DOCS_SP_OPENQUERY; '次にSQLから' SELECT * FROM OPENQUERY(TESTSERVER、 'DOCSADMIN.GET_DOCS_SP_OPENQUERY(26)をDUALからDOCINFOとして選択') 'これはオンザフライで書かれており、うまくいかないかもしれません。 – Joshua

+0

私はあなたの助けを非常に感謝します。私は戻り値がoutパラメータよりもはるかに良く機能すると思います。 C#の構文に似ています。 – gsirianni

関連する問題