TypeScript: параметризованный запрос с множественным обновлением на Postgres завершается неудачно, оператор не существует: text = integer - PullRequest
0 голосов
/ 07 мая 2020

У меня есть следующая таблица базы данных:

CREATE TABLE IF NOT EXISTS notes 
(id SERIAL PRIMARY KEY, board_id INT NOT NULL, note_type INT NOT NULL, note_location VARCHAR(150), 
    note_property VARCHAR(100), text TEXT, meta VARCHAR(150), 
UNIQUE (id, board_id), FOREIGN KEY (board_id) REFERENCES boards(id));

У меня есть многострочный оператор вставки, использующий параметризованные значения, который выглядит так:

INSERT INTO notes(board_id, note_type, note_location, note_property, text, meta) VALUES ($1, $2, $3, $4, $5, $6), ($7, $8, $9, $10, $11, $12), (..);

Это загружается массивом значений, обрабатываемым for-l oop. Теперь это работает как есть, и я могу добавить большое количество строк одновременно в один запрос.

Теперь я пытаюсь сделать то же самое для оператора UPDATE, который разделяет большую часть кода с оператором INSERT builder:

const args: string[] = [];
let argNum = 1;
let sql = `UPDATE notes AS n SET board_id = c.board_id, note_type = c.note_type, note_location = c.note_location, note_property = c.note_property, text = c.text, meta = c.meta FROM (VALUES`;
for (let i = 0; i < pBoardObj.length; i++) {
    args.push(pBoardObj[i].dbId);
    args.push(boardId);
    args.push(pBoardObj[i].class);
    const notLoc = {x: pBoardObj[i].position.x, y: pBoardObj[i].position.y, z: pBoardObj[i].position.z};
    args.push(JSON.stringify(notLoc));
    const notProp: {[k: string]: any} = {};
    notProp.type = pBoardObj[i].type;
    notProp.textSize = pBoardObj[i].textSize;
    if (pBoardObj[i].scale) {
        notProp.scale = pBoardObj[i].scale;
    }
    args.push(JSON.stringify(notProp));
    const text = pBoardObj[i].text || '';
    args.push(text);
    args.push('');
    sql += `($${argNum}, $${argNum += 1}, $${argNum += 1}, $${argNum += 1}, $${argNum += 1}, $${argNum += 1}, $${argNum += 1})`;
    sql += ((i < pBoardObj.length - 1) ? ', ' : '');
    argNum += 1;
}
sql += `) AS c(id, board_id, note_type, note_location, note_property, text, meta) WHERE c.id = n.id;`;
const pgDbQuery = await this.pgdb.query(sql, args);

Это многострочный оператор обновления, основанный на этот ответ здесь , обновленный, поэтому окончательный запрос должен привести к примерно такому результату с массивом в качестве входных данных.

UPDATE notes AS n SET board_id = c.board_id,note_type = c.note_type,note_location = c.note_location,note_property = c.note_property,text = c.text,meta = c.meta 
FROM (VALUES($1, $2, $3, $4, $5, $6, $7), ($8, $9, $10, $11, $12, $13, $14)) AS c(id, board_id, note_type, note_location, note_property, text, meta) 
WHERE c.id = n.id;

Но для этого запроса я получаю эту ошибку:

error: operator does not exist: text = integer
No operator matches the given name and argument type(s). You might need to add explicit type casts.

Если попытаться изменить args с string на any, в надежде, что тип будет сохранились. Я также изменил тип параметра функции приема на any. Я даже попытался изменить массив параметров так, чтобы он представлял собой массив объектов, а не просто значений ({id: number, board_id: number, note_type: number, etc}).

Пока не повезло. Ничего из того, что я пробовал, не обходилось без этой ошибки, которую я даже полностью не понимаю. Первоначально это был простой запрос на замену строки c, который работал до тех пор, пока нам не потребовалась специальная обработка символов, где он не удался. Я также понимаю, что такой подход может иметь некоторые проблемы с безопасностью.

Следует отметить, что проект, над которым я работаю, находится на стадии бета-тестирования, и это в основном для демонстрационных целей, и поэтому мы не совсем заинтересован в добавлении пакетов или библиотек слева и справа, чтобы решить эту проблему (в будущем мы, возможно, даже не go с postgres).

Могу ли я что-нибудь сделать, чтобы исправить это?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...