JDBC 转义

JDBC 规范(类似于 ODBC 规范)承认某些供应商特定的 SQL 可能需要用于某些 RDBMS 功能。为了帮助开发人员跨多个数据库产品编写可移植的 JDBC 应用程序,使用了一种特殊的转义语法来指定开发人员想要运行的通用命令。JDBC 驱动程序将这些转义序列转换为其特定数据库的本机语法。有关更多信息,请参阅 Java DB 技术文档.

可以使用 Statement.setEscapeProcessing(false) 禁用对这些转义的 sql 语句的解析。

Connection.nativeSQL(String sql) 提供了另一种处理转义的方法。它将给定的 SQL 转换为适合 PostgreSQL® 后端的 SQL。

要使用 JDBC 转义,只需编写您的 SQL,将日期/时间文字值、外连接和函数替换为 JDBC 转义语法。例如

ResultSet rs = st.executeQuery("SELECT {fn week({d '2005-01-24'})}");

是以下内容的可移植版本

ResultSet rs = st.executeQuery("SELECT extract(week from DATE '2005-01-24')");

您可以通过添加以下转义来指定在字符串比较(使用 LIKE)中使用哪个转义字符来保护通配符字符(’%’ 和 ‘_’):{escape '转义字符'}。驱动程序仅在比较表达式的末尾支持此功能。

例如,您可以使用“|”作为转义字符来保护“_”,从而比较字符串值。

rs = stmt.executeQuery("select str2 from comparisontest where str1 like '|_abcd' {escape '|'} ");

您可以使用以下语法指定外部联接:{oj table (LEFT|RIGHT|FULL) OUTER JOIN (table | outer-join) ON search-condition}

例如

ResultSet rs = stmt.executeQuery("select * from {oj a left outer join b on (a.i=b.i)} ");

JDBC 规范定义了用于指定日期、时间和时间戳值的转义符,这些转义符受驱动程序支持。

  • 日期{d 'yyyy-mm-dd'},它被转换为 DATE 'yyyy-mm-dd'
  • 时间{t 'hh:mm:ss'},它被转换为 TIME 'hh:mm:ss'
  • 时间戳{ts 'yyyy-mm-dd hh:mm:ss.f...'},它被转换为 TIMESTAMP 'yyyy-mm-dd hh:mm:ss.f'。TIMESTAMP 的小数秒部分 (.f…) 可以省略。

JDBC 规范定义了使用转义调用语法来表示函数:{fn function_name(arguments)}。以下表格显示了 PostgreSQL® 驱动程序支持的函数。驱动程序支持转义函数和转义值的嵌套和混合。JDBC 规范的附录 C 描述了这些函数。

以下表格中的一些函数被翻译,但报告为不支持,因为它们重复或改变了参数的顺序。虽然这对文字值或列来说是无害的,但它会在使用预处理语句时造成问题。例如 " {fn right(?,?)} " 将被翻译为 " substring(? from (length(?)+1-?)) "。如您所见,翻译后的 SQL 需要比翻译前更多的参数,但驱动程序不会自动处理这种情况。

函数 报告为支持 翻译 评论
abs(arg1) abs(arg1)
acos(arg1) acos(arg1)
asin(arg1) asin(arg1)
atan(arg1) atan(arg1)
atan2(arg1, arg2) atan2(arg1, arg2)
ceiling(arg1) ceil(arg1)
cos(arg1) cos(arg1)
cot(arg1) cot(arg1)
degrees(arg1) degrees(arg1)
exp(arg1) exp(arg1)
floor(arg1) floor(arg1)
log(arg1) ln(arg1)
log10(arg1) log(arg1)
mod(arg1, arg2) mod(arg1, arg2)
pi(arg1) pi(arg1)
power(arg1, arg2) pow(arg1, arg2)
radians(arg1) radians(arg1)
rand() random()
rand(arg1) setseed(arg1)*0+random() 使用给定参数初始化种子并返回一个新的随机值。
round(arg1, arg2) round(arg1, arg2)
sign(arg1) sign(arg1)
sin(arg1) sin(arg1)
sqrt(arg1) sqrt(arg1)
tan(arg1) tan(arg1)
truncate(arg1, arg2) trunc(arg1, arg2)
函数 报告为支持 翻译 评论
ascii(arg1) ascii(arg1)
char(arg1) chr(arg1)
concat(arg1, arg2…) (arg1
insert(arg1, arg2, arg3, arg4) overlay(arg1 placing arg4 from arg2 for arg3) 此功能不支持,因为它会改变参数的顺序,这可能会导致问题(例如,对于预处理语句)。
lcase(arg1) lower(arg1)
left(arg1, arg2) substring(arg1 for arg2)
length(arg1) length(trim(trailing from arg1))
locate(arg1, arg2) position(arg1 in arg2)
locate(arg1, arg2, arg3) (arg2*sign(position(arg1 in substring(arg2 from arg3)+position(arg1 in substring(arg2 from arg3)) 不支持,因为三个参数版本会复制并改变参数的顺序。
ltrim(arg1) trim(leading from arg1)
repeat(arg1, arg2) repeat(arg1, arg2)
replace(arg1, arg2, arg3) replace(arg1, arg2, arg3) 仅在 7.3 及更高版本的服务器上报告为支持。
right(arg1, arg2) substring(arg1 from (length(arg1)+1-arg2)) 由于 arg2 重复,因此不支持。
rtrim(arg1) trim(trailing from arg1)
space(arg1) repeat(’ ‘, arg1)
substring(arg1, arg2) substr(arg1, arg2)
substring(arg1, arg2, arg3) substr(arg1, arg2, arg3)
ucase(arg1) upper(arg1)
soundex(arg1) soundex(arg1) 由于需要 fuzzystrmatch 扩展模块,因此不支持。
difference(arg1, arg2) difference(arg1, arg2) 由于需要 fuzzystrmatch 扩展模块,因此不支持。
函数 报告为支持 翻译 评论
curdate() current_date
curtime() current_time
dayname(arg1) to_char(arg1, ‘Day’)
dayofmonth(arg1) extract(day from arg1)
dayofweek(arg1) extract(dow from arg1)+1 我们必须加 1 才能在预期的 1-7 范围内。
dayofyear(arg1) extract(doy from arg1)
hour(arg1) extract(hour from arg1)
minute(arg1) extract(minute from arg1)
month(arg1) extract(month from arg1)
monthname(arg1) to_char(arg1, ‘Month’)
now() now()
quarter(arg1) extract(quarter from arg1)
second(arg1) extract(second from arg1)
week(arg1) extract(week from arg1)
year(arg1) extract(year from arg1)
timestampadd(argIntervalType, argCount, argTimeStamp) ((interval according to argIntervalType and argCount)+argTimeStamp) 由于后端不支持,因此未实现 argIntervalType 值 SQL_TSI_FRAC_SECOND
timestampdiff(argIntervalType, argTimeStamp1, argTimeStamp2) extract((interval according to argIntervalType) from argTimeStamp2-argTimeStamp1 ) 仅支持 argIntervalType 值 SQL_TSI_FRAC_SECOND、SQL_TSI_FRAC_MINUTE、SQL_TSI_FRAC_HOUR 或 SQL_TSI_FRAC_DAY
函数 报告为支持 翻译 评论
database() 当前数据库() 仅在 7.3 及更高版本的服务器上报告为支持。
ifnull(arg1, arg2) coalesce(arg1, arg2)
用户() 用户