从具有十进制列和 bigdecimal JPA 属性的 csv 文件插入到 H2 数据库,Spring Boot

Insert to H2 database from a csv file with a decimal column and a bigdecimal JPA attribute, Spring Boot

我想将数据插入到包含来自 csv 文件的 decimal(13, 4) 列的 h2 table,但出现以下错误

org.springframework.jdbc.datasource.init.ScriptStatementFailedException at ScriptUtils.java:622
        Caused by: org.h2.jdbc.JdbcSQLDataException at DbException.java:457
            Caused by: java.lang.NumberFormatException at BigDecimal.java:577

这是 csv 文件

username,name,grupo,amount,percentage
MYUSER,CLIENT NAME,THE GROUP,30545000,0.093438569266185,

这是我的table

create table my_table
(
    mytable_id integer     NOT NULL AUTO_INCREMENT,
    user                   varchar(30) NOT NULL,
    name            varchar(300)   DEFAULT NULL,
    grupo         varchar(300)   DEFAULT NULL,
    amount                 DECIMAL(13, 4) DEFAULT NULL,
    percentage    decimal(5, 2)  DEFAULT NULL,
    PRIMARY KEY (mytable_id)
);

这是我的 JPA 实体 class

@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "my_table")
public class CreditLineSummaryJPA {

@Id
@Column(name = "mytable_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long mytableId;

@Column(name = "user")
private String user;

@Column(name = "name")
private String name;

@Column(name = "grupo")
private String grupo;

@Column(name = "amount")
private BigDecimal amount;

@Column(name = "percentage")
private double userPercentage;

}

这是要从 csv 文件插入的 sql 语句

    INSERT INTO my_table(user, name, the_group, amount, user_percentage)
SELECT "username", "name", "grupo", CONVERT("amount", decimal(13, 4)),
CONVERT ("percentage", decimal(5, 2))
FROM CSVREAD( 'myFile.csv', 'charset=UTF-8');

和这个returns下面的错误

org.springframework.jdbc.datasource.init.ScriptStatementFailedException at ScriptUtils.java:622
        Caused by: org.h2.jdbc.JdbcSQLDataException at DbException.java:457
            Caused by: java.lang.NumberFormatException at BigDecimal.java:577

编辑 使用双引号后,现在的错误是

org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "username" not found; SQL statement

CSVREAD 的第二个参数是列名列表: https://h2database.com/html/functions.html#csvread

你的情况应该是NULL

CSVREAD('myFile.csv', NULL, 'charset=UTF-8')

CSV中不带空格的列名一般会转为大写(但这取决于数据库设置),所以如果要引用它们,则需要将它们写成大写("USERNAME"等。 ) 或者你可以不带引号写它们:

INSERT INTO my_table(user, name, grupo, amount, percentage)
SELECT username, name, grupo, CAST(amount AS decimal(13, 4)),
CAST(percentage AS decimal(5, 2))
FROM CSVREAD('myFile.csv', NULL, 'charset=UTF-8');

其他一些笔记。

  1. 不要使用 CONVERT,它是 JDBC 的一部分,但它根本不可靠,在 H2 中它的行为也取决于兼容模式。使用 CAST 规范,它是 SQL 标准的一部分。
  2. CAST 规范(或CONVERT 函数)可能会在这种特定情况下被删除,INSERT 语句将自行将所有值转换为列的数据类型。
  3. DEFAULT NULL没有意义;如果未指定值,它将自动插入为 NULL 而无需任何附加子句。 DEFAULT NULL 不是 NOT NULL 的反义词,DEFAULT 与是否存在 NOT NULL 约束无关。
  4. 如果您不使用 MySQL 兼容模式 ,请在最新版本的 H2 中使用 GENERATED BY DEFAULT AS IDENTITYAUTO_INCREMENT 是一种遗留的非标准和不可移植的语法,在 H2 中它应该只用于这种兼容模式。