首页 > 解决方案 > 如何在 Ruby 中使用 PSQL 时间戳函数作为参数?

问题描述

我正在使用 Ruby 方法从 Postgres 数据库中访问任务信息。

def query(statement, *params)
    @logger.info("#{statement}: #{params}")
    @db.exec_params(statement, params)
end

def tasks_completed_for_date(date="CURRENT_DATE")   
    sql = <<~SQL
      SELECT tasks.name AS task_name,
             timetable.start_at AS start_at,
             timetable.end_at AS end_at,
             timetable.duration AS duration,
             timetable.start_at::date AS task_date
        FROM tasks
        JOIN timetable ON tasks.id = timetable.task_id
        WHERE timetable.start_at::date = $1
          AND timetable.duration IS NOT NULL
        ORDER BY tasks.name ASC;
    SQL

    result = query(sql, date)

    if result.ntuples > 0
      result.map do |tuple|
        {
          task_name: tuple['task_name'],
          start_at: tuple['start_at'].slice(11, 5),
          end_at: tuple['end_at'].slice(11, 5),
          total_time: tuple['duration'].slice(0, 5),
          task_date: tuple['task_date'].slice(5, 5)
        }
      end
    end
  end

我希望查询的默认值是当前日期。我认为最好的方法是在调用tasks_completed_for_date字符串的方法中设置默认参数CURRENT_DATE。该字符串将被 PSQL 解释为方法CURRENT_DATE并根据该日期返回数据。相反,我收到以下错误:

错误:不再支持日期/时间值“当前”

我根本没有使用“当前”,而且我知道无论它是什么,它都已经过时了。有没有办法将 PSQL 方法传递给查询(代替 $1),因为我在这里尝试不会导致错误?

标签: rubypostgresqlparameters

解决方案


您的问题是$1占位符的值将是字符串 'CURRENT_DATE',而不是文字值CURRENT_DATE。结果是您实际上是在说'CURRENT_DATE'::date,但这是行不通的:

psql> select 'current_date'::date;
ERROR:  date/time value "current" is no longer supported
LINE 1: select 'current_date'::date;
               ^

您需要将文字值current_date放入查询中,或者找到一个正确转换为日期的字符串。最简单的方法是使用'now'它,因为它可以很好地转换:

psql> select 'now'::date;
    date    
------------
 2019-10-22
(1 row)

快速更改方法的日期参数的默认值应该足够好:

def tasks_completed_for_date(date = 'now')

推荐阅读