SQL_ATTR_ROW_NUMBER

时间:2015-11-26 13:45:34

标签: mysql postgresql sqlite odbc

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。)

1 个答案:

答案 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驱动程序还是围绕一个构建应用程序?