为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。
【DM版本】:DM8
【操作系统】:CENTOS
【CPU】:8C
【问题描述】*:mysql迁移至DM8。如下:data_quality_task 这张表有project_id字段,由于这个字段从用户对象获取,属于公共字段。
原项目使用mysql,框架里面有使用druid方言包里面的MySqlInsertStatement,可以在执行insert语句时,动态增加列及值,麻烦问下DM8有可以代替的方案吗。
SQL: INSERT INTO data_quality_task ( task_type, origin_table_id, table_name_cn, table_name_en, ds_id, ds_name, configuration_status, create_user, update_user ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ? )
Cause: dm.jdbc.driver.DMException: Violate not null constraint on [project_id]


首先你的报错是违反唯一性约束。
然后,动态加列也不是通过方言实现的,而是通过拦截器实现的,给你代码参考:
--定义拦截器 import com.alibaba.druid.filter.FilterAdapter; import com.alibaba.druid.proxy.jdbc.StatementProxy; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; public class DynamicColumnInterceptor extends FilterAdapter { @Override public boolean statement_execute(StatementProxy statement, String sql) { try { // 检查是否是 INSERT INTO 操作 if (sql.trim().toUpperCase().startsWith("INSERT INTO")) { // 动态检查表结构 checkAndAddColumn(statement.getConnection(), "MY_TABLE", "NEW_COLUMN", "VARCHAR(255)"); } } catch (Exception e) { e.printStackTrace(); } return super.statement_execute(statement, sql); } private void checkAndAddColumn(Connection connection, String tableName, String columnName, String columnType) throws Exception { // 检查列是否存在 String checkColumnSql = "SELECT COUNT(*) FROM USER_TAB_COLUMNS WHERE TABLE_NAME = ? AND COLUMN_NAME = ?"; try (PreparedStatement checkStmt = connection.prepareStatement(checkColumnSql)) { checkStmt.setString(1, tableName.toUpperCase()); // 达梦中的表名和列名是大写 checkStmt.setString(2, columnName.toUpperCase()); try (ResultSet rs = checkStmt.executeQuery()) { if (rs.next() && rs.getInt(1) == 0) { // 动态增加列 String alterTableSql = "ALTER TABLE " + tableName + " ADD " + columnName + " " + columnType; try (PreparedStatement alterStmt = connection.prepareStatement(alterTableSql)) { alterStmt.executeUpdate(); System.out.println("Column '" + columnName + "' added to table '" + tableName + "'"); } } } } } } --配置 Druid 数据源,添加拦截器 import com.alibaba.druid.pool.DruidDataSource; public class DataSourceConfig { public static DruidDataSource createDataSource() throws Exception { DruidDataSource dataSource = new DruidDataSource(); dataSource.setUrl("jdbc:dm://localhost:5236/DAMENG"); // 达梦数据库 URL dataSource.setDriverClassName("dm.jdbc.driver.DmDriver"); // 达梦 JDBC 驱动类 dataSource.setUsername("SYSDBA"); // 用户名 dataSource.setPassword("SYSDBA"); // 密码 // 添加自定义拦截器 DynamicColumnInterceptor interceptor = new DynamicColumnInterceptor(); dataSource.getProxyFilters().add(interceptor); return dataSource; } }