aboutsummaryrefslogtreecommitdiff
path: root/odb/mssql/error.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'odb/mssql/error.cxx')
-rw-r--r--odb/mssql/error.cxx66
1 files changed, 52 insertions, 14 deletions
diff --git a/odb/mssql/error.cxx b/odb/mssql/error.cxx
index f6be6ea..0c41d32 100644
--- a/odb/mssql/error.cxx
+++ b/odb/mssql/error.cxx
@@ -20,7 +20,9 @@ namespace odb
SQLHANDLE h,
SQLSMALLINT htype,
connection* conn,
- bool end_tran)
+ bool end_tran,
+ size_t pos,
+ multiple_exceptions* mex)
{
// First see if we have one of the errors indicated via the
// return error code.
@@ -166,14 +168,41 @@ namespace odb
for (SQLSMALLINT i (1);; ++i)
{
- r = SQLGetDiagRecA (htype,
- h,
- i,
- (SQLCHAR*) sqlstate,
- &native_code,
- (SQLCHAR*) msg,
- sizeof (msg),
- &msg_size);
+ // If this is for a batch, filter out based on row association.
+ // Here we only ignore records that have the associated row
+ // number and this number doesn't match ours. In particular,
+ // this means that all the un-associated records which will be
+ // duplicated for all the failed rows, which seems like the
+ // correct thing to do.
+ //
+ if (mex != 0)
+ {
+ SQLLEN n;
+ r = SQLGetDiagField (htype,
+ h,
+ i,
+ SQL_DIAG_ROW_NUMBER,
+ &n,
+ 0,
+ 0);
+
+ if (r == SQL_NO_DATA)
+ break;
+ else if (SQL_SUCCEEDED (r) &&
+ n != SQL_NO_ROW_NUMBER &&
+ n != SQL_ROW_NUMBER_UNKNOWN &&
+ n != static_cast<SQLLEN> (pos + 1)) // 1-based
+ continue;
+ }
+
+ r = SQLGetDiagRecA (htype,
+ h,
+ i,
+ (SQLCHAR*) sqlstate,
+ &native_code,
+ (SQLCHAR*) msg,
+ sizeof (msg),
+ &msg_size);
if (r == SQL_NO_DATA)
break;
@@ -203,27 +232,36 @@ namespace odb
if (e.size () == 0)
e.append (0, "?????", "no diagnostic record (using wrong handle?)");
- throw e;
+ if (mex == 0)
+ throw e;
+ else
+ // It could be that some of these errors are fatal. I guess we
+ // will just have to learn from experience which ones are. The
+ // client code can always treat specific error codes as fatal.
+ //
+ mex->insert (pos, e);
}
void
translate_error (SQLRETURN r, connection& c, bool end_tran)
{
- translate_error (r, c.handle (), SQL_HANDLE_DBC, &c, end_tran);
+ translate_error (r, c.handle (), SQL_HANDLE_DBC, &c, end_tran, 0, 0);
}
void
translate_error (SQLRETURN r,
connection& c,
- const auto_handle<SQL_HANDLE_STMT>& h)
+ const auto_handle<SQL_HANDLE_STMT>& h,
+ size_t pos,
+ multiple_exceptions* mex)
{
- translate_error (r, h, SQL_HANDLE_STMT, &c, false);
+ translate_error (r, h, SQL_HANDLE_STMT, &c, false, pos, mex);
}
void
translate_error (SQLRETURN r, SQLHANDLE h, SQLSMALLINT htype)
{
- translate_error (r, h, htype, 0, false);
+ translate_error (r, h, htype, 0, false, 0, 0);
}
}
}