android.database.sqlite.SQLiteException:靠近“编码”:语法错误(代码 1)

Posted

技术标签:

【中文标题】android.database.sqlite.SQLiteException:靠近“编码”:语法错误(代码 1)【英文标题】:android.database.sqlite.SQLiteException: near "coding": syntax error (code 1) 【发布时间】:2021-10-04 22:28:29 【问题描述】:

您好,我正在创建一个 android 应用程序,当我在公告板上写字时,它允许将标题、内容、价格、数字 (1) 和图像存储在数据库中。将发布注册到数据库时发生错误。 这几天我一直在想,但我不知道为什么。

以下是我的错误。

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.project, PID: 2816
    android.database.sqlite.SQLiteException: near "coding": syntax error (code 1): , while compiling: INSERT INTO writing (title, content, price, person, count, image) VALUES (test coding, this is test, 3000, 2, 1, ?)
        at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
        at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:890)
        at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:501)
        at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
        at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
        at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
        at android.database.sqlite.SQLiteDatabase.compileStatement(SQLiteDatabase.java:1070)
        at com.example.swu_guru.GroupBuyingWrite$onCreate$2.onClick(GroupBuyingWrite.kt:97)
        at android.view.View.performClick(View.java:6294)
        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
        at android.view.View$PerformClick.run(View.java:24770)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

这是数据库类 (MyDBHelper.kt)

package com.example.project

import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper

class MyDBHelper(context: Context) : SQLiteOpenHelper(context, "gbDB", null, 1)
    override fun onCreate(db: SQLiteDatabase?) 
        db!!.execSQL("CREATE TABLE writing (" + "title text, " +
                "content text, " + "price INTEGER, " + "person INTEGER, " + "count INTEGER, " + "image BLOB);")
    

    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) 

    

这是创建帖子部分。 (GroupBuyingWrite.kt)

并且调试表明该类的部分var stmt: SQLiteStatement = sqlitedb.compileStatement(insQuery)有错误。

        btnGBWregister.setOnClickListener 

            sqlitedb = myDBHelper.writableDatabase

            var title: String ?= edtGBWtitle.text.toString()
            var content: String = edtGBWcontent.text.toString()
            var price: String = edtGBWprice.text.toString()
            var person: String = edtGBWperson.text.toString()
            var count: String = GBWcount.toString()
            var image: Drawable = imgGBWimageview.drawable
            var byteArray: ByteArray ?= null


            try 
                val bitmapDrawable = image as BitmapDrawable?
                val bitmap = bitmapDrawable?.bitmap
                val stream = ByteArrayOutputStream()
                bitmap?.compress(Bitmap.CompressFormat.PNG, 100, stream)
                byteArray = stream.toByteArray()
                Log.d("image save", "image saving")
             catch (cce: ClassCastException) Log.d("image null", "image null")

          

            var insQuery: String = "INSERT INTO writing (title, content, price, person, count, image) " +
                    "VALUES ($title, $content, $price, $person, $count, ?)"
            var stmt: SQLiteStatement = sqlitedb.compileStatement(insQuery)
            stmt.bindBlob(1, byteArray)
            stmt.execute()
        

【问题讨论】:

对所有变量使用参数,而不仅仅是byteArray 【参考方案1】:

语法错误是因为字符串没有用单引号括起来。

所以不是"VALUES ($title, $content, $price, $person, $count, ?)"

你应该有"VALUES ('$title', '$content', $price, $person, $count, ?)"

但是,最好将值绑定,所以"VALUES (?,?,?,?,?,?)" 与适当的stmnt.bind....

所以:-

        var insQuery: String = "INSERT INTO writing (title, content, price, person, count, image) " +
                "VALUES (?,?,?,?,?,?)"
        var stmt: SQLiteStatement = sqlitedb.compileStatement(insQuery)
        stmt.bindString(1,title)
        stmt.bndString(2,content)
        stmt.bndString(3,price)
        stmt.bindString(4,person)
        stmt.bindString(5,count)
        stmt.bindBlob(6,byteArray)
        stmt.execute()

另一种方法是使用 SQLiteDatabase insert 便捷方法以及放入 ContentValues 的值。

这可能是:-

    var cv: ContentValues = ContentValues()
    cv.put("title",title)
    cv.put("content",content)
    cv.put("price",price)
    cv.put("person",person)
    cv.put("count",count)
    cv.put("image",image)
    var rowid = sqlitedb.insert("writing",null,cv) //rowid will be the rowid of the inserted row else -1 if row couldn't be inserted
请注意,insert 方法等同于 INSERT OR IGNORE ....,因此要真正充分反映您的 SQL,您将使用 insertOrThrow 方法。 insert 方法的优点是,如注释所述,它返回插入行的 rowid,如果无法插入行,则返回 -1。它还构建底层 SQL(根据 ContententValues(put 的第一个参数)中指定的列)。值本身是有约束力的。

【讨论】:

@user16452112,如果您发现答案有帮助,请考虑将其标记为已回答。

以上是关于android.database.sqlite.SQLiteException:靠近“编码”:语法错误(代码 1)的主要内容,如果未能解决你的问题,请参考以下文章