Oracle Java - 将可选的日期参数添加到 Prepared 语句
Oracle Java - Add optional date parameter to Prepared statement
我想将可选的 "todate" 参数添加到准备好的语句
一种方法是为可选参数添加占位符并在执行前替换它
where id=? OPTIONAL_SECTION
例如 OPTIONAL_SECTION 将设置为 TO_DATE <=sysdate -1
更好更正确的方法是绑定可选参数处理空值
where id=? and TO_DATE <= nvl(?, TO_DATE)
有没有更好的方法来处理可选的日期参数?
特别是因为条件可以不相等 ( TO_DATE < ?)
- 这是一个最小的例子,Id 不是主键(实际上是外键),SQL return 多条记录
A better and correct way is to bind optional parameter with handling null
这不一定更好或更正确。这是一种不同的方式,但如果它“更好且(更)正确”,那就太糟糕了table。
SQL 查询优化器通常 运行 在任何 ?
参数值已知之前,因此 TO_DATE <= nvl(?, TO_DATE)
无法优化,需要完整的 table扫描,排除 where
子句中的任何其他条件。
但是对于 TO_DATE <= ?
,优化器可以使用 TO_DATE
上的索引来对索引进行范围扫描,所以我认为第一个选项可能更好, 取决于可用索引。
condition can be without equal ( TO_DATE < ?)
第二个版本的正确写法是:
where id = ?
and (? is null or TO_DATE < ?)
您当然必须为 PreparedStatement
.
指定两次值
带有可选参数的查询的第一个决定如下:
1) accepatable 对两个/所有选项使用 一个语句
2) 最好为每个选项使用单独的statament
在您的情况下,您有两个参数选项:
id
id
和 date_parameter
从命名来看,我认为 ID
是 table 的主键,所以它 return 只有一行,并且会是 执行计划中的驱动程序-简单索引访问.
date_parameter
只能导致查询return可选无行
在这种情况下,您可以安全地使用决定 1) - 两个选项的一次查询就可以了
但在其他解释中,ID
是具有大量行的 外键 而 date_parameter
仅用于 return最近的少量行。
在这种情况下,决策 1) aka OR 查询将严重失败。执行计划针对 return 处理大量数据的情况进行了优化,因此您将等待很长时间才能获得少量行。
所以在这种情况下,只有决策 2) 提供了一个高效的解决方案。 简答是根据传入的参数动态生成两个查询
where id=?
where id=? and data_parameter <= ?
这种方法的技术问题是,查询具有不同数量的绑定变量,这使得 setXXX 变得复杂。
为了避免这个问题,您可以使用 1=1 or
技巧,即 a) 使绑定变量的数量在所有查询中都相等* 并且 b) 消除不必要的一次。
仅 ID
的查询生成为
where id=? and 1=1 or data_parameter <= ?
使用 ID
和 DATE_PARAM
的查询保持不变
where id=? and data_parameter <= ?
可以找到更多推广这种方法的例子和功劳here and
我想将可选的 "todate" 参数添加到准备好的语句
一种方法是为可选参数添加占位符并在执行前替换它
where id=? OPTIONAL_SECTION
例如 OPTIONAL_SECTION 将设置为 TO_DATE <=sysdate -1
更好更正确的方法是绑定可选参数处理空值
where id=? and TO_DATE <= nvl(?, TO_DATE)
有没有更好的方法来处理可选的日期参数? 特别是因为条件可以不相等 ( TO_DATE < ?)
- 这是一个最小的例子,Id 不是主键(实际上是外键),SQL return 多条记录
A better and correct way is to bind optional parameter with handling null
这不一定更好或更正确。这是一种不同的方式,但如果它“更好且(更)正确”,那就太糟糕了table。
SQL 查询优化器通常 运行 在任何 ?
参数值已知之前,因此 TO_DATE <= nvl(?, TO_DATE)
无法优化,需要完整的 table扫描,排除 where
子句中的任何其他条件。
但是对于 TO_DATE <= ?
,优化器可以使用 TO_DATE
上的索引来对索引进行范围扫描,所以我认为第一个选项可能更好, 取决于可用索引。
condition can be without equal ( TO_DATE < ?)
第二个版本的正确写法是:
where id = ?
and (? is null or TO_DATE < ?)
您当然必须为 PreparedStatement
.
带有可选参数的查询的第一个决定如下:
1) accepatable 对两个/所有选项使用 一个语句
2) 最好为每个选项使用单独的statament
在您的情况下,您有两个参数选项:
id
id
和 date_parameter
从命名来看,我认为 ID
是 table 的主键,所以它 return 只有一行,并且会是 执行计划中的驱动程序-简单索引访问.
date_parameter
只能导致查询return可选无行
在这种情况下,您可以安全地使用决定 1) - 两个选项的一次查询就可以了
但在其他解释中,ID
是具有大量行的 外键 而 date_parameter
仅用于 return最近的少量行。
在这种情况下,决策 1) aka OR 查询将严重失败。执行计划针对 return 处理大量数据的情况进行了优化,因此您将等待很长时间才能获得少量行。
所以在这种情况下,只有决策 2) 提供了一个高效的解决方案。 简答是根据传入的参数动态生成两个查询
where id=?
where id=? and data_parameter <= ?
这种方法的技术问题是,查询具有不同数量的绑定变量,这使得 setXXX 变得复杂。
为了避免这个问题,您可以使用 1=1 or
技巧,即 a) 使绑定变量的数量在所有查询中都相等* 并且 b) 消除不必要的一次。
仅 ID
的查询生成为
where id=? and 1=1 or data_parameter <= ?
使用 ID
和 DATE_PARAM
的查询保持不变
where id=? and data_parameter <= ?
可以找到更多推广这种方法的例子和功劳here and