使用 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'));
}
我收到错误:ORDER BY 中的 42601 非整数常量
。
上面的代码是辅助类的一个方法。我使用以下代码运行它。
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'));
}
最佳答案
我认为 SQL 标准不支持对列名使用绑定(bind)变量(对表名、索引名等也是如此)。这些名称需要使用例如字符串连接或插值在 SQL 语句中进行硬编码。
但请确保您不使用此处用户输入的任何值和/或进行适当的验证和完整性检查,以免引入任何 SQL 注入(inject)后门。
PostgreSql 包不会处理您传递给执行的 SQL,它只会以所需的格式将其转发到数据库并解析结果(目前不正确,但它应该以这种方式工作,请参阅下面的评论)。
一个例子:
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'));
}
关于postgresql - 使用 dart 和 postgresql 按查询排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30191445/