为啥相同的 SQL 查询可能在 SQL Developer 和代码中返回不同的结果?

Posted

技术标签:

【中文标题】为啥相同的 SQL 查询可能在 SQL Developer 和代码中返回不同的结果?【英文标题】:Why might the same SQL query return different results in SQL Developer and in code?为什么相同的 SQL 查询可能在 SQL Developer 和代码中返回不同的结果? 【发布时间】:2018-06-19 17:31:24 【问题描述】:

我的应用程序中有一个查询,该查询应该返回今天或更早到期但尚未发送通知的所有调查。查询如下所示:

select "surveys".* from "surveys" 
    where "reminder_count" = 0 and
    trunc("date") <= to_date(CURRENT_DATE, 'YY-MM-DD')

这是表格中的数据:

| id | user_id | token                            | date     | reminder_count |
|----|---------|----------------------------------|----------|----------------|
| 1  | 1       | 8c01a36d33a18a1ee9e0e6d26aa90eed | 18-06-18 | 0              |
| 2  | 1       | d608650acea377312eb18aea1e14688a | 18-07-16 | 0              |

如您所见,第一个条目的日期是昨天,第二个条目是几周前的。因此查询应该只返回第一行。当我直接在 SQL Developer 中执行它时,它就是这样做的。

但是,当我在代码中使用它时(带有 Objection.js 和 Knex 的 javascript),它会忽略 date 子句并返回两行。

这是我使用的代码:

const surveysDue = await Survey.query()
  .where(reminderCount: 0)
  .where(raw('trunc("date")'), '<=', raw('to_date(CURRENT_DATE, \'YY-MM-DD\')'))

这是该查询的调试输出显示的内容:

 method: 'select',
  options: ,
  timeout: false,
  cancelOnTimeout: false,
  bindings: [ 0 ],
  __knexQueryUid: '2a22ccb5-4763-42d3-bf0a-6ea95a7b9c7e',
  sql:
   'select "surveys".* from "surveys" where "reminder_count" = ? and trunc("date") <= to_date(CURRENT_DATE, \'YY-MM-DD\')' 

日期子句显然在查询中,这只会增加为什么它不起作用的问题。请你指出我在哪里寻找解决方案的正确方向吗?或者也许有人已经遇到过这样的问题?

谢谢。

【问题讨论】:

CURRENT_DATE 返回 DATE 数据类型;对它应用 TO_DATE 函数是错误的(所以删除它)。在这里并不重要,但是 - 在 Oracle 中使用小写或混合大小写创建对象(即将它们括在双引号中)意味着头痛。如果我是你,我会避免它。 @Littlefoot 感谢返回类型提示。但它不会改变查询的任何内容:TO_DATE 只是返回相同的对象。就小写对象名而言,只是出于美观的原因:在 JS 代码中看起来很丑陋,而且仅使用这些标识符,很少有人需要直接查询 DB 没关系; TO_DATE + CURRENT_DATE 是完全错误的。我已经看到你解决了这个问题;我很高兴你能做到。 【参考方案1】:

问题

由于某种原因,SQL Developer 中的CURRENT_DATE 是正确的 (18-06-19),但是,当通过代码查询时,它会返回一年后的今天 (19-06-19)。因此它返回两行,因为它们都在 2018 年。

解决方案

我会尝试找出日期错误的原因,但这可能会花费太多时间,并且在 Oracle 中处理日期从来都不是一件简单的任务......所以我只是用一个 JS Date 实例替换了CURRENT_DATE我自己生成:

const surveysDue = await Survey.query()
  .where(reminderCount: 0)
  .where(raw('trunc("date")'), '<=', moment().toDate())

这个答案本身并没有真正解决问题(它只是一种解决方法),但也许至少它可以为遇到同样问题的人指明正确的方向。

【讨论】:

返回的日期没有错,可能是你的应用宿主机的时钟或者NLS_SETTINGS设置不正确。 @KaushikNayak 主机时钟肯定设置正确,因为我的代码返回正确的日期。 NLS_SETTINGS 是按会话还是按服务器设置?

以上是关于为啥相同的 SQL 查询可能在 SQL Developer 和代码中返回不同的结果?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 SQL 查询中输入的日期值不等于 excel 工作表中的相同日期值?

为啥针对 S3 的 pyspark sql 查询返回空值

为啥这个 SQL 查询失败

为啥这个 Django 原始 SQL 查询不返回输出?

为啥在 SQL Azure 上运行查询要慢得多?

sqlserver查询很慢、而且超时为啥?