2016-12-02 5 views
1

koa v2pg-promiseを使用しています。私は自分の設定をテストするためにパラメータ化/プリペアドステートメント内の単純なSELECT 2 + 2;をしよう:テンプレートで[Object Object]をレンダリングし、pg-monitorからコンソールにこれを返すパラメータ化/プリペアドステートメント使用法pg-promise

// 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'); 
}); 

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 } ] 

マイ問題:

結果4ctx.stateに保存します。 [ anonymous { '?column?': 4 } ]の中でどうすればアクセスできますか?

ありがとうございました!

編集:

私は公式のwikiで名前付きパラメータを扱うに別の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'); 
}); 

私は生のテキストを返した、resultanyオブジェクトを変更しました。私よりもアクセス番号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ドキュメントやレッドダイズのベストプラクティスの一部は、これを行う方法であることを示唆しています(実際に必要かどうかは分かりません)。私のアプリは、最初にポストリクエストを行いません(DBはjsonファイルやAPIのように動作します)。ルーティングは、db(URLパラメータ)から何を照会するかを決定します。私の2番目の例は私には単純な構文があるようです。なぜあなたは最初のものだけを推奨したのですか? – Lanti

+1

'pg-promise'はSQL注入に対する独自の保護を提供します。たとえば、任意の動的列に使用する[SQL Names](https://github.com/vitaly-t/pg-promise#sql-names)を参照してください。)2番目の例では何も特定されていません。また、直接計算カラムを指定して、それらのカラムに直接名前を付ける必要があります。 –

+0

私はこの実装で終わりました: 'db.one( 'SELECT $ {id} + $ {id} as VALUE;'、{id:parseInt(ctx.params.id、10)}、v => v.value ) 'それは働いている。私は 'v.value'の前に' [] 'と' + 'を付けなかった。配列 '[]'と '+'はここで何をしますか? – Lanti

関連する問題