#处理转义

# 转义概述

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
edit-icon
反馈
coperate-icon
coperate
合作
communication-icon
communicate
交流