PostgreSQL, Npgsql returning 42601: syntax error at or near "$1"

时间:2016-06-10 16:14:24

标签: postgresql dapper npgsql

I'm trying to use Npgsql and/or Dapper to query a table and I keep running into Npgsql.PostgresException 42601: syntax error at or near "$1".

Here is what I've got trying it with NpgsqlCommand:

  using (var conn = new NpgsqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["postgres"].ConnectionString))
  {
    conn.Open();
    using (NpgsqlCommand command = new NpgsqlCommand("select * from Logs.Logs where Log_Date > current_date - interval @days day;", conn))
    {
      command.Parameters.AddWithValue("@days", days);
      var reader = command.ExecuteReader();

I've also tried it with Dapper(my preferred method) with:

  using (var conn = new NpgsqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["postgres"].ConnectionString))
  {
    conn.Open();
    var logs = conn.Query<Log>("select * from Logs.Logs where Log_Date > current_date - interval @days day;", new {days = days});

Either way I get the same Npgsql.PostgresException 42601: syntax error at or near "$1" error. The Statement in the Exception shows: select * from Logs.Logs where Log_Date > current_date - interval $1 day

Note, if I do the following it works fine, but it's not properly parameterized:

var logs = conn.Query<Log>("select * from Logs.Logs where Log_Date > current_date - interval '" + days + "' day;");

What am I doing wrong? I very much appreciate any feedback. Thank you.

3 个答案:

答案 0 :(得分:2)

PostgreSQL不允许您在查询中的任何位置粘贴参数。您可以通过以下方式实现您的目标:

var command = new NpgsqlCommand("select * from Logs.Logs where Log_Date > current_date - @days", conn))
command.Parameters.AddWithValue("@days", TimeSpan.FromDays(days));

这样您就可以将间隔从Npgsql直接传递给PostgreSQL,而不是用于创建该间隔的表达式的一部分。

答案 1 :(得分:1)

要从日期中减去天数(假设log_date是数据类型date),您可以简化:

"SELECT * FROM logs.logs WHERE log_date > CURRENT_DATE - @days;"

并提供@days作为未加引号的数字文字(仅限数字) - 这被视为integer。这更有效,因为date - integer会返回date,而date - interval会返回timestamp

The manual about interval input.

答案 2 :(得分:1)

我使用DapperExtensions遇到此错误

添加

DapperExtensions.DapperExtensions.SqlDialect = new PostgreSqlDialect();
DapperAsyncExtensions.SqlDialect = new PostgreSqlDialect();

在创建连接之前,已解决了问题