apache/seatunnel · error · SQLException

Error executing SqlServer SQL: ${ddlSQL}

Error message

Error executing SqlServer SQL: ${ddlSQL}

What it means

Thrown by SqlServerDialect.executeDDL (called from applySchemaChange) when one of the generated DDL statements fails to execute against SQL Server. The full DDL list and the driver's SQLState are wrapped into the new exception.

Source

Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/sqlserver/SqlServerDialect.java:518

            case SQLSERVER_TEXT:
            case SQLSERVER_NTEXT:
            case SQLSERVER_XML:
            case SQLSERVER_UNIQUEIDENTIFIER:
            case SQLSERVER_SQLVARIANT:
                return true;
            default:
                return false;
        }
    }

    private void executeDDL(Connection connection, List<String> ddlSQL) throws SQLException {
        try (Statement statement = connection.createStatement()) {
            for (String sql : ddlSQL) {
                log.info("Executing SqlServer SQL: {}", sql);
                statement.execute(sql);
            }
        } catch (SQLException e) {
            throw new SQLException("Error executing SqlServer SQL: " + ddlSQL, e.getSQLState(), e);
        }
    }

    private String buildColumnCommentSQL(TablePath tablePath, Column column) {
        return String.format(
                "EXEC %s.sys.sp_updateextendedproperty 'MS_Description', N'%s', 'schema', N'%s', "
                        + "'table', N'%s', 'column', N'%s';",
                tablePath.getDatabaseName(),
                column.getComment(),
                tablePath.getSchemaName(),
                tablePath.getTableName(),
                column.getName());
    }

    private boolean columnIsNullable(Connection connection, TablePath tablePath, String column)
            throws SQLException {
        // Prefix with the target database name so the query works even when the JDBC connection
        // is connected to a different database (e.g. master with no databaseName in the URL).

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Read the chained cause exception for the exact SQLState and SQL Server error message
  2. Run the failing DDL manually in SSMS to reproduce and fix syntax/quoting issues
  3. Grant ALTER permission on the table to the connector user
  4. Check that target column names/types are compatible with the SQL Server type mapping
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify ALTER permission and reproduce DDL manually first
SELECT HAS_PERMS_BY_NAME(DB_NAME() + '.dbo.MyTable', 'OBJECT', 'ALTER');

Try / catch

try {
    applySchemaChange(event);
} catch (SQLException e) {
    log.error("DDL failed: {} sqlstate={}", e.getMessage(), e.getSQLState(), e.getNextException());
}

Prevention

When it happens

Trigger: applySchemaChange submits schema-evolution statements (ADD/MODIFY/DROP COLUMN, comments via sp_updateextendedproperty) and SQL Server rejects one — bad identifier quoting, unsupported type mapping, existing column name, or insufficient ALTER permissions.

Common situations: Schema evolution against tables owned by another schema; column type changes unsupported by SQL Server; missing ALTER permission on the table; special characters in column names/comments breaking quoting.

Understand the failure class

Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/4c878756b98440dc. Report an issue: GitHub.