JDBC转义
JDBC转义¶
JDBC规范(如ODBC规范)承认以下事实:某些RDBMS特性可能需要供应商提供的特定SQL。 为了帮助开发人员编写可跨多个数据库产品移植的JDBC应用程序,使用特殊的转义语法指定开发人员要运行的通用命令。 JDBC驱动程序将这些转义序列转换为其特定数据库的语法。 有关更多信息,请参阅Java DB技术文档。
可以使用Statement.setEscapeProcessing(false)禁用对这些转义的sql语句的解析。
Connection.nativeSQL(String sql)提供了另一种处理转义的方法。 它将给定的SQL转换为适合SeaboxSQL™后端的SQL。
示例 使用JDBC转义
要使用JDBC转义,只需编写SQL通过JDBC转义语法替换日期/时间文字值,outer join和函数。 例如 :
ResultSet rs = st.executeQuery("SELECT {fn week({d '2005-01-24'})}");
可移植版本为
ResultSet rs = st.executeQuery("SELECT extract(week from DATE '2005-01-24')");
Like转义字符¶
可指定哪个转义字符用于字符串比较(如Like操作)以保护通配符('%'和'_'),形式为{escape 'escape-character'}。驱动程序仅支持在表达式的末尾设置转义字符。
例如,您可以在比较字符串时使用'|'作为转义字符来保护'_':
rs = stmt.executeQuery("select str2 from comparisontest where str1 like '|_abcd' {escape '|'} ");
Out join转义字符¶
可以使用以下语法指定外部联接:
{oj table(LEFT | RIGHT | FULL)OUTER JOIN(table | external-join)ON search-condition}
例如:
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'时间戳内,秒的小数部分(.f)可以忽略
标量函数转义¶
JDBC规范使用转义调用语法{fn function_name(arguments)}定义函数。下表显示了SeaboxSQL™驱动程序支持的功能,驱动程序支持转义函数和转义值的嵌套和混合。JDBC规范的附录C描述了这些功能。
下表中的某些功能已转换,但未报告为受支持,因为它们正在复制或更改参数的顺序。尽管这对于原有值或列无有害影响,但在使用已经准备好的声明时会引起问题。 例如{fn right(?,?)}将转换为substring(?from(length(?)+1-?)))。如您所见,翻译后的SQL需要更多的参数,但驱动程序不会自动处理它。
表 支持的转义数字函数
| 函数 | 报告为支持 | 转义 | 备注 |
|---|---|---|---|
| abs(arg1) | yes | abs(arg1) | |
| acos(arg1) | yes | acos(arg1) | |
| asin(arg1) | yes | asin(arg1) | |
| atan(arg1) | yes | atan(arg1) | |
| atan2(arg1,arg2) | yes | atan2(arg1,arg2) | |
| ceiling(arg1) | yes | ceil(arg1) | |
| cos(arg1) | yes | cos(arg1) | |
| cot(arg1) | yes | cot(arg1) | |
| degrees(arg1) | yes | degrees(arg1) | |
| exp(arg1) | yes | exp(arg1) | |
| floor(arg1) | yes | floor(arg1) | |
| log(arg1) | yes | ln(arg1) | |
| log10(arg1) | yes | log(arg1) | |
| mod(arg1,arg2) | yes | mod(arg1,arg2) | |
| pi(arg1) | yes | pi(arg1) | |
| power(arg1,arg2) | yes | pow(arg1,arg2) | |
| radians(arg1) | yes | radians(arg1) | |
| rand() | yes | random() | |
| rand(arg1) | yes | setseed(arg1)*0+random() | 随机种子根据给定的参数进行初始化,并返回一个新的随机数值。 |
| round(arg1,arg2) | yes | round(arg1,arg2) | |
| sign(arg1) | yes | sign(arg1) | |
| sin(arg1) | yes | sin(arg1) | |
| sqrt(arg1) | yes | sqrt(arg1) | |
| tan(arg1) | yes | tan(arg1) | |
| truncate(arg1,arg2) | yes | trunc(arg1,arg2) |
表 支持的转义字符串函数
| 函数 | 报告为支持 | 转义 | 备注 |
|---|---|---|---|
| ascii(arg1) | yes | ascii(arg1) | |
| char(arg1) | yes | chr(arg1) | |
| concat(arg1,arg2…) | yes | (arg1||arg2…) | JDBC规范定义只需要两个参数,但是支持更多参数也非常容易。 |
| insert(arg1,arg2,arg3,arg4) | no | overlay(arg1 placing arg4 from arg2 for arg3) | 该函数没有报告为支持,是因为他改变了参数的顺序可能会带来问题(参考示例中的prepared statements)。 |
| lcase(arg1) | yes | lower(arg1) | |
| left(arg1,arg2) | yes | substring(arg1 for arg2) | |
| length(arg1) | yes | length(trim(trailing from arg1)) | |
| locate(arg1,arg2) | no | position(arg1 in arg2) | |
| locate(arg1,arg2,arg3) | no | (arg2*sign(position(arg1 in substring(arg2 from arg3)+position(arg1 in substring(arg2 from arg3)) | 没有报告为支持,因为三个版本的参数重复且顺序不同。 |
| ltrim(arg1) | yes | trim(leading from arg1) | |
| repeat(arg1,arg2) | yes | repeat(arg1,arg2) | |
| replace(arg1,arg2,arg3) | yes | replace(arg1,arg2,arg3) | 只有7.3及以上报告为支持 |
| right(arg1,arg2) | no | substring(arg1 from (length(arg1)+1-arg2)) | 由于arg2重复没有报告为支持。 |
| rtrim(arg1) | yes | trim(trailing from arg1) | |
| space(arg1) | yes | repeat(' ',arg1) | |
| substring(arg1,arg2) | yes | substr(arg1,arg2) | |
| substring(arg1,arg2,arg3) | yes | substr(arg1,arg2,arg3) | |
| ucase(arg1) | yes | upper(arg1) | |
| soundex(arg1) | no | soundex(arg1) | 没有报告为支持是因为需要模糊匹配支持模块。 |
| difference(arg1,arg2) | no | difference(arg1,arg2) | 没有报告为支持是因为需要模糊匹配支持模块。 |
表 支持的转义日期/时间函数
| 函数 | 报告为支持 | 转义 | 备注 |
|---|---|---|---|
| curdate() | yes | current_date | |
| curtime() | yes | current_time | |
| dayname(arg1) | yes | to_char(arg1,'Day') | |
| dayofmonth(arg1) | yes | extract(day from arg1) | |
| dayofweek(arg1) | yes | extract(dow from arg1)+1 | 我们必须加1让他在1-7的预期范围内。 |
| dayofyear(arg1) | yes | extract(doy from arg1) | |
| hour(arg1) | yes | extract(hour from arg1) | |
| minute(arg1) | yes | extract(minute from arg1) | |
| month(arg1) | yes | extract(month from arg1) | |
| monthname(arg1) | yes | to_char(arg1,'Month') | |
| now() | yes | now() | |
| quarter(arg1) | yes | extract(quarter from arg1) | |
| second(arg1) | yes | extract(second from arg1) | |
| week(arg1) | yes | extract(week from arg1) | |
| year(arg1) | yes | extract(year from arg1) | |
| timestampadd(argIntervalType,argCount,argTimeStamp) | yes | ('(interval according to argIntervalType and argCount)'+argTimeStamp) | 由于后端不支持,SQL_TSI_FRAC_SECOND的argIntervalType数值不可用 |
| timestampdiff(argIntervalType,argTimeStamp1,argTimeStamp2) | not | 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数值支持。 |
表 支持的转义杂项函数
| 函数 | 报告为支持 | 转义 | 备注 |
|---|---|---|---|
| database() | yes | current_database() | |
| ifnull(arg1,arg2) | yes | coalesce(arg1,arg2) | |
| user() | yes | user |