TL; TR:返回成功是否正确并且报告的不是实际的行号,而是报告SQL_ROW_NUMBER_UNKNOWN
等其他指标?
AFAIK,并非所有ODBC驱动程序都支持查询SQL_ATTR_ROW_NUMBER
属性,因此该属性是可选的。
我是否正确,如果驱动程序不支持,那么SQLGetStmtAttr
应该返回此代码?
HYC00 - Optional feature not implemented
返回成功是否正确并且报告的不是实际的行号,而是报告SQL_ROW_NUMBER_UNKNOWN
等其他指标?
有ODBC驱动程序可以做到这一点,例如SQLite 3 for ODBC执行此操作:
static SQLRETURN
drvgetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
SQLINTEGER bufmax, SQLINTEGER *buflen)
{
...
case SQL_ATTR_ROW_NUMBER:
if (s->s3stmt) {
*uval = (s->s3stmt_rownum < 0) ?
SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
} else {
*uval = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
}
*buflen = sizeof (SQLULEN);
return SQL_SUCCESS;
...
}
这是正确的和犹太教的实施吗?
例如,如果无法确定行位置, PostgreSQL ODBC driver会返回SQL_ERROR
。
MySQL Connector / ODBC驱动程序似乎总是返回SQL_SUCCESS
并根据此方案计算一些值:
case SQL_ATTR_ROW_NUMBER:
*(SQLUINTEGER *)ValuePtr= stmt->current_row+1;
默认值为
stmt->current_row= -1; /* Before first row */
根据ODBC SQLGetDiagField
标题中的注释,我一直认为SQL_DIAG_ROW_NUMBER
保留sqlext.h
标识符:
/* define for SQL_DIAG_ROW_NUMBER and SQL_DIAG_COLUMN_NUMBER */
#if (ODBCVER >= 0x0300)
#define SQL_NO_ROW_NUMBER (-1)
#define SQL_NO_COLUMN_NUMBER (-1)
#define SQL_ROW_NUMBER_UNKNOWN (-2)
#define SQL_COLUMN_NUMBER_UNKNOWN (-2)
#endif
或者,也许最安全的做法是检查SQLGetStmtAttr(SQL_ATTR_ROW_NUMBER)
针对SQL_ROW_NUMBER_UNKNOWN
报告的值?
(MSDN论坛上提出了同样的问题,here。)
答案 0 :(得分:3)
对于驱动程序返回
完全有效 HYC00 - Optional feature not implemented
在这种情况下,如果它没有实现它。如果当前行号未知或无法确定,则驱动程序也可以返回0。
驱动程序不应返回负数(即SQL_ROW_NUMBER_UNKNOWN
),因为SQL_ATTR_ROW_NUMBER
的类型定义为SQLULEN
(也称为无符号数)。你已经指出的定义:
/* define for SQL_DIAG_ROW_NUMBER and SQL_DIAG_COLUMN_NUMBER */
#if (ODBCVER >= 0x0300)
#define SQL_NO_ROW_NUMBER (-1)
#define SQL_NO_COLUMN_NUMBER (-1)
#define SQL_ROW_NUMBER_UNKNOWN (-2)
#define SQL_COLUMN_NUMBER_UNKNOWN (-2)
#endif
实际上与诊断有关,因为发生错误时。您有时可以跟踪发生错误的列和行,或者如果没有与错误关联的行/列,或者无法确定行/列,则驱动程序可以返回这些定义。
在这种情况下SQLite 3实现是错误的,MySQL驱动程序似乎是正确的,因为它始终能够计算并返回当前行号。
请问这个问题背后的动机是什么?您是在尝试自己构建ODBC驱动程序还是围绕一个构建应用程序?