Страницы

Поиск по вопросам

суббота, 14 декабря 2019 г.

Подстановка параметра PreparedStatement в JDBC Oracle

#java #oracle #jdbc


Столкулся с тем, что данная конструкция подстановки параметра (:1) работает с драйвером
Oracle:

    try {
        Class.forName("oracle.jdbc.driver.OracleDriver");
        try (Connection con =
                 DriverManager.getConnection("HOST", "USER", "PASS")) {
            try (PreparedStatement preparedStatement =
                     con.prepareStatement("select * from TABLE where name = :1")) {
                preparedStatement.setString(1, "NAME");
                try (ResultSet resultSet = preparedStatement.executeQuery()) {
                    while (resultSet.next()) {
                        System.out.println(resultSet.getObject(1));
                    }
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }


В JSR указано использование только знака ?.
Это особенность реализации драйвера?  

UPD:  

Версия БД:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
PL/SQL Release 12.1.0.2.0 - Production

Что замечено еще:  

    try (PreparedStatement preparedStatement =
             con.prepareStatement("select * from TABLE where name = :abc and id =
:dcf")) {
        preparedStatement.setString(1, "PARAM");
        preparedStatement.setInt(2, 173);
        try (ResultSet resultSet = preparedStatement.executeQuery()) {
            while (resultSet.next()) {
                System.out.println(resultSet.getObject(1));
            }
        }
    }


просьба обратить внимание на название подстановок, этот код работает.
А вот этот уже не работает:  

    try (PreparedStatement preparedStatement =
             con.prepareStatement("select * from TABLE  where name = :abc and id
= :dcf")) {
        preparedStatement.setString(2, "NAME");
        preparedStatement.setInt(1, 173);
        try (ResultSet resultSet = preparedStatement.executeQuery()) {
            while (resultSet.next()) {
                System.out.println(resultSet.getObject(1));
            }
        }
    }

    java.sql.SQLSyntaxErrorException: ORA-01722: неверное число


То есть на название вообще нет реакции, только на ":" порядок.
    


Ответы

Ответ 1



В JSR указано использование только знака ?. Символ ? это ещё не подстановочный параметр, это только местозаполнитель (placeholder), все символы местозаполнители функция prepareStatement() заменит на подстановочные переменные (или переменные связывания (bind variables)) используя синтаксис для подстановочных переменных целевой СУБД. Если в SQL выражении указать подстановочные параметры сразу в том виде, в котором на целевой СУБД выполнится подготовка и компиляция (parse), то функция prepareStatement() не призведёт никакой замены и не заметит, что её "лишили работы". Это особенность реализации драйвера? Да, или лучше сказать - это особенность целевой СУБД, которую этот драйвер поддерживает. Касательно подстановочных переменных, различные СУБД имеют различный синтаксис этих переменных: Oracle: :var (colon) MySQL, DB2 and Firebird: ? (question marks) Sybase, MS SQL Server: @var (at sign) PostgreSQL: $var (dollar sign) Для подтверждения вышесказанного, рассмотрим следующий пример. Выполним один и тот же запрос несколько раз с различным использованием местозаполнителей и подстановочных параметров: create or replace and compile java source named TestPrepared as import java.sql.*; public class TestPrepared { public static void selectValue (int id, String item) { String[] stmts = { /*#1*/"/* ? */ select id, item from items where id = ? and item = ?", /*#2*/"/* ? */ select id, item from items where id = :1 and item = :2", /*#3*/"/* ? */ select id, item from items where id = :2 and item = :3", /*#4*/"/* ? */ select id, item from items where id = :id and item = :item"}; try { Connection con = DriverManager.getConnection("jdbc:oracle:thin:@dbsrv:1521/pdb1","sh","sh"); for (int i=0; i

Комментариев нет:

Отправить комментарий