从具有十进制列和 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');
其他一些笔记。
- 不要使用
CONVERT
,它是 JDBC 的一部分,但它根本不可靠,在 H2 中它的行为也取决于兼容模式。使用 CAST
规范,它是 SQL 标准的一部分。
- CAST 规范(或
CONVERT
函数)可能会在这种特定情况下被删除,INSERT
语句将自行将所有值转换为列的数据类型。
DEFAULT NULL
没有意义;如果未指定值,它将自动插入为 NULL
而无需任何附加子句。 DEFAULT NULL
不是 NOT NULL
的反义词,DEFAULT
与是否存在 NOT NULL
约束无关。
- 如果您不使用 MySQL 兼容模式 ,请在最新版本的 H2 中使用
GENERATED BY DEFAULT AS IDENTITY
。 AUTO_INCREMENT
是一种遗留的非标准和不可移植的语法,在 H2 中它应该只用于这种兼容模式。
我想将数据插入到包含来自 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');
其他一些笔记。
- 不要使用
CONVERT
,它是 JDBC 的一部分,但它根本不可靠,在 H2 中它的行为也取决于兼容模式。使用CAST
规范,它是 SQL 标准的一部分。 - CAST 规范(或
CONVERT
函数)可能会在这种特定情况下被删除,INSERT
语句将自行将所有值转换为列的数据类型。 DEFAULT NULL
没有意义;如果未指定值,它将自动插入为NULL
而无需任何附加子句。DEFAULT NULL
不是NOT NULL
的反义词,DEFAULT
与是否存在NOT NULL
约束无关。- 如果您不使用 MySQL 兼容模式 ,请在最新版本的 H2 中使用
GENERATED BY DEFAULT AS IDENTITY
。AUTO_INCREMENT
是一种遗留的非标准和不可移植的语法,在 H2 中它应该只用于这种兼容模式。