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

ODP.NET UPDATE ... RETURNING INTO ...複数の行、パラメータタイプ

    最後に、何時間もコードを検索して遊んだ後、私は次の結論に達しました(頭痛は別として):

    から組み合わせを使って欲しいものを手に入れました
    1. ヒントこちら 、UPDATE..RETURNINGステートメントを匿名のPL / SQLブロックにラップすることを提案しました(BEGINで始まり、ENDで終わります;)-これは説明なしで行われ、動作が異なる理由はまだ正確にはわかりません
    2. OracleCommandに関するOracleドキュメントの
    3. コードスニペット、特にPLのバインドに関する部分/SQL連想配列 BULK COLLECT INTOを使用(単純な配列バインディングを機能させることができませんでした。):

    try
    {
        conn.Open();
        transaction = conn.BeginTransaction();
    
        cmd = new OracleCommand();
        cmd.Connection = GetConnection();
    
        cmd.CommandText =
            "BEGIN UPDATE some_table " +
            "SET status = 'locked', " +
            "    locked_tstamp = SYSDATE, " +
            "    user_name = '" + user + "' " +
            "WHERE rownum <= 4 " +
            "RETURNING id BULK COLLECT INTO :id; END;";
    
        cmd.CommandType = CommandType.Text;
    
        cmd.BindByName = true;
        cmd.ArrayBindCount = 4;
    
        p = new OracleParameter();
        p.ParameterName = "id";
        p.Direction = ParameterDirection.Output;
        p.OracleDbType = OracleDbType.Int64;
        p.Size = 4;
        p.ArrayBindSize = new int[] { 10, 10, 10, 10 };
        p.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
        cmd.Parameters.Add(p);
    
        int nRowsAffected = cmd.ExecuteNonQuery();
    
        // nRowsAffected is always -1 here
        // we can check the number of "locked" rows only by counting elements in p.Value (which is returned as OracleDecimal[] here)
        // note that the code also works if less than 4 rows are updated, with the exception of 0 rows
        // in which case an exception is thrown - see below
        ...
    }
    catch (Exception ex)
    {
        if (ex is OracleException && !String.IsNullOrEmpty(ex.Message) && ex.Message.Contains("ORA-22054")) // precision underflow (wth)..
        {
            Logger.Log.Info("0 rows fetched");
            transaction.Rollback();
        }
        else
        {
            Logger.Log.Error("Something went wrong during Get : " + ex.Message);
            ret = null;
            transaction.Rollback();
        }
    }
    finally
    {
        // do disposals here
    }
    ...
    



    1. Restful ApiExpressPostgresデータベース

    2. Mysql日時形式は10分追加します

    3. 挿入する前に2つの条件を確認するにはどうすればよいですか?

    4. PostgreSQLはより多くの出力を無効にします