在C#/ VB中的Oracle中的一个嵌入式脚本中获取多个查询值

时间:2015-09-15 06:41:55

标签: c# .net sql-server vb.net oracle

我试图在VB中的一个嵌入式脚本中获取DataSet的多个查询值。 SQL Server脚本运行正常,而Oracle运行不正常。

<scripts id="getReportDetails">
    <mssql>
          SELECT GOAL_DESC, COALESCE(NULLIF(GOAL_EVALUATOR_COMMENT,''),'-') AS GOAL_EVALUATOR_COMMENT,COALESCE(NULLIF(GOAL_ASSESSEE_COMMENT,''),'-') AS GOAL_ASSESSEE_COMMENT
          FROM HS_HR_PEA_EXGOAL_TOIMPROVE
          WHERE TEMP_ID=@TEMP_ID AND TEMP_VERSION=@TEMP_VERSION AND FREQ_ID=@FREQ_ID AND EMP_NUMBER=@EMP_NUMBER

          SELECT EVALUATION_TYPE FROM HS_HR_PEA_TEMPLATE
          WHERE TEMP_ID=@TEMP_ID AND TEMP_VERSION=@TEMP_VERSION
    </mssql>
    <oracle>
          SELECT GOAL_DESC, COALESCE(NULLIF(GOAL_EVALUATOR_COMMENT,''),'-') AS GOAL_EVALUATOR_COMMENT,COALESCE(NULLIF(GOAL_ASSESSEE_COMMENT,''),'-') AS GOAL_ASSESSEE_COMMENT
          FROM HS_HR_PEA_EXGOAL_TOIMPROVE
          WHERE TEMP_ID=@TEMP_ID AND TEMP_VERSION=@TEMP_VERSION AND FREQ_ID=@FREQ_ID AND EMP_NUMBER=@EMP_NUMBER;

          SELECT EVALUATION_TYPE FROM HS_HR_PEA_TEMPLATE
          WHERE TEMP_ID=@TEMP_ID AND TEMP_VERSION=@TEMP_VERSION;
    </oracle>
</scripts>

有没有办法在Oracle的一个脚本中从这两个查询中获取值?

1 个答案:

答案 0 :(得分:1)

这很大程度上取决于您使用的Oracle版本。在11g上,与SQL Server相同的方法是不可能的,因为它不支持隐式游标。所以实现它的唯一方法是定义两个显式游标并在.NET中使用它们。

在Oracle 12中,它与SQL Server中的一样简单,但是当我异步读取隐式游标时,我遇到了ODAC崩溃。

我为你做了一个例子:

using (var connection = new OracleConnection("DATA SOURCE=HQ_PDB_TCP;PASSWORD=oracle;USER ID=HUSQVIK"))
{
    connection.Open();

    using (var command = connection.CreateCommand())
    {
        // Oracle 11
        command.CommandText = "BEGIN OPEN :C1 FOR SELECT 1 FROM DUAL; OPEN :C2 FOR SELECT 2, 3 FROM DUAL; END;";
        var p1 = command.CreateParameter();
        p1.OracleDbType = OracleDbType.RefCursor;
        p1.Direction = ParameterDirection.Output;       
        command.Parameters.Add(p1);

        var p2 = command.CreateParameter();
        p2.OracleDbType = OracleDbType.RefCursor;
        p2.Direction = ParameterDirection.Output;
        command.Parameters.Add(p2);

        command.ExecuteNonQuery();

        using (var reader1 = ((OracleRefCursor)p1.Value).GetDataReader())
        {
            reader1.Read();

            Console.WriteLine($"Reader 1 values: {reader1[0]}");
        }

        using (var reader2 = ((OracleRefCursor)p2.Value).GetDataReader())
        {
            reader2.Read();

            Console.WriteLine($"Reader 2 values: {reader2[0]}, {reader2[1]}");
        }

        command.Parameters.Clear();

        // Oracle 12
        command.CommandText = "DECLARE C1 SYS_REFCURSOR; C2 SYS_REFCURSOR; BEGIN OPEN C1 FOR SELECT 1 FROM DUAL; DBMS_SQL.RETURN_RESULT(C1); OPEN C2 FOR SELECT 2, 3 FROM DUAL; DBMS_SQL.RETURN_RESULT(C2); END;";
        using (var implicitReader = command.ExecuteReader())
        {
            implicitReader.Read();

            Console.WriteLine($"Implicit cursor 1 values: {implicitReader[0]}");

            implicitReader.NextResult();
            implicitReader.Read();

            Console.WriteLine($"Implicit cursor 2 values: {implicitReader[0]}, {implicitReader[1]}");
        }
    }
}