繁体   English   中英

Microsoft SQL和JDBC中的Prepared Statements中奇数位置的参数

[英]Parameters in odd locations in Prepared Statements in Microsoft SQL and JDBC

所以我在Microsoft SQL 2008中执行以下语句:

  SELECT
  'UTC' AS timezone,
  rel.unique_id AS relay,sns.unique_id AS sensor,
  dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime) / ? * ?, 0) AS time,
  SUM(CONVERT(FLOAT,dat.data)) AS total
  FROM sensor_data dat
   LEFT OUTER JOIN data_package pak ON dat.package_id = pak.id
   LEFT OUTER JOIN relays rel ON pak.relay_id = rel.id
   LEFT OUTER JOIN sensors sns ON dat.sensor_id = sns.id
   LEFT OUTER JOIN sensor_types typ ON sns.sensor_type = typ.id
   WHERE typ.name = 'Volume' AND dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime) / ? * ?, 0) > ? AND dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime) / ? * ?, 0) < ?
   GROUP BY rel.unique_id,sns.unique_id, dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime) / ? * ?, 0)
   ORDER BY time,relay,sensor

如果我使用jTDS / JDBC驱动程序设置参数,如下所示:

Parameter 1: 15
Parameter 2: 15
Parameter 3: 15
Parameter 4: 15
Parameter 5: 2011-10-31 20:00:00
Parameter 6: 15
Parameter 7: 15
Parameter 8: 2011-12-29 19:00:00
Parameter 9: 15
Parameter 10: 15

我收到错误:

Caused by: java.sql.SQLException: Column 'data_package.rtime' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

如果我在所有那些人手动投入15秒? 空格,查询工作完美,只有日期作为参数。

1)是否有参数化区间值(在这种情况下为15)或者我只需要将其转义并在它成为预准备语句之前搜索并替换它(如果这是真的,那么什么是逃避该参数的最佳方法斯卡拉/ JAVA)

2)我可以不再重复dateadd(datediff())部分三次吗? 我知道我不能在WHERE子句中引用“时间”,但有没有其他方法来指定某个地方以使其更清洁?

你的选择看起来像:

SELECT dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime) / ? * ?, 0) AS time,

和你的小组:

GROUP BY dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime) / ? * ?, 0)

随着? 由常数代替,这两个是相同的。

但是使用未命名的参数会引入一个问题。 select版本使用参数1和2,按版本分组使用参数9和10.而SQL Server现在不会将这些参数始终相等。 所以它抛出一个错误。

您可以通过计算子查询中的字段来避免这种情况:

left join
        (
        select  *
        ,       dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime) / ? * ?, 0) as X
        from    data_package
        ) as pak
on      dat.package_id = pak.id

您现在可以在查询的其他部分引用pak.X ,例如:

group by
        pak.X

Andomar是对的,问题是你的GROUP BY中使用了参数,但我相信他的解决方案可能过于复杂。 我想,更容易写:

SELECT
  'UTC' AS timezone,
  rel.unique_id AS relay,sns.unique_id AS sensor,
  dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime) / ? * ?, 0) AS time,
  SUM(CONVERT(FLOAT,dat.data)) AS total
  FROM sensor_data dat
   LEFT OUTER JOIN data_package pak ON dat.package_id = pak.id
   LEFT OUTER JOIN relays rel ON pak.relay_id = rel.id
   LEFT OUTER JOIN sensors sns ON dat.sensor_id = sns.id
   LEFT OUTER JOIN sensor_types typ ON sns.sensor_type = typ.id
   WHERE typ.name = 'Volume' AND dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime) / ? * ?, 0) > ? AND dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime) / ? * ?, 0) < ?
   GROUP BY rel.unique_id,sns.unique_id, time
   ORDER BY time,relay,sensor

(另一方面,因为在您的特定情况下,您在WHERE中使用完全相同的表达式,可能子查询更好。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM