使用dart和postresql查询排序

时间:2015-05-12 12:51:24

标签: postgresql dart

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

1 个答案:

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