【问题标题】:SQLite simple insert querySQLite 简单插入查询
【发布时间】:2013-10-29 00:55:54
【问题描述】:

我正在尝试使用 SQLite 作为我的存储。我还使用 nuget 和 using 语句添加了引用 dll。

我有

private void SetConnection()
{
            sql_con = new SQLiteConnection
                ("Data Source=c:\\Dev\\MYApp.sqlite;Version=3;New=False;Compress=True;");
}

private void ExecuteQuery(string txtQuery)
{
            SetConnection();
            sql_con.Open();
            sql_cmd = sql_con.CreateCommand();
            sql_cmd.CommandText = txtQuery;
            sql_cmd.ExecuteNonQuery();
            sql_con.Close(); 
}

我正在发送这样的查询 txt

public void Create(Book book)
{
            string txtSqlQuery  = "INSERT INTO Book (Id, Title, Language, PublicationDate, Publisher, Edition, OfficialUrl, Description, EBookFormat) ";
            txtSqlQuery += string.Format("VALUES (@{0},@{1},@{2},@{3},@{4},@{5},@{6},@{7},{8})", 
                        book.Id, book.Title, book.Language, book.PublicationDate, book.Publisher, book.Edition, book.OfficialUrl, book.Description, book.EBookFormat);
                   try
                   {
                       ExecuteQuery(txtSqlQuery);
                   }
                   catch (Exception ex )
                   {
                       throw new Exception(ex.Message);
                   }    
}

我的数据库已正确创建并通过有效数据传递书籍实例是可以的。但是在这行代码上执行查询总是抛出异常:

sql_cmd.ExecuteNonQuery();

我显然在这里做错了,但我看不到。

更新:抛出的异常消息是

SQL 逻辑错误或缺少数据库

无法识别的令牌:“22cf”

这个22cf 是传递的book.Id guid 字符串的一部分。

【问题讨论】:

  • 抛出了什么异常?
  • @Alireza 更新问题
  • 我注意到您没有在 SQL 命令中使用形式参数。这不是非常可取的,因为您将不得不担心将数据呈现到 SQL 语句中(即格式化日期、小数分隔符等......)。

标签: c# .net sqlite


【解决方案1】:

Don't EVER insert your data in your statement!

使用准备好的语句和绑定参数:

public void Create(Book book) {
    SQLiteCommand insertSQL = new SQLiteCommand("INSERT INTO Book (Id, Title, Language, PublicationDate, Publisher, Edition, OfficialUrl, Description, EBookFormat) VALUES (?,?,?,?,?,?,?,?,?)", sql_con);
    insertSQL.Parameters.Add(book.Id);
    insertSQL.Parameters.Add(book.Title);
    insertSQL.Parameters.Add(book.Language);
    insertSQL.Parameters.Add(book.PublicationDate);
    insertSQL.Parameters.Add(book.Publisher);
    insertSQL.Parameters.Add(book.Edition);
    insertSQL.Parameters.Add(book.OfficialUrl);
    insertSQL.Parameters.Add(book.Description);
    insertSQL.Parameters.Add(book.EBookFormat);
    try {
        insertSQL.ExecuteNonQuery();
    }
    catch (Exception ex) {
        throw new Exception(ex.Message);
    }    
}

【讨论】:

  • 如果参数不是字符串类型,此示例不起作用。
  • 不正确:SqlParameterCollection.Add 接受 Object 值。当然,实现会将 .NET 类型转换为适当的数据库类型。 SQLite 实现接受字符串类型,但也接受数字类型,null,...
  • 这是 SQLiteParameterCollection.Add(),但你是对的——它确实接受对象。我一定是在测试时犯了一些错误。在任何情况下,一旦您键入左括号,IntelliSense 就不会显示该版本的 Add()(仅当您在 Add 之前键入 . 时才会显示它)。
  • 如果对象很复杂,如何进行嵌套或递归添加?
  • 这似乎无效。您收到一个转换错误,抱怨您的对象不是SQLiteParameter 类型。
【解决方案2】:

将记录插入 SqliteDB:

using System.Data.SQLite;

    private void btnInsert_Click(object sender, RoutedEventArgs e)
    {
     string connection = @"Data Source=C:\Folder\SampleDB.db;Version=3;New=False;Compress=True;";
     SQLiteConnection sqlite_conn = new SQLiteConnection(connection);
     string stringQuery ="INSERT INTO _StudyInfo"+"(Param,Val)"+"Values('Name','" + snbox.Text + "')";//insert the studyinfo into Db
     sqlite_conn.Open();//Open the SqliteConnection
     var SqliteCmd = new SQLiteCommand();//Initialize the SqliteCommand
     SqliteCmd = sqlite_conn.CreateCommand();//Create the SqliteCommand
     SqliteCmd.CommandText = stringQuery;//Assigning the query to CommandText
     SqliteCmd.ExecuteNonQuery();//Execute the SqliteCommand
     sqlite_conn.Close();//Close the SqliteConnection
    }

【讨论】:

    【解决方案3】:

    使用 Dapper (Dapper.2.0.90) 和 SQLite (System.Data.SQLite.Core.1.0.114.2) 更新最新版本

    using System.Data.SQLite;
    using Dapper;
    

    连接字符串(数据库名称 - 'Store.db')

    connectionString="Data Source=.\Store.db;Version=3;"

    我的应用程序中的人员保存方法

        public static void SavePerson(PersonModel person)
        {
            using (IDbConnection cnn = new SQLiteConnection(connectionString))
            {
                cnn.Execute("insert into Person (FirstName, LastName) values (@FirstName, @LastName)", new { person.FirstName, person.LastName} );
            }
        }
    

    人物模型

    public class PersonModel
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    
        public string FullName
        {
            get
            {
                return $"{ FirstName } { LastName }";
            }
        }
    }
    

    这个答案包括我在我的应用程序中使用和使用的代码方法。

    【讨论】:

      【解决方案4】:

      在将字符串发送到 INSERT 语句时应使用 (') 值 (@{0},'@{1}','@{2}','@{3}','@{4}','@{5}','@{6}',' @{7}',{8}) 您还应该捕获 SQLExeprion

      【讨论】:

      • 很好的答案,我可能会按照这里的建议使用命名参数stackoverflow.com/questions/809246/… 为什么?因为在我的某些 sql 语句中,您可能会多次使用相同的参数。
      猜你喜欢
      • 1970-01-01
      • 2013-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多