sql >> データベース >  >> RDS >> Oracle

C#のDBMS_OUTPUT.GET_LINESから出力バッファーを取得する

    コードの主な問題は、出力バッファーの各要素のバインドサイズが設定されていないことでした。また、結果を取得するときに出力バッファに適切にインデックスを付けていませんでした。そして最後に、実行の順序も役割を果たします。匿名のコードブロックを実行する前に、まず出力を有効にする必要があります。行われたすべての変更は、次のMCVE にコメントされています。 。それを機能させるために必要な変更のみが行われました。

    static void Main(string[] args)
    {
        string str = "User Id=xxx; password=xxx; Data Source=localhost:1521/xxx;";
        string sql = @"DECLARE lvsName VARCHAR2(6) := 'Oracle'; BEGIN  DBMS_OUTPUT.PUT_LINE('Do you see me?'); DBMS_OUTPUT.PUT_LINE('My name is: ' || lvsName); END;";
    
        OracleConnection _connection = new OracleConnection(str);
    
        try
        {
            _connection.Open();
    
            //adapter not being used
            //using (OracleDataAdapter oda = new OracleDataAdapter())
    
            using (OracleCommand cmd = new OracleCommand(sql, _connection))
            {
                // First enable buffer output
                // Set output Buffer
                cmd.CommandText = "BEGIN DBMS_OUTPUT.ENABLE(NULL); END;";
                cmd.CommandType = CommandType.Text;
                cmd.ExecuteNonQuery();
    
                // Then execute anonymous block
                // Execute anonymous PL/SQL block
                cmd.CommandText = sql;
                cmd.CommandType = CommandType.Text;
                var res = cmd.ExecuteNonQuery();
    
    
                // Get output
                cmd.CommandText = "BEGIN DBMS_OUTPUT.GET_LINES(:outString, :numLines); END;";
                cmd.CommandType = CommandType.Text;
    
                cmd.Parameters.Clear();
    
                cmd.Parameters.Add(new OracleParameter("outString", OracleDbType.Varchar2, int.MaxValue, ParameterDirection.Output));
                cmd.Parameters["outString"].CollectionType = OracleCollectionType.PLSQLAssociativeArray;
                cmd.Parameters["outString"].Size = sql.Length;
                cmd.Parameters["outString"].ArrayBindSize = new int[sql.Length];
    
                // set bind size for each array element
                for (int i = 0; i < sql.Length; i++)
                {
                    cmd.Parameters["outString"].ArrayBindSize[i] = 32000;
                }
    
    
                cmd.Parameters.Add(new OracleParameter("numLines", OracleDbType.Int32, ParameterDirection.InputOutput));
                cmd.Parameters["numLines"].Value = 10; // Get 10 lines
                cmd.ExecuteNonQuery();
    
                int numLines = Convert.ToInt32(cmd.Parameters["numLines"].Value.ToString());
                string outString = string.Empty;
    
                // Try to get more lines until there are zero left
                while (numLines > 0)
                {
                    for (int i = 0; i < numLines; i++)
                    {
                        // use proper indexing here
                        //OracleString s = (OracleString)cmd.Parameters["outString"].Value;
                        OracleString s = ((OracleString[])cmd.Parameters["outString"].Value)[i];
                        outString += s.ToString();
    
                        // add new line just for formatting
                        outString += "\r\n";
                    }
    
                    cmd.ExecuteNonQuery();
                    numLines = Convert.ToInt32(cmd.Parameters["numLines"].Value.ToString());
                }
    
                Console.WriteLine(outString);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    
        _connection.Close();
        _connection.Dispose();
    
        Console.WriteLine("Press RETURN to exit.");
        Console.ReadLine();
    }
    

    そして、出力結果は次のとおりです。

    Do you see me?
    My name is: Oracle
    
    Press RETURN to exit.
    


    1. SQL ServerのOBJECTPROPERTY()を使用して、オブジェクトが主キーであるかどうかを確認します

    2. Mybatis:SQLの一部をPOJO内のHashMapにマップします

    3. クラウドでアクセスデータベースを構築する方法

    4. Redshift-エポック文字列をタイムスタンプに変換します