使用dart和postresql驱动程序运行此查询时
getPost(int limit, int offset, String order_by){
connect(uri).then((conn){
conn.query('''select * from posts
order by @order_by
limit @limit offset @offset''', {'limit': limit, 'offset': offset, 'order_by': order_by})
.toList()
.then((rows){
print(rows);
})
.whenComplete(() => conn.close());
})
.catchError((err) => print('Error in getPost: $err'));
}
我得到了Error: 42601 non-integer constant in ORDER BY
。
上面的代码是一个帮助类的方法。我使用以下代码运行它。
dbUtil.getPost(10, 10, "posted_at");
我读了here,postgresql期望一个字符串文字。这就是为什么我也试过这段代码dbUtil.getPost(10, 10, r"posted_at");
没有成功。
如果我将@order_by
替换为posted_at
,则查询会正确返回值。
有人知道如何解决这个问题吗?
工作代码的灵感来自以下答案。
getPost(int limit, int offset, String order_by){
connect(uri).then((conn){
var sb = new StringBuffer();
sb.write("select * from posts ");
sb.write(order_by);
sb.write(" limit @limit offset @offset");
String query = sb.toString();
conn.query(query, {'limit': limit, 'offset': offset})
.toList()
.then((rows){
print(rows);
})
.whenComplete(() => conn.close());
})
.catchError((err) => print('Error in getPost: $err'));
}
答案 0 :(得分:2)
我不认为SQL标准支持使用绑定变量作为列名(表名,索引名等相同)。这些名称需要在SQL语句中使用例如字符串连接或插值进行硬编码。
但请确保您不要在此处使用来自用户输入的任何值和/或进行适当的验证和清理检查以不引入任何SQL注入后门。
PostgreSql包不会处理您传递给执行的SQL,它只会以所需的格式将其转发到数据库并解析结果(当前不是真的,但它应该以这种方式工作,请参阅下面的注释)。 / p>
一个例子:
bool isValidSqlColumnName(String columnName) {
return new RegExp(r'^[a-zA-Z_][a-zA-Z0-9_]*$').hasMatch(columnName);
}
getPost(int limit, int offset, String order_by){
if(!isValidSqlColumnName(order_by)) {
throw 'Only valid column names are accepted.';
}
connect(uri).then((conn){
conn.query('''select * from posts
order by $order_by
limit @limit offset @offset''', {'limit': limit, 'offset': offset, 'order_by': order_by})
.toList()
.then((rows){
print(rows);
})
.whenComplete(() => conn.close());
})
.catchError((err) => print('Error in getPost: $err'));
}