Использование кодов ошибок вместо явных проверок в SQL? - PullRequest
0 голосов
/ 15 октября 2011

У меня есть запрос, который пытается вставить строку в таблицу. Возможно, что запрос не удастся из-за сбоя первичного ключа, потому что уже есть строка с этим идентификатором.

Я мог бы проверить это перед попыткой вставки, но я также могу обнаружить это, проверив состояние SQL SQLException. Это правильный способ сделать этот тип вещи? Или я должен сделать явную проверку перед рукой?

Причина, по которой я спрашиваю, состоит в том, что, если мне придется выполнить явную проверку перед выполнением вставки, мне придется заблокировать таблицу, из которой я проверяю, во избежание несоответствия. Использование проверки кода ошибки означает, что мне не нужно будет блокировать таблицу.

Проверьте заранее

try {
    con.setAutoCommit(false);
    con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
    Statement statement = con.createStatement();
    ResultSet rs = statement.executeQuery("SELECT * FROM SomeTable WHERE Id = 123");
    if(rs.next()) {
        con.setAutoCommit(true);
        System.err.println("Entry with Id 123 already exists!");
        return;
    }
    statement = con.createStatement();
    statement.executeQuery("INSERT INTO SomeTable(Id) VALUES(123)");
    con.commit();
    con.setAutoCommit(true);
} catch(SQLException e) {
    // These 2 lines actually need to be wrapped in a try/catch too.
    con.rollback();
    con.setAutoCommit(true);
}

Проверка кода ошибки

try {
    Statement = con.createStatement();
    statement.executeQuery("INSERT INTO SomeTable(Id) VALUES(123)");
} catch(SQLException e) {
    if(e.getSQLState().equals("23505"))
        System.err.println("Entry with Id 123 already exists!");
}

Ответы [ 3 ]

1 голос
/ 17 октября 2011

Ваш подход "проверка кода ошибки" действителен и действительно является соглашением.Обратите внимание, что вы также можете проанализировать свойство Message исключения для имени ограничения SQL, которое было нарушено, поэтому рекомендуется сделать детализацию ограничений гранулярной (т. Е. Допустить ошибку при создании множества простых ограничений, а не нескольких сложных)и дать каждому значимое имя.

0 голосов
/ 15 октября 2011

Во-первых, вы должны избегать подобных ошибок, используя последовательности или автоинкрементные столбцы для PK.

Тем не менее, правильная обработка SQLExceptions по-прежнему необходима, так как могут возникнуть всевозможные другие ошибки.

0 голосов
/ 15 октября 2011

Лично я предпочитаю защищаться от подобных вещей. Я бы написал свой запрос следующим образом:

INSERT INTO SomeTable(ID)
SELECT 123
WHERE NOT EXISTS (SELECT 1 FROM SomeTable WHERE id = 123)

Конечно, вам придется изменить этот запрос в зависимости от вашего вида SQL. Может быть:

SELECT 123
FROM DUAL 
WHERE NOT EXISTS...

После вставки вы можете проверить свой счетчик строк и определить, имело ли место нарушение PK.

...