SQL字符串含引号报错:Dart本地存储新闻文章的解决方案问询
解决SQL插入时含引号字符串导致的语法错误问题
这是开发本地数据库应用时很常见的坑——直接把变量拼进SQL语句里,不仅会因为字符串中的引号提前闭合SQL语法导致报错,还存在SQL注入的安全风险,咱们用正确的姿势来解决它:
问题根源
你当前的代码是把$title、$description这些变量直接拼接进INSERT语句的字符串里,当描述(或其他字段)包含双引号时,比如"entitled" Overcoming...,SQL会认为第二个VALUES值在"entitled"这里就结束了,后面的Overcoming就变成了无效的SQL语法,于是抛出syntax error。
正确解决方案:使用参数化查询
sqflite提供了参数化查询的方式,会自动帮你处理字符串中的特殊字符(包括引号),同时规避SQL注入风险。有两种常用的写法:
方法1:位置占位符(?)
把SQL语句中的变量替换成?,然后在第二个参数里按顺序传入变量列表:
await database.transaction((txn) async { int id1 = await txn.rawInsert( 'INSERT INTO Article(title, description, url, urltoimage, publishedat) VALUES(?, ?, ?, ?, ?)', [title, description, url, urlToImage, publishedAt] ); debugPrint('inserted1: $id1'); });
方法2:命名占位符(:变量名)
用:字段名作为占位符,然后传入一个键值对的Map,可读性更强:
await database.transaction((txn) async { int id1 = await txn.rawInsert( 'INSERT INTO Article(title, description, url, urltoimage, publishedat) VALUES(:title, :description, :url, :urltoimage, :publishedat)', { 'title': title, 'description': description, 'url': url, 'urltoimage': urlToImage, 'publishedat': publishedAt } ); debugPrint('inserted1: $id1'); });
为什么这能解决问题?
当使用参数化查询时,sqflite会负责把你的变量值正确转义(比如把字符串里的双引号转成\"),确保SQL语句的语法结构不会被破坏,同时也能防止恶意构造的字符串篡改SQL逻辑。
以后处理数据库的增删改查时,都尽量用这种参数化的方式,别再直接拼接字符串啦~
内容的提问来源于stack exchange,提问作者Jake
相关产品推荐
相关产品推荐

