2016-12-02 5 views
1

Я использую koa v2 с pg-promise. Я пытаюсь сделать простой SELECT 2 + 2; в Parameterized/Подготовили заявление, чтобы проверить мои настройки:Параметрированные/подготовленные заявления использование pg-prom

// http://127.0.0.1:3000/sql/2 
router.get('/sql/:id', async (ctx) => { 
    await db.any({ 
    name: 'addition', 
    text: 'SELECT 2 + 2;', 
    }) 
    .then((data) => { 
     console.log('DATA:', data); 
     ctx.state = { title: data }; // => I want to return num 4 instead of [Object Object] 
    }) 
    .catch((error) => { 
     console.log('ERROR:', error); 
     ctx.body = '::DATABASE CONNECTION ERROR::'; 
    }) 
    .finally(pgp.end); 

    await ctx.render('index'); 
}); 

Который делает [Object Object] в шаблонах и возвращение на консоль от pg-monitor:

17:30:54 connect([email protected]) 
17:30:54 name="addition", text="SELECT 2 + 2;" 
17:30:54 disconnect([email protected]) 
DATA: [ anonymous { '?column?': 4 } ] 

Мои проблема:

Я хочу сохранить результат 4 в ctx.state. Я не знаю, как я могу получить к нему доступ в пределах [ anonymous { '?column?': 4 } ]?

Благодарим за помощь!

Edit:

Я нашел другой recommended(1)ways(2) к работе с именованными параметрами в официальной вики.

// http://127.0.0.1:3000/sql/2 
router.get('/sql/:id', async (ctx) => { 
    const obj = { 
    id: parseInt(ctx.params.id, 10), 
    }; 
    await db.result('SELECT ${id} + ${id}', obj) 
    .then((data) => { 
     console.log('DATA:', data.rows[0]['?column?']); 
     ctx.state = { title: data.rows[0]['?column?'] }; // => 4 
    }) 
    .catch((error) => { 
     console.log('ERROR:', error); 
     ctx.body = '::DATABASE CONNECTION ERROR::'; 
    }) 
    .finally(pgp.end); 

    await ctx.render('index'); 
}); 

Я изменил any объект result, который возвращался необработанный текст. Чем я могу получить номер 4 как объект javascript. Я делаю что-то неправильно? Есть ли другой способ получить доступ к этому значению?

Что такое рекомендуемый, более быстрый и безопасный способ использования?

ответ

1

Поскольку вы запрашиваете только одно значение, то следует использовать метод one:

db.one({ 
    name: 'addition', 
    text: 'SELECT 2 + 2 as value', 
}, [], v => +v.value) 
    .then(value => { 
     console.log('value:', value); //=> value: 4 
    }); 

Первое, мы называем результат как value, а затем мы используем дополнительное преобразование значения с преобразованием: v => +v.value.

И для такого примера вы не можете использовать типы PreparedStatement или ParameterizedQuery, потому что они формат запроса на стороне сервера, и PostgreSQL не поддерживает синтаксис как $1 + $1.

Настоящий вопрос - вам действительно нужны эти типы?

+0

Я хочу использовать метод запроса, который безопасен для SQL-инъекции. Часть лучших практик в документах API и ответах reddit предполагает, что это способ сделать это (поэтому я не знаю, действительно ли это мне нужно или нет). Мое приложение сначала не будет делать почтовые запросы (БД будет действовать как json-файл или API). Маршрутизация решит, что нужно запрашивать из db (параметры URL). Мой второй пример кажется мне простым синтаксисом. У вас что-нибудь против, почему вы только рекомендовали первый? – Lanti

+1

'pg-prom' обеспечивает собственную защиту от SQL-инъекций. Например, см. [Имена SQL] (https://github.com/vitaly-t/pg-promise#sql-names), которые вы должны использовать для любых динамических столбцов;) Во втором примере нет ничего конкретного. И вы всегда должны указывать расчетные столбцы, чтобы иметь возможность обращаться к ним напрямую. –

+0

Я закончил с этой реализацией: 'db.one ('SELECT $ {id} + $ {id} как VALUE;', {id: parseInt (ctx.params.id, 10)}, v => v.value) 'и это работает. Я оставил '[]' и '+' перед 'v.value'. Что делает массив '[]' и '+' здесь? – Lanti

 Смежные вопросы

  • Нет связанных вопросов^_^