2010-01-01 20 views

Respuesta

7

SQLException contiene información específica de la base de datos relacionada con la excepción. Desde el doc:

Cada excepción de SQL proporciona varios tipos de información :

1) una cadena que describe el error. Esto se utiliza como el mensaje de excepción de Java, disponible mediante el método getMesage.

2) un "SqlState" cadena, que sigue el régimen del Convenio SqlState XOPEN o las convenciones de SQL 99 . Los valores de la cadena SQLState se describen en la especificación adecuada de . El método de DatabaseStaData getSQLStateType se puede usar para descubrir si el controlador devuelve el tipo de XOPEN o el tipo de SQL 99.

3) un código de error entero que es específico de cada proveedor. Normalmente, este será el código de error real devuelto por la base de datos subyacente .

4) una cadena a una siguiente Excepción. Esto se puede utilizar para proporcionar información de error adicional.

4

Brian's right, se lanzará una SQLException por CUALQUIER problema de JDBC. Esto es parcialmente por qué JDBC es tan molesto. El Spring library JDBC helpers proporciona un exception translator para mirar el SQLCode, SQLState, etc., y arroja el DataAccessException apropiado. Existen muchas de estas clases de excepción que le dan una mejor idea de lo que salió mal, con nombres como DataIntegrityViolationException, DataSourceLookupFailureException, PermissionDeniedDataAccessException y otros.

+0

^Lista de grandes recursos ^. Hay tanto que Spring tiene para ofrecer. Desearía tener tiempo para revisar cada bi de la API. De todos modos, también quería tirar, parece que la pregunta apuntaba subliminalmente a un INSERTO si el PK o FK es el mismo y, por lo tanto, no se puede insertar. Si este es el caso, podría atrapar una DataIntegrityViolationException, pero el uso más apropiado sería usar una cláusula SQL MERGE en lugar de un INSERT. Ver http://en.wikipedia.org/wiki/Merge_(SQL) – Prancer

24

La forma mejor y más independiente de manejar SQLException más específicamente es determinar el código de estado SQL que se puede obtener por SQLException#getSQLState(). SQLState es un código de 5 caracteres, de los cuales los dos primeros son comunes entre todos los DB y los últimos tres pueden diferir dependiendo de la DB y/o la condición específica.He aquí un extracto de la spec:

  • 02: sin datos
  • 07: Error de SQL dinámico
  • 08: Conexión excepción
  • 0A: no cuentan con el apoyo
  • 21: cardinalidad violación
  • 22: excepción de datos
  • 23: violación de la restricción de integridad
  • 24: estado no válido del cursor
  • 25: estado de la transacción no válida
  • 26: nombre de sentencia SQL no válida
  • 28: Aclaración de autorización no válido
  • 2B: privilegio depende descriptores todavía existen
  • 2C: carácter no válido nombre del conjunto de
  • 2D: finalización de transacción no válida
  • 2E: nombre de conexión no válida
  • 33: nombre descriptor SQL no válido
  • 34: cursor no válido nombre
  • 35: condición inválida número
  • 3C: nombre del cursor ambigua
  • 3D: nombre del catálogo no válido
  • 3F: esquema no válido nombre

lo tanto, para determinar si el La excepción SQL es causada por una violación de restricción, puede hacer lo siguiente en una clase (ficticia) SQLUtil:

public static boolean isConstraintViolation(SQLException e) { 
    return e.getSQLState().startsWith("23"); 
} 
+0

Puedo obtener un mensaje detallado de mi excepción informando que mi nueva fila infringe cierta restricción, pero cuando hago una 'e.getSQLState() 'para personalizar mi mensaje, siempre obtengo un valor' null'. ¿Hay alguna forma de superar esto? – Pere

2

Siguiendo en BalusC's answer, aquí hay una lista más completa y reciente de todas las clases y subclases especificadas por el estándar SQL: 2011. Acabo de ensamblar esta lista para el Javadoc of jOOQ's SQLStateSubclass.

+----+-----------------------------------------------------------+-----+--------------------------------------------------------------+ 
| Class and class description         | Subclass and subclass description         | 
+----+-----------------------------------------------------------+-----+--------------------------------------------------------------+ 
| 00 | Successful completion          | 000 | No subclass             | 
| 01 | Warning             | 000 | No subclass             | 
| 01 | Warning             | 001 | Cursor operation conflict         | 
| 01 | Warning             | 002 | Disconnect error            | 
| 01 | Warning             | 003 | Null value eliminated in set function      | 
| 01 | Warning             | 004 | String data, right truncation        | 
| 01 | Warning             | 005 | Insufficient item descriptor areas       | 
| 01 | Warning             | 006 | Privilege not revoked          | 
| 01 | Warning             | 007 | Privilege not granted          | 
| 01 | Warning             | 009 | Search condition too long for information schema    | 
| 01 | Warning             | 00A | Query expression too long for information schema    | 
| 01 | Warning             | 00B | Default value too long for information schema    | 
| 01 | Warning             | 00C | Result sets returned           | 
| 01 | Warning             | 00D | Additional result sets returned        | 
| 01 | Warning             | 00E | Attempt to return too many result sets      | 
| 01 | Warning             | 00F | Statement too long for information schema     | 
| 01 | Warning             | 012 | Invalid number of conditions         | 
| 01 | Warning             | 02F | Array data, right truncation         | 
| 02 | No data             | 000 | No subclass             | 
| 02 | No data             | 001 | No additional result sets returned       | 
| 07 | Dynamic SQL Error           | 000 | No subclass             | 
| 07 | Dynamic SQL Error           | 001 | Using clause does not match dynamic parameter specifications | 
| 07 | Dynamic SQL Error           | 002 | Using clause does not match target specifications   | 
| 07 | Dynamic SQL Error           | 003 | Cursor specification cannot be executed      | 
| 07 | Dynamic SQL Error           | 004 | Using clause required for dynamic parameters     | 
| 07 | Dynamic SQL Error           | 005 | Prepared statement not a cursor specification    | 
| 07 | Dynamic SQL Error           | 006 | Restricted data type attribute violation      | 
| 07 | Dynamic SQL Error           | 007 | Using clause required for result fields      | 
| 07 | Dynamic SQL Error           | 008 | Invalid descriptor count          | 
| 07 | Dynamic SQL Error           | 009 | Invalid descriptor index          | 
| 07 | Dynamic SQL Error           | 00B | Data type transform function violation      | 
| 07 | Dynamic SQL Error           | 00C | Undefined DATA value           | 
| 07 | Dynamic SQL Error           | 00D | Invalid DATA target           | 
| 07 | Dynamic SQL Error           | 00E | Invalid LEVEL value           | 
| 07 | Dynamic SQL Error           | 00F | Invalid DATETIME_INTERVAL_CODE        | 
| 08 | Connection exception          | 000 | No subclass             | 
| 08 | Connection exception          | 001 | SQL-client unable to establish SQL-connection    | 
| 08 | Connection exception          | 002 | Connection name in use          | 
| 08 | Connection exception          | 003 | Connection does not exist         | 
| 08 | Connection exception          | 004 | SQL-server rejected establishment of SQL-connection   | 
| 08 | Connection exception          | 006 | Connection failure           | 
| 08 | Connection exception          | 007 | Transaction resolution unknown        | 
| 09 | Triggered action exception        | 000 | No subclass             | 
| 0A | Feature not supported          | 000 | No subclass             | 
| 0A | Feature not supported          | 001 | Multiple server transactions         | 
| 0D | Invalid target type specification       | 000 | No subclass             | 
| 0E | Invalid schema name list specification     | 000 | No subclass             | 
| 0F | Locator exception           | 000 | No subclass             | 
| 0F | Locator exception           | 001 | Invalid specification          | 
| 0L | Invalid grantor           | 000 | No subclass             | 
| 0M | Invalid SQL-invoked procedure reference     | 000 | No subclass             | 
| 0P | Invalid role specification        | 000 | No subclass             | 
| 0S | Invalid transform group name specification    | 000 | No subclass             | 
| 0T | Target table disagrees with cursor specification   | 000 | No subclass             | 
| 0U | Attempt to assign to non-updatable column     | 000 | No subclass             | 
| 0V | Attempt to assign to ordering column      | 000 | No subclass             | 
| 0W | Prohibited statement encountered during trigger execution | 000 | No subclass             | 
| 0W | Prohibited statement encountered during trigger execution | 001 | Modify table modified by data change delta table    | 
| 0Z | Diagnostics exception          | 000 | No subclass             | 
| 0Z | Diagnostics exception          | 001 | Maximum number of stacked diagnostics areas exceeded   | 
| 21 | Cardinality violation          | 000 | No subclass             | 
| 22 | Data exception           | 000 | No subclass             | 
| 22 | Data exception           | 001 | String data, right truncation        | 
| 22 | Data exception           | 002 | Null value, no indicator parameter       | 
| 22 | Data exception           | 003 | Numeric value out of range         | 
| 22 | Data exception           | 004 | Null value not allowed          | 
| 22 | Data exception           | 005 | Error in assignment           | 
| 22 | Data exception           | 006 | Invalid interval format          | 
| 22 | Data exception           | 007 | Invalid datetime format          | 
| 22 | Data exception           | 008 | Datetime field overflow          | 
| 22 | Data exception           | 009 | Invalid time zone displacement value       | 
| 22 | Data exception           | 00B | Escape character conflict         | 
| 22 | Data exception           | 00C | Invalid use of escape character        | 
| 22 | Data exception           | 00D | Invalid escape octet           | 
| 22 | Data exception           | 00E | Null value in array target         | 
| 22 | Data exception           | 00F | Zero-length character string         | 
| 22 | Data exception           | 00G | Most specific type mismatch         | 
| 22 | Data exception           | 00H | Sequence generator limit exceeded       | 
| 22 | Data exception           | 00P | Interval value out of range         | 
| 22 | Data exception           | 00Q | Multiset value overflow          | 
| 22 | Data exception           | 010 | Invalid indicator parameter value       | 
| 22 | Data exception           | 011 | Substring error            | 
| 22 | Data exception           | 012 | Division by zero            | 
| 22 | Data exception           | 013 | Invalid preceding or following size in window function  | 
| 22 | Data exception           | 014 | Invalid argument for NTILE function       | 
| 22 | Data exception           | 015 | Interval field overflow          | 
| 22 | Data exception           | 016 | Invalid argument for NTH_VALUE function      | 
| 22 | Data exception           | 018 | Invalid character value for cast        | 
| 22 | Data exception           | 019 | Invalid escape character          | 
| 22 | Data exception           | 01B | Invalid regular expression         | 
| 22 | Data exception           | 01C | Null row not permitted in table        | 
| 22 | Data exception           | 01E | Invalid argument for natural logarithm      | 
| 22 | Data exception           | 01F | Invalid argument for power function       | 
| 22 | Data exception           | 01G | Invalid argument for width bucket function     | 
| 22 | Data exception           | 01H | Invalid row version           | 
| 22 | Data exception           | 01S | Invalid XQuery regular expression       | 
| 22 | Data exception           | 01T | Invalid XQuery option flag         | 
| 22 | Data exception           | 01U | Attempt to replace a zero-length string      | 
| 22 | Data exception           | 01V | Invalid XQuery replacement string       | 
| 22 | Data exception           | 01W | Invalid row count in fetch first clause      | 
| 22 | Data exception           | 01X | Invalid row count in result offset clause     | 
| 22 | Data exception           | 020 | Invalid period value           | 
| 22 | Data exception           | 021 | Character not in repertoire         | 
| 22 | Data exception           | 022 | Indicator overflow           | 
| 22 | Data exception           | 023 | Invalid parameter value          | 
| 22 | Data exception           | 024 | Unterminated C string          | 
| 22 | Data exception           | 025 | Invalid escape sequence          | 
| 22 | Data exception           | 026 | String data, length mismatch         | 
| 22 | Data exception           | 027 | Trim error             | 
| 22 | Data exception           | 029 | Noncharacter in UCS string         | 
| 22 | Data exception           | 02D | Null value substituted for mutator subject parameter   | 
| 22 | Data exception           | 02E | Array element error           | 
| 22 | Data exception           | 02F | Array data, right truncation         | 
| 22 | Data exception           | 02G | Invalid repeat argument in sample clause      | 
| 22 | Data exception           | 02H | Invalid sample size           | 
| 23 | Integrity constraint violation       | 000 | No subclass             | 
| 23 | Integrity constraint violation       | 001 | Restrict violation           | 
| 24 | Invalid cursor state          | 000 | No subclass             | 
| 25 | Invalid transaction state         | 000 | No subclass             | 
| 25 | Invalid transaction state         | 001 | Active SQL-transaction          | 
| 25 | Invalid transaction state         | 002 | Branch transaction already active       | 
| 25 | Invalid transaction state         | 003 | Inappropriate access mode for branch transaction    | 
| 25 | Invalid transaction state         | 004 | Inappropriate isolation level for branch transaction   | 
| 25 | Invalid transaction state         | 005 | No active SQL-transaction for branch transaction    | 
| 25 | Invalid transaction state         | 006 | Read-only SQL-transaction         | 
| 25 | Invalid transaction state         | 007 | Schema and data statement mixing not supported    | 
| 25 | Invalid transaction state         | 008 | Held cursor requires same isolation level     | 
| 26 | Invalid SQL statement name        | 000 | No subclass             | 
| 27 | Triggered data change violation       | 000 | No subclass             | 
| 27 | Triggered data change violation       | 001 | Modify table modified by data change delta table    | 
| 28 | Invalid authorization specification      | 000 | No subclass             | 
| 2B | Dependent privilege descriptors still exist    | 000 | No subclass             | 
| 2C | Invalid character set name        | 000 | No subclass             | 
| 2C | Invalid character set name        | 001 | Cannot drop SQL-session default character set    | 
| 2D | Invalid transaction termination       | 000 | No subclass             | 
| 2E | Invalid connection name         | 000 | No subclass             | 
| 2F | SQL routine exception          | 000 | No subclass             | 
| 2F | SQL routine exception          | 002 | Modifying SQL-data not permitted        | 
| 2F | SQL routine exception          | 003 | Prohibited SQL-statement attempted       | 
| 2F | SQL routine exception          | 004 | Reading SQL-data not permitted        | 
| 2F | SQL routine exception          | 005 | Function executed no return statement      | 
| 2H | Invalid collation name         | 000 | No subclass             | 
| 30 | Invalid SQL statement identifier       | 000 | No subclass             | 
| 33 | Invalid SQL descriptor name        | 000 | No subclass             | 
| 34 | Invalid cursor name          | 000 | No subclass             | 
| 35 | Invalid condition number         | 000 | No subclass             | 
| 36 | Cursor sensitivity exception        | 000 | No subclass             | 
| 36 | Cursor sensitivity exception        | 001 | request rejected            | 
| 36 | Cursor sensitivity exception        | 002 | request failed            | 
| 38 | External routine exception        | 000 | No subclass             | 
| 38 | External routine exception        | 001 | Containing SQL not permitted         | 
| 38 | External routine exception        | 002 | Modifying SQL-data not permitted        | 
| 38 | External routine exception        | 003 | Prohibited SQL-statement attempted       | 
| 38 | External routine exception        | 004 | Reading SQL-data not permitted        | 
| 39 | External routine invocation exception      | 000 | No subclass             | 
| 39 | External routine invocation exception      | 004 | Null value not allowed          | 
| 3B | Savepoint exception          | 000 | No subclass             | 
| 3B | Savepoint exception          | 001 | Invalid specification          | 
| 3B | Savepoint exception          | 002 | Too many              | 
| 3C | Ambiguous cursor name          | 000 | No subclass             | 
| 3D | Invalid catalog name          | 000 | No subclass             | 
| 3F | Invalid schema name          | 000 | No subclass             | 
| 40 | Transaction rollback          | 000 | No subclass             | 
| 40 | Transaction rollback          | 001 | Serialization failure          | 
| 40 | Transaction rollback          | 002 | Integrity constraint violation        | 
| 40 | Transaction rollback          | 003 | Statement completion unknown         | 
| 40 | Transaction rollback          | 004 | Triggered action exception         | 
| 42 | Syntax error or access rule violation      | 000 | No subclass             | 
| 44 | With check option violation        | 000 | No subclass             | 
| HZ | Remote database access         | 000 | No subclass             | 
+----+-----------------------------------------------------------+-----+--------------------------------------------------------------+ 
0

También puede utilizar getErrorCode() método para controlar las excepciones correctamente, especialmente útil cuando se trabaja con procedimientos almacenados o funciones y usted tiene sus propios códigos de error personalizados.

Puede ser útil para alguien que tenga un contexto similar.

0

En la cláusula catch, puede ser más específico para manejar ese Exception.

try { 

// Your code here 

} catch(SQLException ex){ 
    if(ex instanceof SQLIntegrityConstraintViolationException) { 
      // Handle Here 
    } 
} 
+1

Por lo general, es mejor usar una cláusula catch específica adicional, en lugar de usar if. –

+0

¡Por supuesto que agregué el azúcar, terminas con la adición de té! Pero prefiero de esta manera porque antes de entrar al 'si' usualmente uso la excepción general y para mí es más fácil de mantener, pero la elección siempre depende del desarrollador. –

Cuestiones relacionadas