В настоящее время я разрабатываю приложение, в котором пользователь может сохранять новостные статьи на database в локальном хранилище. Вот как я выполняю эту транзакцию.
INSERT INTO Article(title, description, url, urltoimage, publishedat) VALUES("$title", "$description", "$url", "$urlToImage", "$publishedAt")
Единственная проблема, с которой я столкнулся, заключается в том, что любая часть транзакции содержит quotation marks внутри string, возникает ошибка в строках ...
"Calling Crypto a ‘Harsh Mistress,’ ShapeShift Announces Major Layoffs", "ShapeShift exchange has become the latest in a string of cryptocurrency and blockchain companies to announce major layoffs due to the ongoing cryptocurrency bear market. In a Medium post entitled "Overcoming ShapeShift's Crypto Winter and the"
DB Error: 1 "near "Overcoming": syntax error"
Рассматривая всю статью, наличие дополнительного quotation marks обманывает запрос, заставляя полагать, что description заканчивается на слове озаглавленный, и, таким образом, прерывается на слове Преодоление, которое в идеале все еще должно рассматриваться запросом как часть строки description.
Я ищу способ предотвратить это, чтобы всю статью можно было сохранить на локальный database, несмотря на наличие лишнего quotation marks.
Это вся ошибка, создаваемая дротик:
DatabaseException(Error Domain=FMDatabase Code=1 "near "Overcoming": syntax error" UserInfo = {NSLocalizedDescription=near "Overcoming": syntax error}) sql 'INSERT INTO Article(title, description, url, urltoimage, publishedat) VALUES("Calling Crypto a ‘Harsh Mistress,’ ShapeShift Announces Major Layoffs", "ShapeShift exchange has become the latest in a string of cryptocurrency and blockchain companies to announce major layoffs due to the ongoing cryptocurrency bear market. In a Medium post entitled "Overcoming ShapeShift's Crypto Winter and the", "https://www.ccn.com/calling-crypto-a-harsh-mistress-shapeshift-announces-major-layoffs/", "https://www.ccn.com/wp-content/uploads/2019/01/shapeshift-crypto-exchange-layoffs.jpg", "2019-01-08T18:24:58Z")' args []}
Редактировать;
Это полный код, который я использую в дротике для решения этой проблемы.
Creating the table
var databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'saved_articles.db');
Database database = await openDatabase(path, version: 1,
onCreate: (Database db, int version) async {
// When creating the db, create the table
await db.execute('CREATE TABLE Article (id INTEGER PRIMARY KEY, title TEXT, description TEXT, url TEXT, urltoimage TEXT, publishedat TEXT, CONSTRAINT article_constraint UNIQUE (title));');
});
Inserting the article
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');
});
Спасибо
«база данных в локальном хранилище», вероятно, означает в браузере и будет примерно таким же, как в обычном JS.
@ GünterZöchbauer Я не знаком с JavaScript - что это означает в моем вопросе? Под локальным хранилищем я подразумеваю файл .db на телефоне пользователя.
@Jake Вы используете для этого Dart или JS? Какую библиотеку SQL вы используете? Не могли бы вы опубликовать несколько строк кода, которые вызывают запрос на вставку?
@DaveC Да, это пакет, спасибо за комментарий к SQL-инъекции, кстати, я об этом не подумал. Не уверен, что это имеет большое значение, поскольку данные не являются конфиденциальными и их будет сложно внедрить в любом случае, поскольку к ним можно получить доступ только через устройство iOS.
@DaveC Я использую движок Dart, чтобы выполнить это, позвольте мне быстро отредактировать, чтобы показать вам, что я делаю.
Неважно, сложно ли колоть, это обычная практика. Это также сделает побег персонажа, который вам нужен!
Просто никогда не используйте конкатенацию строк для значений параметров sql, независимо от того, насколько безопасно или небезопасно, по вашему мнению, в текущих ситуациях. Просто приводит к вредным привычкам.
@DaveC Я учту предупреждение и скорректирую свой код, спасибо за подсказку.
@DaveC Я внес правки, дайте мне знать, если вам нужно больше поработать


При выполнении rawQuery используйте механизмы выхода, предоставляемые sqflite.
Вместо:
int id1 = await txn.rawInsert(
'INSERT INTO Article(title, description, url, urltoimage, publishedat)
VALUES("$title", "$description", "$url", "$urlToImage", "$publishedAt")'
);
Используйте этот метод:
int id1 = await txn.rawInsert(
'INSERT INTO Article(title, description, url, urltoimage, publishedat)
VALUES(?, ?, ?, ?, ?)',
[title, description, url, urlToImage, publishedAt]
);
Это также должно экранировать любые зарезервированные символы SQL.
Работает как шарм, когда выполняется, хотя этот код не требует $ до title, description и т. д. И не будет работать с ними, поэтому, возможно, внесите изменения, чтобы прояснить это.
Конечно, не беспокойтесь, я никогда не касался Дарта, так что не был уверен, лол. C# навсегда.
Вам необходимо использовать некоторую форму реализации параметризации, которая, вероятно, предоставляется любым клиентом SQL, используемым в Dart. Вы должны категорически избегать объединения строк вручную, чтобы избежать внедрения SQL. Основы SQL 101 :)