c - 选择上的 sqlite3_bind_text,准备好的 vs 字符串 SQL 语句的结果不同

标签 c sqlite

当我尝试使用 sqlite3_bind_text 函数进行选择时遇到问题。

目的是在我的数据的 10 分钟时间段内获取最新值。

如果我使用准备好的语句并绑定(bind)我的值,则结果与使用 SQL 语法的普通字符串不同。

两个测试的 SQL 语法“应该”相同。

当代码运行时,我得到以下输出:

test 1 = 0.000000 AnalogRPM        <-- Error
test 2 = 7.700000 7.69999980926514 <-- Correct value

在我看来,我的绑定(bind)语句返回列的名称而不是值(就好像该值被插入为“AnalogRPM”

有没有人遇到过类似的事情?或者你能看出我的代码有什么错误吗?

欢迎任何反馈:)

char str[1000];
sqlite3_stmt *test1;

/** First test, use prepared statement to get double value */
snprintf(str, sizeof(str),
"select ? from DATA WHERE ts_sec BETWEEN ? AND ? ORDER BY rowid DESC LIMIT 1");

/** All 'rc' are check in my code, i just left them out to make it easier to read */
rc = sqlite3_prepare_v2(db_livedata, str, -1, &test1, 0);

if(rc != SQLITE_OK)
    printf("SQL error on line:%d msg:%s \n",__LINE__, sqlite3_errmsg(db_livedata));

rc = sqlite3_bind_text( test1, 1, "AnalogRPM",-1,0);
rc = sqlite3_bind_int(  test1, 2, stat_time.tv_sec - 600);
rc = sqlite3_bind_int(  test1, 3, stat_time.tv_sec);

do
 {
    rc = sqlite3_step( test1);
    switch( rc )
    {
       /** No more data */
       case SQLITE_DONE:
          break;

       /** New data */
       case SQLITE_ROW:
       {
          uint16_t size = sqlite3_column_count( test1);

          if(size == 1) // should always be one
          {
             value   = sqlite3_column_double( test1, 0);
             printf("test 1 = %f %s\n",value, sqlite3_column_text(test1, 0));
          }
       }
       break;

       default:
          break;
    }
}while( rc==SQLITE_ROW );


/** Second test use normal string for prepare */
sqlite3_stmt *test2;
snprintf(str, sizeof(str),
"select AnalogRPM from DATA WHERE ts_sec BETWEEN %d AND %d ORDER BY rowid DESC LIMIT 1"
,stat_time.tv_sec - 600, stat_time.tv_sec);

rc = sqlite3_prepare_v2(db_livedata, str, -1, &test2, 0);

if(rc != SQLITE_OK)
    printf("SQL error on line:%d msg:%s \n",__LINE__, sqlite3_errmsg(db_livedata));

do
{
    rc = sqlite3_step( test2);
    switch( rc )
    {
        /** No more data */
        case SQLITE_DONE:
            break;

        /** New data */
        case SQLITE_ROW:
        {
            uint16_t size = sqlite3_column_count( test2);
            if(size == 1)
            {
                value   = sqlite3_column_double( test2, 0);
                printf("test 2 = %f %s\n",value, sqlite3_column_text(test2, 0));
            }
        }
        break;

        default:
            break;
    }
}while( rc==SQLITE_ROW );

最佳答案

第一个版本本质上是

SELECT 'AnalogRPM' ...

第二个是

SELECT AnalogRPM ...

区别在于表达式是字符串文字还是列名。

您不能对列名使用变量绑定(bind)。在 SQL 语句编译时需要知道列名。

关于c - 选择上的 sqlite3_bind_text,准备好的 vs 字符串 SQL 语句的结果不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19927188/

相关文章:

c++ - 在 C/C++ 中读取和处理 WAV 文件数据

c - 从命令行获取数组输入

android - 如何使用 kotlin 将一列复制到 SQlite 数据库中的另一列

android - 如何确保数据只在 SQLite 中插入一次?

java - 使用预填充或外部数据库在 ListView 中添加 OnClickListener

从任务计划程序执行时,SQLite reader.read() 总是返回 false

python - PyErr_Set* 两次

c - 文本未打印在输出上

c - 接收 SIGSEGV 的程序可能是针对 0xffffffff 的指针

java - Android Sqlite 和外键失败