【问题标题】:Cannot execute an sqlite SQL file to create a database无法执行 sqlite SQL 文件来创建数据库
【发布时间】:2013-11-08 23:41:41
【问题描述】:

我有一个用于创建数据库的长事务的 sql(文本文件)。

我为此使用 Kompex sqlite c++ 库:

// open database
Kompex::SQLiteDatabase *pDatabase = new Kompex::SQLiteDatabase(CT2A(strDBFilename), SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);

// create statement instance for sql queries/statements
Kompex::SQLiteStatement *pStmt = new Kompex::SQLiteStatement(pDatabase);

strSQLCreateDB=get_file_contents(strSQLFilename).c_str(); // load the SQL file

try {
    pStmt->Sql(strSQLCreateDB);
    pStmt->ExecuteAndFree();        
} catch(Kompex::SQLiteException &exception)
{
    std::cerr << "Exception Occured" << std::endl;
    exception.Show();
}

pDatabase->Close();

数据库是用 0 字节创建的,没有错误。 即使没有 kompex 库,我也对任何示例代码感兴趣,以执行创建数据库的这个 sql 事务。

从 sqlite 浏览器执行数据库会创建没有错误的数据库。

这是 SQL 命令文件的一部分

/* Disable Foreign Keys */
pragma foreign_keys = off;
/* Begin Transaction */
begin transaction;

/* Database [scanlog(1)] */
pragma auto_vacuum=0;
pragma encoding='UTF-8';
pragma page_size=1024;

/* Drop table [ApplicationNames] */
drop table if exists [ApplicationNames];

/* Table structure [ApplicationNames] */
CREATE TABLE [ApplicationNames] (
  [Id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
  [ApplicationName] TEXT, 
  [Icon] TEXT);
CREATE INDEX [IndexApps] ON [ApplicationNames] ([Id], [ApplicationName]);

/* Data [ApplicationNames] */
insert into [ApplicationNames] values(1, 'Windows System', null);
insert into [ApplicationNames] values(2, 'Internet Explorer', null); 
insert into [ApplicationNames] values(3, 'Google Chrome', null);

/* Commit Transaction */
commit transaction;

/* Enable Foreign Keys */
pragma foreign_keys = on;

【问题讨论】:

    标签: c++ sql sqlite


    【解决方案1】:

    您的问题是Sqlsqlite3_prepare 函数只执行字符串中的first SQL 命令。

    要在一个字符串中执行多个命令,必须使用sqlite3_exec

    if (SQLITE_OK != (ret = sqlite3_open_v2(CT2A(strDBFilename), &pDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL)))
    {
        TRACE("Failed to open SQLite conn: %d\n", ret);
        break;
    } 
    
    if (SQLITE_OK != (ret = sqlite3_exec(pDb, CT2A(strSQLCreateDB), NULL, 0, NULL)))
    {
        TRACE("Failed to execute SQLite script: %d, %s\n", ret, sqlite3_errmsg(pDb));
        break;
    }
    

    【讨论】:

    • CT2A() 函数需要包含哪些内容,它有什么作用?我不得不使用strDBFilename.c_str(),因为我有std::string。此外,您可能希望指出strSQLCreateDB 是一串SQL 语句,而不是要创建的文件名。起初对我来说这并不明显。
    • @Volomike 所有这些东西都来自问题的代码。
    【解决方案2】:

    这似乎有效:

    // open connection to a DB
        if (SQLITE_OK != (ret = sqlite3_open_v2(CT2A(strDBFilename), &pDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL)))
        {
            TRACE("Failed to open SQLite conn: %d\n", ret);
            break;
        } 
    
        // prepare the statement
        if (SQLITE_OK != (ret = sqlite3_prepare_v2(pDb, CT2A(strSQLCreateDB), -1, &query, NULL)))
        {
            TRACE("Failed to prepare SQLite script: %d, %s\n", ret, sqlite3_errmsg(pDb));
            break;
        }
    
        if (SQLITE_OK != (ret=sqlite3_exec(pDb, CT2A(strSQLCreateDB), NULL, 0, NULL)))
        {
            TRACE("Failed to execute SQLite script: %d, %s\n", ret, sqlite3_errmsg(pDb));
            break;
        }
    

    【讨论】:

      【解决方案3】:

      view.sql有声明

      从文件中获取数据库定义,这样便于管理表、视图和触发器的定义:

      {
          std::ifstream ifs("view.sql");
          std::string content(
              (std::istreambuf_iterator<char>(ifs) ),        
              (std::istreambuf_iterator<char>())
          );
      
          size_t n_pos,o_pos=0;
          n_pos = content.find(";");
          while (n_pos!=content.npos) {
              ++n_pos;
              sqlite::execute(con,content.substr(o_pos,n_pos-o_pos).c_str(),true);
              o_pos=n_pos;
              n_pos= content.find(";",o_pos);
          }
      }
      sqlite::execute(con,"VACUUM;",true);
      

      【讨论】:

      • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
      猜你喜欢
      • 2018-11-13
      • 1970-01-01
      • 1970-01-01
      • 2022-01-01
      • 2014-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-27
      相关资源
      最近更新 更多