sql >> Database >  >> RDS >> Oracle

ODP.NET UPDATE... TERUGKEER IN... meerdere rijen, parametertype

eindelijk, na urenlang zoeken en spelen met code, kwam ik tot de volgende conclusies (afgezien van de hoofdpijn):

ik kreeg wat ik wilde met combinatie van

  1. een hint hier , wat suggereerde om de UPDATE..RETURNING-instructie in een anoniem PL/SQL-blok in te pakken (begin met BEGIN en eindig met END;) - dit ging zonder uitleg en ik weet nog steeds niet precies waarom het gedrag anders is
  2. codefragment in Oracle-documentatie over OracleCommand, met name het deel over het binden van PL /SQL associatieve arrays met BULK COLLECT INTO (kon de eenvoudige matrixbinding niet laten werken..):

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. PostgreSQL-schema's voor toepassingen met meerdere tenants

  2. Python gebruiken om toegang te krijgen tot SQL met een variabele kolomnaam

  3. Doorzoek alle tabellen, alle kolommen voor een specifieke waarde SQL Server

  4. Ik probeer een bestand te kopiëren, maar krijg een foutmelding