#处理转义
# 转义概述
YashanDB JDBC允许在应用程序中书写SQL语句时,对日期时间型的变量进行特殊转义处理。
YashanDB JDBC允许在应用程序中书写SQL语句时,按如下格式书写日期时间型的变量,并在传递服务端执行之前将其转换为YashanDB服务端可接受的日期时间格式。
-- 以下d、t和ts不区分大小写。
-- 日期
{d 'yyyy-mm-dd'}
{d 'yyyymmdd'}
{d 'yyyy/mm/dd'}
-- 时间
{t 'hh:mm:ss'}
-- 时间戳
{ts 'yyyy-mm-dd hh:mm:ss.fff'}
{ts 'yyyy/mm/dd hh:mm:ss.fff'}
# 日期变量转义
日期变量转义使用{d 'date-value'}格式。YashanDB JDBC支持yyyy-mm-dd、yyyymmdd和yyyy/mm/dd三种输入格式,并在SQL发送到服务端前将日期值转换为YashanDB可接受的格式。例如:
SELECT {d '2020-02-01'} FROM dual;
SELECT {d '20200201'} FROM dual;
SELECT {d '2020/02/01'} FROM dual;
日期值也可以使用绑定参数传入:
SELECT {d ?} FROM dual;
转义表达式内或表达式后可以包含SQL块注释。例如:
SELECT {d /* DATE value */ '20200201'} FROM dual;
SELECT {d '2020-02-01'} /* DATE value */ FROM dual;
# 时间变量转义
时间变量转义使用{t 'time-value'}格式,时间值采用hh:mm:ss格式。YashanDB JDBC在转换时间值时补充日期部分1970-01-01。例如:
SELECT {t '01:59:01'} FROM dual;
时间值也可以使用绑定参数传入:
SELECT {t ?} FROM dual;
# 时间戳变量转义
时间戳变量转义使用{ts 'timestamp-value'}格式。YashanDB JDBC支持以连字符或斜杠分隔日期,并支持指定小数秒。例如:
SELECT {ts '2020-02-01 01:09:01.123'} FROM dual;
SELECT {ts '2020/02/01 01:09:01.123'} FROM dual;
时间戳值也可以使用绑定参数传入:
SELECT {ts ?} FROM dual;
# FN转义
FN转义使用JDBC统一语法调用标量函数,由YashanDB JDBC将转义表达式转换为YashanDB支持的函数调用。当前仅支持LENGTH函数。
| 语法 | 说明 |
|---|---|
| {fn LENGTH(value)} | 返回字符串的字符数。 |
例如:
SELECT {fn LENGTH('YashanDB')} FROM dual;
# CALL转义
CALL转义使用JDBC统一语法调用YashanDB中的存储过程或函数。调用存储过程时使用{call ...}格式;调用有返回值的函数时使用{? = call ...}格式。
| 语法 | 说明 |
|---|---|
| {call procedure_name(?, ...)} | 调用存储过程。 |
| {? = call function_name(?, ...)} | 调用函数并获取返回值。 |
其中,?表示参数占位符。输入参数通过setXxx()方法赋值,输出参数和函数返回值通过registerOutParameter()方法注册。
# 转义示例
以下示例使用YashanDB JDBC连接数据库并执行各类转义语句。执行示例前,请将连接地址、用户名和密码修改为实际环境的配置。
# 日期变量转义示例
以下示例使用日期变量转义查询日期值。驱动在执行SQL前处理{d '2020-02-01'}表达式。
package quickstart;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;
public class DateVariableEscapeExample {
public static void main(String[] args) throws Exception {
String url = "jdbc:yasdb://192.168.1.2:1688/yasdb";
Properties properties = new Properties();
properties.setProperty("user", "username");
properties.setProperty("password", "passwd");
Class.forName("com.yashandb.jdbc.Driver");
String sql = "SELECT {d '2020-02-01'} FROM dual";
try (Connection connection =
DriverManager.getConnection(url, properties);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql)) {
if (resultSet.next()) {
System.out.println(
"Date: " + resultSet.getString(1));
}
}
}
}
正常情况下,程序输出如下:
Date: 2020-02-01
# 时间变量转义示例
以下示例使用时间变量转义查询时间值。YashanDB JDBC返回的值包含驱动补充的日期部分1970-01-01。
package quickstart;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;
public class TimeVariableEscapeExample {
public static void main(String[] args) throws Exception {
String url = "jdbc:yasdb://192.168.1.2:1688/yasdb";
Properties properties = new Properties();
properties.setProperty("user", "username");
properties.setProperty("password", "passwd");
Class.forName("com.yashandb.jdbc.Driver");
String sql = "SELECT {t '01:59:01'} FROM dual";
try (Connection connection =
DriverManager.getConnection(url, properties);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql)) {
if (resultSet.next()) {
System.out.println(
"Time: " + resultSet.getString(1));
}
}
}
}
正常情况下,程序输出如下:
Time: 1970-01-01 01:59:01.0
# 时间戳变量转义示例
以下示例使用时间戳变量转义查询包含毫秒的时间戳值。
package quickstart;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;
public class TimestampVariableEscapeExample {
public static void main(String[] args) throws Exception {
String url = "jdbc:yasdb://192.168.1.2:1688/yasdb";
Properties properties = new Properties();
properties.setProperty("user", "username");
properties.setProperty("password", "passwd");
Class.forName("com.yashandb.jdbc.Driver");
String sql =
"SELECT {ts '2020-02-01 01:09:01.123'} FROM dual";
try (Connection connection =
DriverManager.getConnection(url, properties);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql)) {
if (resultSet.next()) {
System.out.println(
"Timestamp: " + resultSet.getString(1));
}
}
}
}
正常情况下,程序输出如下:
Timestamp: 2020-02-01 01:09:01.123
# FN转义示例
以下示例使用FN转义调用YashanDB JDBC支持的LENGTH函数,计算字符串YashanDB的字符数。
package quickstart;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;
public class FunctionEscapeExample {
public static void main(String[] args) throws Exception {
String url = "jdbc:yasdb://192.168.1.2:1688/yasdb";
Properties properties = new Properties();
properties.setProperty("user", "username");
properties.setProperty("password", "passwd");
Class.forName("com.yashandb.jdbc.Driver");
String sql = "SELECT {fn LENGTH('YashanDB')} FROM dual";
try (Connection connection =
DriverManager.getConnection(url, properties);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql)) {
if (resultSet.next()) {
System.out.println(
"Length: " + resultSet.getInt(1));
}
}
}
}
正常情况下,程序输出如下:
Length: 8
# CALL转义示例
以下示例先创建一个存储过程和一个函数,再分别使用两种CALL转义格式进行调用。执行示例的用户需要具有创建和删除存储过程、函数的权限。示例执行结束后会删除所创建的数据库对象。
package quickstart;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.Types;
import java.util.Properties;
public class CallEscapeExample {
public static void main(String[] args) throws Exception {
String url = "jdbc:yasdb://192.168.1.2:1688/yasdb";
Properties properties = new Properties();
properties.setProperty("user", "username");
properties.setProperty("password", "passwd");
Class.forName("com.yashandb.jdbc.Driver");
String procedure = "JDBC_ESCAPE_DOUBLE";
String function = "JDBC_ESCAPE_TRIPLE";
try (Connection connection =
DriverManager.getConnection(url, properties)) {
try (Statement statement = connection.createStatement()) {
statement.execute(
"CREATE OR REPLACE PROCEDURE " + procedure
+ " (P_INPUT IN INTEGER, "
+ "P_OUTPUT OUT INTEGER) AS "
+ "BEGIN P_OUTPUT := P_INPUT * 2; END;");
statement.execute(
"CREATE OR REPLACE FUNCTION " + function
+ " (P_INPUT IN INTEGER) RETURN INTEGER AS "
+ "BEGIN RETURN P_INPUT * 3; END;");
}
try {
try (CallableStatement statement =
connection.prepareCall(
"{call " + procedure + "(?, ?)}")) {
statement.setInt(1, 21);
statement.registerOutParameter(2, Types.INTEGER);
statement.execute();
System.out.println(
"Procedure result: "
+ statement.getInt(2));
}
try (CallableStatement statement =
connection.prepareCall(
"{? = call " + function + "(?)}")) {
statement.registerOutParameter(1, Types.INTEGER);
statement.setInt(2, 14);
statement.execute();
System.out.println(
"Function result: "
+ statement.getInt(1));
}
} finally {
try (Statement statement =
connection.createStatement()) {
statement.execute("DROP PROCEDURE " + procedure);
statement.execute("DROP FUNCTION " + function);
}
}
}
}
}
正常情况下,程序输出如下:
Procedure result: 42
Function result: 42

