PreparedStatement, используя один параметр для нескольких «?»

У меня есть запрос вставки, если не существует, как показано ниже.

BEGIN
    IF NOT EXISTS (SELECT * FROM tbl_sampleTable WHERE name = ? or subject = ?)
    BEGIN
        INSERT INTO tbl_sampleTable VALUES (?,?)
    END
END

Я выполняю вышеуказанный запрос с помощью JDBC PreparedStatement, как показано ниже.

    pst.setString(1, name);
    pst.setString(2, subject);
    pst.setString(3, subject);
    pst.setString(4, name);
    pst.executeUpdate();

Я получаю это имя и тему в качестве параметров метода, есть ли в любом случае я могу предоставить значения для нескольких «?» с тем же параметром, что и они, вместо того, чтобы упоминать их по два раза.

Изменить: я не использую весну или какую-либо другую структуру, если это имеет значение.

Всего 4 ответа


В этом случае вы можете использовать переменные SQL. Это не общее решение. А также многие специфические варианты SQL-разработчиков знают такие конструкции insert-when-not-exist, которым не нужен такой архаичный код.

BEGIN
    DECLARE @MyName varchar(100);
    DECLARE @MySubject varchar(100);
    SET @MyName = ?;
    SET @MySubject = ?;
    IF NOT EXISTS (SELECT * FROM tbl_sampleTable WHERE name = @MyName OR subject = @MySubject)
    BEGIN
        INSERT INTO tbl_sampleTable(subject, name) VALUES (@MySubject, @MyName)
    END
END

JDBC не поддерживает именованные параметры, но Spring JDBC предоставляет эту функцию с помощью NamedParameterJdbcTemplate


Вам нужно добавить некоторую оболочку, не используя Spring (NamedParameterJdbcTemplate), вы можете попробовать другое как инфраструктуру HTTP-RPC

Класс org.httprpc.sql.Parameters, предоставляемый инфраструктурой HTTP-RPC, приносит JDBC именованную поддержку параметров. Метод parse () этого класса используется для создания экземпляра Parameters из JPA-подобного SQL-запроса; например:

SELECT * FROM user WHERE first_name LIKE :pattern or last_name LIKE :pattern

В качестве аргумента требуется строка или ридер, содержащий текст запроса:

 Parameters parameters = Parameters.parse(sqlReader);

Метод getSQL () класса Parameters возвращает обработанный запрос в стандартном синтаксисе JDBC. Это значение может использоваться при вызове Connection # prepareStatement ():

PreparedStatement statement = connection.prepareStatement(parameters.getSQL());

Значения параметров задаются с помощью метода put ():

parameters.put("pattern", pattern);

Значения применяются к заявлению с помощью метода apply ():

parameters.apply (заявление);


Полезным трюком в этой ситуации является объявление переменных.

Вы привязываете значения к переменным только один раз, и вы можете использовать их несколько раз в своем блоке PL / SQL.

DECLARE
  l_name tbl_sampleTable.name%TYPE := ?;
  l_subject tbl_sampleTable.subject%TYPE := ?;
BEGIN
    IF NOT EXISTS (SELECT * FROM tbl_sampleTable WHERE name = l_name  or subject = l_subject )
    BEGIN
        INSERT INTO tbl_sampleTable (name,subject)
        VALUES (l_name ,l_subject )
    END
END

Есть идеи?

10000