sqlite3 c ++函数:当INSERT语句作为参数出现时,它不会被执行

时间:2017-06-07 11:02:48

标签: c++ sqlite

我正在实现一个接收任何SQL语句然后执行它的函数。

void dbExec(std::string str, bool vertical)
{
   sqlite3 *db; // Create db object
   char *zErrMsg = 0;
   int rc;
   const char *sql = str.c_str(); // Convert string to char
   sqlite3_stmt *stmt = NULL; // SQL statement

   /* Open Database */
   rc = sqlite3_open("db/survey.db",&db);
   if (rc)
   {
      fprintf(stderr, "DBOPEN_ERR: %s\n", sqlite3_errmsg(db));
   }

   /* Execute SQL statement */
   rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); // Prepare statement

   if (rc != SQLITE_OK )
   { // Check error
      fprintf(stderr, "DB error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
   }

   int cols = sqlite3_column_count(stmt); // Number of columns
   const char *data = NULL; // data char pointer

   if (vertical)
   {
      sqlite3_step( stmt );
      for (int i = 0; i < cols; i++)
      {
         // Print column name and info
         data = (const char*)sqlite3_column_text( stmt, i );
         std::cout << std::setw(20) << sqlite3_column_name(stmt,i)
                   << std::setw(30) << (data ? data : "[NULL]" );
         printf("\n");
      }
   }
   else
   {
      for (int i = 0; i < cols; i++)
      {
         // Print column name
         std::cout << std::setw(15) << sqlite3_column_name(stmt,i);
      }
      printf("\n");

      while ( sqlite3_step( stmt ) == SQLITE_ROW )
      {
         // print each row
         for (int i = 0; i < cols; i++)
         {
            data = (const char*)sqlite3_column_text( stmt, i );
            std::cout << std::setw(15) << (data ? data : "[NULL]" );
         }
         printf("\n");
      }
   }

   /* Close Database */
   sqlite3_close(db);
}

str参数为:

SELECT * FROM TABLE 

它完美无缺。如果str参数是:

INSERT INTO TABLE (COL1) VALUES(100) 

它没有用。

但是,如果在函数内部我添加以下行:

str = "INSERT INTO TABLE (COL1) VALUES(100)";

它完美无缺。我尝试了很多东西,但我仍然无法弄清楚发生了什么......有什么想法吗?

谢谢!

编辑: 以这种方式调用函数dbExec

void addBorehole()
{
   std::string statement;
   statement = "INSERT INTO BOREHOLE (TOTAL_DEPTH) VALUES (45)";

   dbExec(statement, false);
}

2 个答案:

答案 0 :(得分:0)

您的问题是数据库正忙(SQLITE_BUSY)。 documentation sais:

  

[...] SQLITE_BUSY表示与单独的数据库连接发生冲突,可能是在单独的进程中[...]

因此必须有一个阻止数据库的进程。 要获取阻止数据库的进程,您可以执行以下操作(从Stack Exchange网络复制)。

<强> Linux:

  
    

$ fuser development.db

  
     

此命令将显示锁定文件的进程:

     
    

&GT; development.db:5430

  
     

刚刚杀死这个过程...

     

kill -9 5430

<强> Windows:

  

PowerShell方法:

IF((Test-Path -Path $FileOrFolderPath) -eq $false) {
    Write-Warning "File or directory does not exist."       
}
Else {
    $LockingProcess = CMD /C "openfiles /query /fo table | find /I ""$FileOrFolderPath"""
    Write-Host $LockingProcess
}
     

更多详情How to find out which process is locking a file or folder in Windows

Windows的另一种方法是使用ProcessExplorer

答案 1 :(得分:0)

好的,通过在关闭数据库之前编写以下行来解决问题:

sqlite3_finalize( stmt );

信息:https://sqlite.org/c3ref/close.html

  

如果数据库连接与未完成的准备相关联   语句或未完成的sqlite3_backup对象然后sqlite3_close()   将保持数据库连接打开并返回SQLITE_BUSY。

然而,当我在函数内部硬编码语句时,我仍然无法理解它的工作原理。

谢谢!