SQLSTATE
SQLSTATE is a standardized five-character alphanumeric code used in the Structured Query Language (SQL) to indicate the outcome of SQL statement execution, encompassing successful completion, warnings, no data conditions, and error states. It forms part of the international SQL standard defined by ISO/IEC 9075, enabling portable error handling across compliant database management systems by replacing vendor-specific codes with a uniform reporting mechanism.[1] The structure of an SQLSTATE code divides into a two-character class code, which categorizes the general type of condition (e.g., success or exception), and a three-character subclass code, which offers more detailed information about the specific issue. Each of the five characters must be a digit from 0 to 9 or an uppercase letter from A to Z, ensuring consistent encoding.[2] Class codes follow predefined categories in the standard, with '00' denoting successful completion, '01' for warnings (such as data truncation), '02' for no data returned, and exception classes like '08' for connection issues, '22' for data exceptions (e.g., invalid data types), '23' for integrity constraint violations, '42' for syntax errors, and '38' for external routine exceptions.[3] Subclasses within these classes provide granularity, such as '22003' for numeric value out of range under the data exception class.[4] Introduced in the SQL-92 revision of the standard (ISO/IEC 9075:1992 and ANSI X3.135-1992), SQLSTATE enhanced SQL's diagnostic features by establishing a diagnostics area and supporting statements like GET DIAGNOSTICS for retrieving detailed error information, moving beyond earlier vendor-dependent error reporting.[1] Subsequent SQL standards, including SQL:1999, SQL:2003, and up to SQL:2023, have expanded the defined SQLSTATE values while maintaining backward compatibility, with classes beginning with 0, 1, 2, 3, 4, or A through G reserved for standard-defined conditions and others available for implementation-specific use.[5] In practice, SQLSTATE is integral to embedded SQL programs, stored procedures, and database APIs in systems like IBM Db2, PostgreSQL, MariaDB, Apache Spark, and Databricks, where it facilitates robust exception handling and cross-platform application development.[1][4][2]Introduction
Definition
SQLSTATE is a standardized five-character alphanumeric code used to report the outcome of SQL statement execution in relational database management systems (RDBMS). It is defined in the SQL standards ISO/IEC 9075 and ANSI X3.135, where it serves as a status parameter indicating success, warnings, no data found, or exceptions.[1][6] The code comprises a two-character class (the first two positions) that categorizes the condition broadly and a three-character subclass (the remaining positions) that specifies details, with each character limited to digits (0-9) or uppercase Latin letters (A-Z).[7][1] In contrast to vendor-specific codes like SQLCODE, which are implementation-dependent and vary across DBMS, SQLSTATE promotes portability by adhering to a uniform scheme that works consistently in any standards-compliant RDBMS. SQLCODE, while included in early SQL standards, was deprecated in ISO/IEC 9075:1992 (SQL-92) and fully removed in later editions, making SQLSTATE the recommended approach for cross-platform compatibility.[8][9] SQLSTATE facilitates exception handling, diagnostics, and condition signaling in SQL by populating the diagnostics area after statement execution, enabling applications to retrieve and act on status information. Through constructs like the GET DIAGNOSTICS statement, it provides access to condition details for error analysis, while the SIGNAL statement allows explicit raising of conditions using SQLSTATE values.[10][11][12] This mechanism supports robust application development by standardizing how SQL engines communicate execution results.[6]Purpose and Benefits
SQLSTATE serves as a standardized five-character code that indicates the outcome of an SQL statement's execution, signaling conditions such as success, warnings, no data found, or exceptions.[13] This mechanism enables portable error handling by providing a consistent format across different database management systems (DBMS), allowing applications to detect and respond to specific error classes or subclasses without relying on vendor-specific codes.[13] For instance, the class "00" denotes successful execution, while "01" indicates warnings, facilitating uniform diagnostics in diverse SQL environments.[14] The primary benefits of SQLSTATE lie in its promotion of interoperability and reduced vendor lock-in for developers. By adhering to ISO/IEC standards, it ensures that error conditions are reported in a predictable manner, enabling SQL code to be more easily ported between compliant DBMS implementations without extensive modifications.[13] This standardization simplifies application-level diagnostics, as programmers can test for broad error categories (e.g., data exceptions under class "22") or precise subclasses, enhancing reliability and maintainability in multi-vendor setups.[13] Additionally, it supports structured exception handling in embedded SQL and APIs, where applications can programmatically inspect and handle conditions, thereby improving overall system robustness.[15] In SQL's exception model, SQLSTATE integrates seamlessly with the GET DIAGNOSTICS statement to retrieve detailed information about execution outcomes. This statement populates host variables with the SQLSTATE value alongside other diagnostics, such as message text or constraint names, allowing for granular error analysis within handlers or procedures.[13] For example, after an unsuccessful operation, an application can use GET DIAGNOSTICS to fetch the RETURNED_SQLSTATE, enabling targeted recovery actions based on the standardized code.[16] This integration fosters efficient, standards-compliant exception management, minimizing downtime and supporting complex transaction processing across SQL-compliant systems.[13]History and Development
Origins in SQL Standards
The SQLSTATE mechanism was formally introduced in the SQL-92 standard, published as ANSI X3.135-1992 by the American National Standards Institute and as ISO/IEC 9075:1992 by the International Organization for Standardization and the International Electrotechnical Commission. This standard marked a significant advancement in the SQL language specification, particularly in the area of diagnostics and error handling, by defining SQLSTATE as a five-character alphanumeric string to report the outcome of SQL statements, including success, warnings, and exceptions. The structure consists of a two-character class code followed by a three-character subclass code, providing a standardized way to categorize conditions such as data exceptions or integrity constraint violations.[6] Prior to SQL-92, SQL implementations varied in error reporting, hindering portability across systems. SQLSTATE was designed to address this issue by establishing a uniform, internationally portable diagnostic system, enabling applications to handle errors consistently regardless of the underlying database management system. This unification effort complemented the deprecation of the earlier SQLCODE integer-based status parameter from the SQL-89 standard (ISO/IEC 9075:1989), promoting backward compatibility while favoring the more structured SQLSTATE for future development.[6] The development of SQLSTATE was led by the ANSI X3H2 Database Committee, which coordinated the U.S. contributions to the international effort, and the ISO/IEC JTC1/SC32 working group on database languages, responsible for harmonizing the global specification.[17][18] The first formal definition appears in Part 1 (Framework) of ISO/IEC 9075:1992, particularly in Clause 22 (Diagnostics management) and related subclauses, where it is specified as the preferred status parameter within the diagnostics area, which is cleared at the start of each SQL statement.[6] This foundational work laid the groundwork for subsequent enhancements in later SQL standards, such as SQL:1999.[6]Evolution in Subsequent Standards
Following its initial definition in the SQL-92 standard, SQLSTATE underwent significant expansions in SQL:1999 (ISO/IEC 9075-2:1999) to accommodate the introduction of advanced database features, particularly through the SQL Persistent Stored Modules (SQL/PSM) extension. New subclasses were added within existing classes to handle exceptions related to triggers and stored procedures, enabling more granular error reporting in procedural SQL code. For instance, the class 2F was defined for SQL routine exceptions (e.g., 2F000 for general SQL routine errors, 2F002 for prohibited SQL statements), while class 09 addressed triggered action exceptions (e.g., 09000 for general trigger failures). Additionally, class 38 was introduced for external routine exceptions (e.g., 38000 for general cases), and diagnostics items such as TRIGGER_CATALOG, TRIGGER_SCHEMA, and TRIGGER_NAME were specified to provide context-specific information during trigger execution. These additions supported the new capabilities for defining triggers (with BEFORE/AFTER timing and statement/row granularity) and invoking stored procedures, including dynamic result sets and parameter handling, while integrating with the overall diagnostics area for exception propagation.[13] Subsequent revisions further refined SQLSTATE to align with emerging SQL functionalities. In SQL:2003 (ISO/IEC 9075:2003), the new SQL/XML part introduced support for XML data types and operations, with errors for XML-specific issues such as invalid document structures handled under the existing data exception class 22. SQL:2006 (ISO/IEC 9075:2006) enhanced XML capabilities with XQuery integration, continuing to leverage class 22 for related data exceptions without major SQLSTATE structural changes. SQL:2008 (ISO/IEC 9075:2008) built on this by enhancing support for window functions, introducing refinements to cardinality and invalid cursor state exceptions (classes 21 and 24) that could arise from window frame boundary violations or ordering issues in analytic queries.[19][20] By SQL:2011 (ISO/IEC 9075:2011), temporal data features—such as system-versioned and application-time period tables—were added, with error handling for temporal operations utilizing existing integrity constraint (class 23) and transaction (class 40) exception classes to manage issues like period definition violations and rollbacks in historical queries. SQL:2016 (ISO/IEC 9075:2016) introduced JSON data type support and row pattern recognition, expanding data exception handling in class 22 for JSON parsing and validation errors, alongside refinements to diagnostics for pattern matching failures. Throughout these updates, the condition handling statements SIGNAL and RESIGNAL, originally specified in SQL/PSM, were more tightly integrated with SQLSTATE, allowing developers to raise user-defined conditions with custom SQLSTATE values (e.g., via SIGNAL SQLSTATE 'XXXXX') for precise exception propagation in compound statements and handlers.[21][22] As of the latest revision in SQL:2023 (ISO/IEC 9075:2023), SQLSTATE saw minor clarifications to the diagnostics framework while preserving backward compatibility and the established taxonomy for conditions. This approach ensured seamless migration and portability for applications across prior standards, with no major new classes introduced.[23][24][1]Code Structure
Format and Composition
SQLSTATE codes are defined as fixed-length strings consisting of exactly five characters. The first two characters form the class code, while the last three characters form the subclass code.[1][3] Each character in an SQLSTATE code must be either a digit from '0' to '9' or an uppercase letter from 'A' to 'Z', drawn from the ISO 646 (ASCII) character set.[3] The class code identifies a broad category of the SQL statement's outcome, such as '00' indicating successful completion, while the subclass code specifies a particular condition within that category, such as '000' denoting no specific subclass information.[25][1] SQLSTATE codes that do not conform to these encoding rules, including those using lowercase letters, other symbols, or invalid combinations, are considered undefined by the standard, and their behavior in database systems is unspecified.[26] In programming interfaces, SQLSTATE values are returned as character strings rather than numeric values, with no standard specification for numeric conversion. For instance, in ODBC and JDBC APIs, the diagnostic functions retrieve the SQLSTATE as a five-character string.[27][28]Class and Subclass Organization
The SQLSTATE codes are organized into 1,296 possible classes, identified by two alphanumeric characters ranging from '00' to 'ZZ', which categorize the outcome of SQL statement execution. These classes are semantically grouped into success (class 00), warnings (class 01), no data (class 02), feature-specific conditions (classes 0A to 3Z), and exceptions (classes 40 to 99, along with other predefined ranges like 07 to 3Z for specific error types). The first character of the class code often indicates the broad category: digits 0-4 or letters A-H are reserved by the SQL standard for predefined conditions, while other characters (5-9 or I-Z) allow for implementation-defined extensions by database vendors.[29][1] Within each class, there is a hierarchy of up to 46,656 subclasses, identified by three alphanumeric characters ranging from '000' to 'ZZZ', providing finer-grained details about the condition. The subclass '000' typically serves as a generic indicator for the class without specifying a particular subcondition, while other values like '001' denote specific scenarios, such as cursor operations. The first character of the subclass further distinguishes between standard and non-standard definitions: digits 0-4 or letters A-H are reserved for conditions defined in the ISO/IEC 9075 SQL standard, whereas other characters (5-9 or I-Z) are available for implementation-defined subclasses, enabling vendors to extend functionality without conflicting with standard codes. For instance, Oracle uses 'U' for certain non-updatable column assignments (e.g., 0U000) and 'V' for ordering column issues (e.g., 0V000).[29][1] To aid documentation and interpretation, classes are often annotated with category indicators: 'S' for success classes (00), 'W' for warnings (01), 'N' for no data (02), and 'X' for exception classes (all others). These indicators are not part of the SQLSTATE code itself but are used in standards references and vendor guides to classify conditions quickly. The standard reserves specific subclasses within classes for portability, while allowing vendors to define additional ones to handle product-specific errors, ensuring broad compatibility across SQL implementations.[29][1]Standard Classes
Success and Warning Classes
The SQLSTATE success class, designated as "00", signifies the successful completion of an SQL statement without any detected issues or warnings.[13] The primary subclass, 00000, indicates normal execution where the statement has fully succeeded, such as a standard SELECT query retrieving expected data or an INSERT operation adding rows without anomalies.[13] According to ISO/IEC 9075-2:1999, database management systems (DBMS) are required to return this class for all successful outcomes to ensure consistent status reporting across compliant implementations.[13] Additional subclasses within class 00, such as 00001 for cases involving extra result sets returned, are implementation-defined and provide optional details on non-standard but successful behaviors.[13] In contrast, the warning class "01" denotes that an SQL statement has completed successfully overall, but with non-fatal conditions that may warrant attention, such as data truncation or null handling.[13] These warnings do not interrupt execution or rollback transactions, allowing the application to proceed while accessing diagnostic information for logging or user notification.[13] The standard recommends implementing class 01 codes to enhance portability, as they standardize the reporting of minor issues across different DBMS vendors.[13] Key subclasses in class 01 include the following representative examples, as defined in the ISO/IEC 9075 standards:| Subclass | Meaning | Context |
|---|---|---|
| 01000 | General warning | Catch-all for unspecified cautionary conditions during statement execution.[13] |
| 01001 | Cursor operation conflict | Arises when a cursor encounters modifications by another operation, such as in positioned DELETE statements.[13] |
| 01003 | Null value eliminated in set function | Occurs during aggregation functions like SUM or COUNT where nulls are excluded from calculations.[13] |
| 01004 | String data, right truncation | Triggered by data assignment exceeding target column length, such as in CAST operations.[13] |
| 01006 | Privilege not revoked | Issued when attempting to revoke a non-existent or already-revoked privilege.[13] |
No Data and Feature Classes
Class 02, known as the No Data class, signals that an SQL operation has completed successfully but returned no rows. The primary subclass, 02000 (no data), is returned when a SELECT statement yields no matching rows or when a FETCH operation attempts to retrieve data beyond the end of a cursor's result set. According to the SQL standard, this class is treated as both a no-data condition and a warning, allowing applications to handle the absence of data without interpreting it as a failure.[4][1] Applications must explicitly check for class 02 to differentiate this status from true exceptions, preventing erroneous error recovery logic that could disrupt normal query flows. For instance, failing to account for 02000 might lead to unnecessary transaction rollbacks in scenarios where empty results are expected. The SQL standard recommends this verification to ensure robust handling of data retrieval operations.[4][3] Class 0A, the Feature Not Supported class, indicates that an SQL statement attempts to invoke a feature not implemented by the database system. The general subclass 0A000 (feature not supported) applies to unsupported elements, such as certain procedural extensions or advanced data types. This class provides diagnostic information when required SQL capabilities, like specific aggregation functions or module features, are unavailable.[4][1] Additional feature-related classes include 0B (Invalid Transaction Initiation) and 0F (Locator Exception). Class 0B, with subclass 0B000 (invalid transaction initiation), arises when a transaction cannot be properly started, such as in read-only contexts or nested transaction prohibitions. Class 0F addresses issues with locators—references to database objects like arrays or large objects—with 0F000 (locator exception) as the general code and 0F001 (invalid locator specification) for malformed locators; these highlight gaps in support for locator-based features. Unlike warning classes that accompany successful executions, these provide informative signals on capability limitations without implying data corruption.[4][3][1]Exception Classes
Connection and Transaction Exceptions
Connection and transaction exceptions in SQLSTATE pertain to issues arising during the establishment, maintenance, or termination of database sessions and transactions, as defined in the ISO/IEC 9075 SQL standard. These exceptions ensure that applications can detect and handle disruptions in connectivity or invalid transactional operations promptly, preventing inconsistent states or lost work. Class 08 specifically addresses connection-related failures, while classes 2D and 40 focus on transaction lifecycle errors, such as improper termination or forced rollbacks due to conflicts.[4][1] Class 08: Connection Exception signals problems with SQL connections, often stemming from network issues, server unavailability, or configuration errors that prevent or interrupt session establishment. This class is raised when the SQL client cannot initiate or sustain a valid connection to the SQL server, encompassing scenarios like failed handshakes or abrupt disconnections during execution. According to the SQL standard, implementations must raise a class 08 exception immediately upon detecting such conditions to halt further operations on the invalid connection. Representative subclasses include:- 08001 (SQL client unable to establish SQL connection): Occurs when the client fails to connect due to reasons such as incorrect server address, authentication failure, or network timeouts.[4]
- 08003 (Connection does not exist): Triggered when an operation references a non-existent connection name or identifier.[1]
- 08004 (SQL server rejected establishment of SQL connection): Raised if the server denies the connection request, for instance, due to resource limits or security policies.[4]
- 40000 (Transaction rollback): General rollback condition, applicable to various rollback triggers.[4]
- 40001 (Serialization failure): Indicates a transaction rollback due to inability to serialize concurrent transactions, common in high-isolation levels like SERIALIZABLE.[1]
- 40003 (Statement completion unknown): Used when a statement's outcome is indeterminate following a rollback, such as in distributed transactions.[4]
Data and Integrity Exceptions
Data and integrity exceptions in SQLSTATE encompass errors arising from invalid data values, constraint breaches, and syntactic or access rule violations during SQL statement execution. These classes—22, 23, and 42—signal issues that typically prevent the successful completion of data manipulation or query operations, ensuring data quality and schema adherence in compliant database systems.[13] Class 22, designated for data exceptions, captures anomalies in data handling, such as type mismatches, out-of-range values, or invalid literals that occur during assignment, casting, or arithmetic operations. For instance, subclass 22002 (null_value_no_indicator_parameter) is raised when a NULL value is assigned in embedded SQL without an indicator parameter for the host variable. Subclass 22003 denotes a numeric value out of range, occurring when an arithmetic result or cast exceeds the allowed precision or scale of the data type. Additionally, subclass 22007 signifies an invalid datetime format, raised when date, time, or timestamp literals fail to conform to the expected syntax or range, such as malformed ISO 8601 strings in INSERT or UPDATE statements. These subclasses are defined in the SQL:1999 standard to standardize error reporting for data integrity during runtime evaluation.[13][1] Class 23 addresses integrity constraint violations, which occur when data modifications contravene predefined rules like primary keys, foreign keys, or check conditions. The general subclass 23000 covers broad integrity failures, while 23502 specifically flags not null violations, activated during INSERT or UPDATE operations that attempt to assign NULL to a non-nullable column. Subclass 23505 identifies unique constraint breaches, such as duplicate values inserted into a column governed by a UNIQUE or PRIMARY KEY constraint. These errors are integral to maintaining referential integrity and are invoked at statement commit or during constraint validation in transactions.[13][1] Class 42 pertains to syntax errors or access rule violations, encompassing malformed SQL statements or insufficient privileges that hinder execution. Subclass 42000 represents general syntax issues, such as unbalanced clauses or unrecognized tokens in the query parser. Subclass 42S02 (invalid_schema_name) highlights invalid schema names, often due to references to non-existent or misspelled schema qualifiers in object identifiers. This class ensures precise diagnosis of structural or authorization problems before statement processing advances. Class 44 (WITH CHECK OPTION violation), with subclass 44000, relates to violations of the WITH CHECK OPTION on views, where an UPDATE or INSERT through a view fails because the resulting row does not satisfy the view's defining predicate.[13][1] In the ISO SQL standard, these exception classes uniformly abort the offending statement, rolling back any partial effects to preserve database consistency, while populating diagnostic areas with the specific SQLSTATE code for application-level error handling and logging. This mechanism, outlined in Clause 22 of SQL:1999, facilitates portable error recovery across conforming implementations.[13]Usage in Database Systems
Implementation in ANSI/ISO SQL
The ISO/IEC 9075 standard, which defines the SQL language, mandates that all conforming database management systems (DBMS) populate the diagnostics area with an SQLSTATE value following the execution of each SQL statement. This requirement ensures standardized error and status reporting, enabling consistent handling of outcomes across implementations. The diagnostics area serves as a structured repository for diagnostic information, where SQLSTATE provides a five-character code indicating the completion status, warnings, or exceptions resulting from the statement.[23][30] SQLSTATE integrates directly with key SQL mechanisms for retrieval and conditional handling. The GET DIAGNOSTICS statement retrieves the SQLSTATE value (along with other diagnostic details like SQLCODE and message text) from the diagnostics area into host variables or session parameters, allowing applications to inspect statement outcomes programmatically. In procedural extensions defined in ISO/IEC 9075-4 (SQL/PSM), SQLSTATE is used in DECLARE HANDLER statements to define condition handlers, such as HANDLER FOR SQLSTATE '23505' to address unique constraint violations, enabling CONTINUE or EXIT actions to manage exceptions within compound statements.[28][31] For portability, the standard recommends that applications query SQLSTATE values rather than vendor-specific codes, as it promotes cross-DBMS compatibility by abstracting error semantics into a universal format. ISO/IEC 9075 defines over 100 predefined SQLSTATE values, organized into classes (e.g., '23' for integrity constraint violations) and subclasses, with implementations required to use these for standard conditions while reserving user-defined codes in specific ranges. Compliance levels vary: Core SQL conformance (per Parts 1, 2, and 11 of ISO/IEC 9075) mandates basic SQLSTATE support in the diagnostics area and essential classes for error reporting; full SQL conformance extends this to advanced features like comprehensive exception handling in procedural modules.[32][6]Vendor-Specific Adaptations
PostgreSQL provides full support for the SQL standard's SQLSTATE codes, assigning five-character codes to all server-emitted messages while extending the scheme with vendor-specific subclasses for conditions not covered by the standard.[4] These extensions include codes starting with 'XX', such as 'XX000' for internal errors that do not fit standard categories, and 'P0001' for exceptions raised via the RAISE statement in PL/pgSQL.[4] PostgreSQL maps these SQLSTATE values to its internal error codes, ensuring compatibility with standard SQL diagnostics while allowing for database-specific error handling in applications.[4] MySQL and MariaDB implement SQLSTATE codes alongside their proprietary ER_ error numbers, mapping most server errors to standard SQLSTATE values but using 'HY000' (general error) as a fallback for unmapped conditions.[33] In MySQL, this approach extends to replication errors, where many such issues—such as corrupted events or thread initialization failures—are assigned 'HY000' rather than a specific subclass, though syntax-related replication problems may fall under class '42' (syntax error or access rule violation).[34] MariaDB follows a similar pattern, providing SQLSTATE values in its error code reference for all built-in errors, with '45000' recommended for custom signals and 'HY000' for vendor-specific cases not aligned with the standard.[35] Oracle offers partial support for SQLSTATE, primarily relying on its native SQLCODE and SQLERRM mechanisms for error reporting, but making SQLSTATE available in environments like PL/SQL and Pro*C/C++ when ANSI mode is enabled.[29] In PL/SQL, errors in the range ORA-06500 to ORA-06599 map to SQLSTATE class '65000' for procedural language issues, representing a vendor extension beyond standard classes.[36] This hybrid approach allows applications to access standardized codes via the SQLCA structure, though full SQLSTATE compliance requires explicit configuration.[36] Microsoft SQL Server supports SQLSTATE codes primarily through its ODBC driver and in error messages returned by the server, aligning with the SQL standard for diagnostic reporting in client applications. While native T-SQL uses @@ERROR for error handling, SQLSTATE values are provided in the extended error information for ODBC, JDBC, and OLE DB connections, enabling portable exception handling. Vendor-specific errors may use implementation-defined classes, but standard conditions map to predefined SQLSTATEs like '23000' for constraint violations.[37] IBM Db2 maintains comprehensive SQLSTATE support with over 500 defined values, adhering closely to ISO/IEC 9075 and ANSI X3.135 standards while introducing vendor-specific subclasses in classes starting with '5' for Db2-unique conditions.[1] These include class '51' for invalid application states (e.g., '51002' for package not found), class '53' for inconsistent specifications, and class '58' for system errors like duplicate DBID detection ('58001').[1] No subclasses starting with 'D' are defined, but the extensive list ensures detailed diagnostics for z/OS and other platforms.[1] Vendor-specific extensions to SQLSTATE, such as custom classes and fallback codes, can reduce application portability by introducing non-standard values that may not map consistently across database management systems.[1] To address this, interfaces like ODBC standardize error mapping through SQLSTATE definitions, enabling applications to handle diagnostics uniformly regardless of the underlying DBMS.Examples and Interpretation
Common SQLSTATE Codes
SQLSTATE codes, with classes defined in the ANSI/ISO SQL standard (ISO/IEC 9075) and including both standard and common implementation-defined subclasses, serve as a portable mechanism for indicating the success or failure of SQL operations, with the most common ones falling into classes for success, warnings, no data, and various exceptions. These enable consistent error handling across compliant database systems such as PostgreSQL and IBM Db2. Below is a table of 12 frequently encountered SQLSTATE codes, grouped by class, including their meanings and typical triggers.[4][1]| Class | Code | Description | Typical Triggers |
|---|---|---|---|
| 00 | 00000 | Successful completion | SQL statement executes without errors or warnings. |
| 01 | 01000 | General warning | Minor issues like data truncation or conversion warnings during execution. |
| 01 | 01003 | Null value eliminated in aggregate | Aggregate functions (e.g., SUM, AVG) ignore null values in computations. |
| 02 | 02000 | No data found | Query returns an empty result set, such as in a SELECT INTO or FETCH operation. |
| 08 | 08006 | Connection failure | Failure to establish or maintain a connection to the database server. |
| 22 | 22001 | String data, right truncation | Inserted or updated string exceeds the target column's length limit. |
| 23 | 23502 | Not null violation | Attempt to insert or update a NULL value in a column defined as NOT NULL. |
| 23 | 23503 | Foreign key violation | Insert or update violates a foreign key constraint by referencing non-existent data. |
| 23 | 23505 | Unique violation | Insert or update attempts to create a duplicate key in a unique index or constraint. |
| 40 | 40001 | Serialization failure | Transaction rollback due to deadlock or serialization anomaly in concurrent operations. |
| 42 | 42601 | Syntax error or access rule violation | Invalid SQL syntax, such as missing tokens, clauses, or improper structure. |
| 42 | 42S02 | Base table or view not found | Reference to a non-existent table, view, or object in the statement. |
Diagnostic Usage in Applications
In embedded SQL environments, applications retrieve SQLSTATE values following the execution of SQL statements to diagnose errors or warnings. The SQL Communications Area (SQLCA) structure, included via a preprocessor directive such asEXEC SQL INCLUDE SQLCA;, automatically populates the sqlstate field—a five-character string—after each executable SQL statement.[29] Alternatively, the standardized GET DIAGNOSTICS statement can explicitly fetch SQLSTATE along with other diagnostic details like error messages and row counts from the diagnostics area, enabling more granular error inspection in languages like C (Pro*C) or COBOL.[38] For instance, after a failed INSERT, a program might check SQLSTATE to determine if the issue stems from a constraint violation.
In database APIs such as ODBC and JDBC, SQLSTATE is accessed through exception or diagnostic mechanisms to facilitate cross-vendor error handling. For ODBC applications, after an SQL function like SQLExecDirect returns an error, developers call SQLGetDiagRec or SQLGetDiagField on the statement handle to retrieve the SQLSTATE value from the diagnostic record, which provides a standardized code independent of vendor-specific error numbers.[37] In JDBC, the SQLException.getSQLState() method returns the five-character SQLSTATE string from the thrown exception object, allowing applications to identify the error category without relying on implementation-specific codes.[39] A common pattern involves conditional logic based on SQLSTATE, such as:
This approach enables targeted recovery, like retrying transactions for transient errors. Best practices for handling SQLSTATE emphasize proactive logging and structured exception management to enhance application reliability and debugging. Applications should log the full SQLSTATE alongside the executed statement text, timestamp, and contextual details (e.g., input parameters) to a centralized error repository, facilitating root-cause analysis without exposing sensitive data to end users.[40] For error classes like '23' (integrity constraint violations), implement dedicated handlers that attempt retries for non-fatal issues or escalate to user notifications, while broader classes like '08' (connection exceptions) trigger reconnection logic. Avoiding generic catch-all handlers prevents masking specific issues, and testing against representative SQLSTATE values from common scenarios ensures robust coverage.[41] Object-relational mapping (ORM) frameworks integrate SQLSTATE by translating database errors into higher-level exceptions, streamlining diagnostics in modern applications. In Hibernate, for example, underlying JDBCtry { // Execute SQL statement } catch (SQLException e) { String sqlState = e.getSQLState(); if ("23505".equals(sqlState)) { handleDuplicateKeyException(); // Unique constraint violation } else if (sqlState.startsWith("23")) { notifyUserOfIntegrityError(); // Class 23: Data integrity issues } }try { // Execute SQL statement } catch (SQLException e) { String sqlState = e.getSQLState(); if ("23505".equals(sqlState)) { handleDuplicateKeyException(); // Unique constraint violation } else if (sqlState.startsWith("23")) { notifyUserOfIntegrityError(); // Class 23: Data integrity issues } }
SQLExceptions are wrapped in JDBCException subclasses, with the framework mapping SQLSTATE values to specific types like ConstraintViolationException for class '23' codes or DataAccessException for connectivity failures, allowing developers to catch and respond at the domain level without direct SQLSTATE inspection.[42] This abstraction aids debugging, as traces in tools like Hibernate's logging or integrated IDE profilers include resolved SQLSTATE details for tracing back to the originating SQL statement.