Почему я не могу объединить переменные до конца моего SQL запроса? - PullRequest
2 голосов
/ 25 апреля 2020

Я пытаюсь использовать параметры в своих вызовах API, чтобы добавить строку с заданными значениями в таблицу в базе данных SQLite. Это работает, когда я просто объединяю переменную в конец запроса, но не когда я объединяю несколько переменных и некоторые дополнительные SQL запросы (например, преобразование переменных в определенный тип данных.

Я заметил, что запросы SQL имеют цветовую кодировку определенным образом c, но составные части окрашены как обычные строки. Вот код:

let id = req.query.id;
        let filename = req.query.filename;
        let is_folder = req.query.is_folder;
        let parent = req.query.parent;
        let guid = req.query.guid;
        let size = req.query.size;
        await initDatabasePromise;
        const result = await database.all(`INSERT INTO content VALUES (` + id + `, CONVERT(varchar(512), ` + filename + `), ` + is_folder
            + `, ` + parent + `, CONVERT(varchar(64), ` + guid  + `), ` + size  + `, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)`);
        res.json(result);

А вот изображение, которое показывает цветовую кодировку, в случае, если я неправильно ее понимаю:

Вот часть моего кода, которая показывает цветовые кодированные части

Here is a portion of my code, which shows the color coded parts

И это ошибка, которую я получаю:

[Error: SQLITE_ERROR: no such column: undefined] {
  errno: 1,
  code: 'SQLITE_ERROR'
}
[Error: SQLITE_ERROR: near ")": syntax error] {
  errno: 1,
  code: 'SQLITE_ERROR'
}

А вот строка запроса, сохраненная как переменная и распечатанная. Я понятия не имею, почему она напечатала две из них, или почему все получилось to undefined в первом:

INSERT INTO content VALUES (undefined, CONVERT(varchar(512), undefined), undefined, undefined, CONVERT(varchar(64), undefined), undefined, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)

INSERT INTO content VALUES (3, CONVERT(varchar(512), Untitled), true, 1, CONVERT(varchar(64), 012345), 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)

Может быть, я неправильно преобразовываю типы данных? Может быть, остальная часть запроса SQL интерпретируется как одна гигантская строка? У кого-нибудь есть идеи, которые могут мне помочь? о ut?

Редактировать: Если есть другой способ ввода параметров в запрос SQL, пожалуйста, дайте мне знать! Я новичок в SQL, и я буду благодарен за любой совет, который смогу получить. Однако, пожалуйста, не будь грубым или снисходительным, я действительно новичок в этом, и я просто пытаюсь получить некоторую помощь. Спасибо.

1 Ответ

1 голос
/ 25 апреля 2020

Вы можете взглянуть на документацию node-sqlite3 о том, как использовать параметры в ваших запросах. Вы определенно не хотите взять необработанные значения из строки запроса и объединить их непосредственно в ваши SQL запросы, поскольку это делает ваше приложение уязвимым для SQL инъекций атак.

Вместо этого ваш запрос должен выглядеть примерно так:

const result = await database.all(
    `INSERT INTO content VALUES (?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)`, 
    [req.query.id, req.query.filename, req.query.is_folder, req.query.parent, req.query.guid, req.query.size],
);

Вы также можете использовать именованные параметры:

const result = await database.all(
    `INSERT INTO content VALUES ($id, $filename, $is_folder, $parent, $guid, $size, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)`, {
    $id: req.query.id,
    $filename: req.query.filename,
    $is_folder: req.query.is_folder,
    $parent: req.query.parent,
    $guid: req.query.guid,
    $size: req.query.size,
});

Даже тогда я, вероятно, не передавал бы параметры строки запроса непосредственно в ваш запрос, если вы точно не знаете, что это будут значения, которым вы можете доверять ... вам, вероятно, нужно также "санировать" типы / значения; например,

  • is_folder - это то, что вы хотели бы преобразовать в целочисленное или логическое истинное / ложное значение
  • id, parent и size, вероятно, вещи, которые вы хотели бы преобразовать в целые числа
  • filename - это то, где вы можете удалить слэши / папки и оставить только имя файла

Есть и другие вещи, которые следует учитывать как с точки зрения базы данных:

  • id само по себе может быть чем-то, что вы хотите автоматически увеличивать, так что его вообще не нужно указывать вручную
  • Ваши столбцы меток времени могут быть по умолчанию в базе данных, поэтому вам не нужно указывать их в запросах INSERT.

Возможно, вы захотите быть более явным с помощью оператора INSERT, а не только с указанными вами значениями также укажите столбец. Примерно так:

INSERT INTO content (id, filename, is_folder, parent, guid, size, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...