database-connection – Firebird 2.5 C客户端:DATE数据类型错误

环境:Firebird 2.5.4-64bit,在
Windows 8.1上.

我正在尝试使用C客户端API编写C客户端(使用VS2013).在包含DATE列的表上准备SELECT语句时收到此错误(调用isc_dsql_prepare函数时出错)

Dynamic SQL Error
-SQL error code = -804
-Data type unknown
-Client SQL dialect 1 does not support reference to DATE datatype

从isql工具,我确认数据库正在使用SQL方言3:
SQL>显示sql方言;
        客户端SQL方言设置为:3,数据库SQL方言为:3

在客户端,我将SQL方言设置为3(至少我没有附加错误):

uint32_t sqlDialect = 3;
    const char* charset = "UTF8";
    char dpbBuffer[256], *dpb, *p;

    dpb = dpbBuffer;
    *dpb++ = isc_dpb_version1;
    *dpb++ = isc_dpb_user_name;
    *dpb++ = user.size();
    strcpy(dpb, user.c_str());
    dpb += user.size();
    *dpb++ = isc_dpb_password;
    *dpb++ = pwd.size();
    strcpy(dpb, pwd.c_str());
    dpb += pwd.size();
    *dpb++ = isc_dpb_lc_ctype;
    *dpb++ = 4;
    strcpy(dpb, charset);
    dpb += 4;
    *dpb++ = isc_dpb_sql_dialect;
    memcpy(dpb, &sqlDialect, 4);
    dpb += 4;

    short dpbLength = dpb - dpbBuffer;

    if (isc_attach_database(status, 0, url.c_str(), &_db, dpbLength, dpbBuffer))
    {
        isc_print_status(status);
    }

我对TIMESTAMP列没有任何问题,因此我可以将所有DATE列设置为TIMESTAMP类型,但我希望有人可以解释错误消息.

解:
非常感谢Mark Rotteveel指出了确切的问题.

首先,有关我如何准备声明的更多信息:

std::string sql = "SELECT * FROM truc";
out_sqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(NbColumn));
out_sqlda->version = SQLDA_VERSION1;
out_sqlda->sqln = NbColumn;
isc_stmt_handle stmt;
isc_dsql_allocate_statement(status, &_db, &stmt);
isc_dsql_prepare(status, &(TransactHandle), &stmt, 0, sql.c_str(), 1, out_sqlda);

我被Interbase API指南pdf滥用了,它提供了以下内容:

isc_dsql_prepare(
status_vector,
&trans, /* Set by previous isc_start_transaction() call. */
&stmt, /* Statement handle set by this function call. */
0, /* Specifies statement string is null-terminated. */
str, /* Statement string. */
SQLDA_VERSION1, /* XSQLDA version number. */
out_sqlda /* XSQLDA for storing column data. */
);

但第6个参数不是SQLDA版本,而是SQL方言!放3解决了这个问题.
查看.Net提供程序的代码也非常有用.

最佳答案 如前所述,API中的某些方法将SQL方言版本作为参数(isc_dsql_prepare,isc_dsql_execute_immediate和isc_dsql_exec_immed2).如果使用参数1而不是3来调用它们,则您的语句将被解析为方言1语句.

正如您所注意到的,“Interbase 6 API指南”(第112页)中的示例表明它是SQLDA版本.我的猜测是,在以前版本的Interbase(版本6中引入了方言)中,这个参数是SQLDA版本(参见例如isc_describe,它在XSQLDA参数之前获取da_version参数),并且他们重​​用此参数来保留方法参数类型和计数相同.其中一些方法需要da_version参数的事实有点奇怪(sqlda版本是XSQLDA的一部分).

点赞