अंत में, घंटों की खोज और कोड के साथ खेलने के बाद, मैं निम्नलिखित निष्कर्ष पर पहुंचा (सिरदर्द के अलावा):
मुझे वह मिला जो मैं
. से संयोजन का उपयोग करके चाहता था- एक संकेत यहां , जिसने UPDATE..RETURNING स्टेटमेंट को एक अनाम PL/SQL ब्लॉक में लपेटने का सुझाव दिया (BEGIN से शुरू करें और END के साथ समाप्त करें;) - यह बिना स्पष्टीकरण के चला गया और मुझे अभी भी नहीं पता कि व्यवहार अलग क्यों है
- OracleCommand के बारे में Oracle दस्तावेज़ में कोड स्निपेट, विशेष रूप से बाइंडिंग PL के बारे में हिस्सा /एसक्यूएल सहयोगी सरणियाँ थोक संग्रह के साथ (काम करने के लिए बाध्यकारी सरल सरणी नहीं मिल सका ..):
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
}
...