使用带参数的Oracle函数将记录集从Oracle返回到.Net

gsi*_*nni 2 c# oracle asp.net-3.5 oracle11g .net-3.5

我目前在oracle数据库中有以下函数,它返回由管道分隔的连接字符串.这是一个遗留应用程序,正在更新以使用.net 3.5.exiisting应用程序将返回的结果集连接成VARCHAR2数据类型.我想要做的是将整个结果集返回给我的.net客户端.我正在尝试完成的MS SQL等同于一个简单的"SELECT*FROM TBL WHERE id = @id"我不习惯Oracle使用的一些概念.我似乎混合了OOP和SQL查询.我已经阅读了多个这方面的例子,但似乎无法找到我正在寻找的确切内容.你能帮忙吗?

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;
/
Run Code Online (Sandbox Code Playgroud)

Jos*_*hua 5

那么,您可以将函数转换为过程并具有该SYS_REFCURSOR类型的OUT参数.使用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;
Run Code Online (Sandbox Code Playgroud)

示例.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;
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

完成使用后一定要关闭光标(上面的using (reader)语句完成).

因此,在您的情况下,您可以创建一个在函数中输出原始游标的过程,然后只需迭代上面列出的.Net中的游标.请注意,Oracle方面的列名称很重要,并且与您在.Net中使用的列名相匹配.