【问题标题】:Issue with a SQL query on a date time field in CosmosDBCosmosDB 中日期时间字段的 SQL 查询问题
【发布时间】:2019-08-03 18:52:46
【问题描述】:

我必须进行查询,选择属于两个日期(开始和结束)之间的间隔的集合元素。虽然尊重 startdate 约束,但 enddate 似乎总是晚两个小时。提取的项目大于或等于 startdate 并且小于或等于 enddate 减去两个小时。

一个项目的例子如下:

{
  "messageUID": "xxxxxxxxx22019-05-31T16:59:16+02:00",
  "deviceId": "xxxxxxxxxxxxx",
  "dateTimeDevice": "2019-05-31T14:59:16",
  "messageId": 39,
  "release": 104,
  "VIn": 23430,
  "VOut": 20592,
  "AIn": 53,
  "AOut": 40,
  "CosPhi": 43,
  "W": 54,
  "Var": 112,
  "VA": 125,
  "WhCnt": 365009,
  "VarhCnt": 756729,
  "TimeSlot": 0,
  "MeterTS": "2019-05-31 16:59:17",
  "Sampling": 60,
  "Wh": 3422,
  "Varh": 7098,
  "WSaved": 0,
  "EventProcessedUtcTime": "2019-05-31T14:59:18.3140933Z",
  "PartitionId": 1,
  "EventEnqueuedUtcTime": "2019-05-31T14:59:18.29Z",
  "IoTHub": {
    "MessageId": null,
    "CorrelationId": null,
    "ConnectionDeviceId": "Device",
    "ConnectionDeviceGenerationId": "636909297614425839",
    "EnqueuedTime": "2019-05-31T14:59:18.296Z",
    "StreamId": null
  },
  "id": "EBBBrain-1060894172",
  "_rid": "dEkOAONukRECAAAAAAAAAA==",
  "_self": 
  "dbs/dEkOAA==/colls/dEkOAONukRE=/docs/dEkOAONukRECAAAAAAAAAA==/",
  "_etag": "\"2400a2a2-0000-0c00-0000-5cf1415c0000\"",
  "_attachments": "attachments/",
  "_ts": 1559314780
}

查询的where子句如下:

sqlQuerySpec.QueryText += "where (c.EventProcessedUtcTime >= @startdate) and ";
sqlQuerySpec.QueryText += "(c.EventProcessedUtcTime <= @enddate) and ";
sqlQuerySpec.QueryText += "(c.deviceId = @deviceId)";
sqlQuerySpec.Parameters = new SqlParameterCollection()
  {
    new SqlParameter("@startdate",startdate.ToString("yyyy-MM-ddTHH:mm:ss.FFFFFFFZ")),
    new SqlParameter("@enddate",enddate.ToString("yyyy-MM-ddTHH:mm:ss.FFFFFFFZ")), 
    new SqlParameter("@deviceId", deviceId)
  };

在调试中似乎参数传递正确。

解决了如下更改代码的问题:

sqlQuerySpec.QueryText += "where (RIGHT(c.messageUID, 25) >= @startdate) and ";
sqlQuerySpec.QueryText += "(RIGHT(c.messageUID, 25) <= @enddate) and ";
sqlQuerySpec.QueryText += "(c.deviceId = @deviceId)";
sqlQuerySpec.Parameters = new SqlParameterCollection()
  {
    new SqlParameter("@startdate",DateTime.SpecifyKind(startdate,DateTimeKind.Unspecified)),
    new SqlParameter("@enddate",DateTime.SpecifyKind(enddate,DateTimeKind.Unspecified)), 
    new SqlParameter("@deviceId", deviceId)
  };

在此先感谢大家。

【问题讨论】:

  • 这完全是夏令时问题。你startdateenddate 是否在同一个本地时区?
  • 是的,他们是。例如 startdate.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.FFFFFFFZ") => "2019-08-03T00:28:43Z" enddate.ToUniversalTime().ToString("yyyy -MM-ddTHH:mm:ss.FFFFFFFZ") => "2019-08-04T00:28:43Z"
  • @Frank:对不起,我尝试应用时区但没有成功。我只在查询的顶端遇到问题。我也尝试在 startdate 和 enddate 上施加静态值,但问题仍然存在。返回项目的范围从 startdate 到 enddate-2 小时。如果是时区问题,它将同时应用于 startdate 和 enddate。
  • 您是否尝试过使用本机值/日期时间对象而不是字符串值?
  • @Frank : 是的,我试过了,得到了同样的结果。

标签: c# azure-cosmosdb azure-cosmosdb-sqlapi


【解决方案1】:

我用以下代码解决了我的问题:

sqlQuerySpec.QueryText += "where (RIGHT(c.messageUID, 25) >= @startdate) and ";
sqlQuerySpec.QueryText += "(RIGHT(c.messageUID, 25) <= @enddate) and ";
sqlQuerySpec.QueryText += "(c.deviceId = @deviceId)";
sqlQuerySpec.Parameters = new SqlParameterCollection()
  {
    new SqlParameter("@startdate",DateTime.SpecifyKind(startdate,DateTimeKind.Unspecified)),
    new SqlParameter("@enddate",DateTime.SpecifyKind(enddate,DateTimeKind.Unspecified)), 
    new SqlParameter("@deviceId", deviceId)
 ;

谢谢大家。

【讨论】:

    猜你喜欢
    • 2018-08-06
    • 2016-07-09
    • 1970-01-01
    • 1970-01-01
    • 2018-05-31
    • 2015-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多