JDBC 转义
JDBC 规范(如 ODBC 规范)承认对于某些 RDBMS 的功能可能需要用到某些供应商特定的 SQL。为了帮助开发人员跨多个数据库产品编写可移植的 JDBC 应用程序,特殊的转义语法用于指定开发人员希望运行的通用命令。JDBC 驱动程序翻译这些转义序列,转换为特定数据库的相关语法。有关更多信息,请参阅 Java DB 技术文档。
可以使用Statement.setEscapeProcessing(false)
禁用这些转义的 sql 语句解析。
Connection.nativeSQL(String sql)
提供另一种处理转义的方法。它将给定的 SQL 转换为适用于PostgreSQL后端的 SQL。
例 8.1.使用 JDBC 转义
要使用 JDBC 转义,您只需编写 SQL 将日期/时间文字值、外部连接和函数替换为 JDBC 转义语法。例如:
ResultSet rs = st.executeQuery("SELECT {fn week({d '2005-01-24'})}");
它是下面SQL的可移植性的版本
ResultSet rs = st.executeQuery("SELECT extract(week from DATE '2005-01-24')");
您可以指定在字符串比较(使用LIKE
)中使用的转义字符,通过添加以下转义:{escape 'escape-character'}
,以保护通配符(’%’ 和 ‘_’)。驱动程序仅在比较表达式的末尾支持此功能。
例如,您可以在比较字符串值时使用 ‘|’ 作为转义字符来保护 ‘_’ :
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 规范定义了用于指定驱动程序支持的日期、时间和时间戳值的转义。
- date :
{d 'yyyy-mm-dd'}
转换为DATE 'yyyy-mm-dd'
- time :
{t 'hh:mm:ss'}
转换为TIME 'hh:mm:ss'
- timestamp :
{ts 'yyyy-mm-dd hh:mm:ss.f...'}
转换为TIMESTAMP 'yyyy-mm-dd hh:mm:ss.f'
。时间戳中秒数后面的小数部分(.f…)可以省略。
JDBC 规范使用转义调用语法定义函数:{fn function_name(arguments)}
。下表显示 PostgreSQL 驱动程序支持哪些函数。驱动程序支持嵌套和混合转义函数和转义值。JDBC 规范的附录 C 章节描述了这些函数。
下表中的某些函数都已被翻译,但由于它们重复或更改他们的参数顺序而报告为不受支持。虽然这对文字值或列无害,但在使用预备语句时会导致问题。例如{fn right(?,?)}
将被转换为substring(? from (length(?)+1-?))
。请注意,有些转换后的 SQL 需要比转换前更多的参数,但驱动程序不会自动处理此问题。
表 8.1.支持的转义数值函数
函数 | 是否支持 | 译为 | 备注 |
---|---|---|---|
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) |
表 8.2.支持的转义字符串函数
函数 | 是否支持 | 译为 | 备注 |
---|---|---|---|
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 及更高版本的 PostgreSQL 支持。 |
right(arg1, arg2) | 不支持 | substring(arg1 from (length(arg1)+1-arg2)) | 不支持,因为参数 arg1 重复了。 |
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 contrib 模块。 |
difference(arg1, arg2) | 不支持 | difference(arg1, arg2) | 不支持,因为它需要 fuzzystrmatch contrib 模块。 |
表 8.3.支持的转义日期/时间函数
函数 | 是否支持 | 译为 | 备注 |
---|---|---|---|
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 ) | 仅支持 SQL_TSI_FRAC_SECOND、SQL_TSI_FRAC_MINUTE、SQL_TSI_FRAC_HOUR 或 SQL_TSI_FRAC_DAY 这些 argIntervalType 值 |
表 8.4.其他支持的转义函数
函数 | 是否支持 | 译为 | 备注 |
---|---|---|---|
database() | 支持 | current_database() | 仅为 7.3 及更高版本的 PostgreSQL 支持。 |
ifnull(arg1, arg2) | 支持 | coalesce(arg1, arg2) | |
user() | 支持 | user |