【问题标题】:Data truncation for enum in Java and MySQL (java.sql.SQLException: Data truncated for ...)Java 和 MySQL 中枚举的数据截断 (java.sql.SQLException: Data truncated for ...)
【发布时间】:2019-08-08 19:35:31
【问题描述】:

我有一个表示 .csv 文件结构的自定义类,该类稍后会读入该类的 arrayList。它有以下标签:

public class InputFile {

public enum Status {
    IN_STOCK,
    OUT_OF_STOCK
}

private int lineNumber;
private String sku;
private Status statusCode;
private Date orderDate;

public InputFile(int lineNumber, String sku, Status status, Date orderDate) {
    this.lineNumber = lineNumber;
    this.sku = sku;
    statusCode = status;
    setOrderDate(orderDate);
}

public Status getStatusCode() {
    return statusCode;
}

public void setStatusCode(Status input) {
    statusCode = input;
}

这是简化的 .csv 文件:

LineNumber;SKU;Status;OrderDate
1;553555254;IN_STOCK;2018-04-21
2;668470653;IN_STOCK;2018-05-08
3;899395925;OUT_OF_STOCK;2018-06-06

当我将这些读入 arrayList 并将各个状态放在控制台上只是为了检查时,它显示正确(IN_STOCK、OUT_OF_STOCK)。但是,当我尝试将其插入数据库时​​,它会被截断:

java.sql.SQLException:第 1 行的“状态”列的数据被截断

这是数据库上传的代码:

try {
     String orderItemQuery = "INSERT INTO `order_processing`.`order_item` (`OrderItemId`, `OrderId`, `SalePrice`, `ShippingPrice`, `Sku`, `Status`)" + "VALUES (?, ?, ?, ?, ?, ?)";

     PreparedStatement orderItemStmt = conn.prepareStatement(orderItemQuery);
     for (InputFile i : CSVManager.getList())
     {
         orderItemStmt.setInt (1, i.getOrderItemId());
         orderItemStmt.setInt(2,i.getOrderId());
         orderItemStmt.setDouble (3, i.getSalePrice());
         orderItemStmt.setDouble (4, i.getShippingPrice());
         orderItemStmt.setString (5, i.getSku());
         orderItemStmt.setObject(6, InputFile.Status.valueOf(i.getStatusCode().toString()));
         orderItemStmt.execute();
        }
    }
    catch (Exception e)
    {
        ...
    }

这是数据库表的 .sql:

create table order_item
(
  OrderItemId    int         not null
    primary key,
  OrderId        int         not null,
  SalePrice      decimal     not null,
  ShippingPrice  decimal     not null,
  TotalItemPrice decimal AS (ShippingPrice + SalePrice) not null,
  SKU            varchar(25) not null,
  Status         enum ('OUT_OF_STOCK', 'IN_STOCK') not null,
  constraint order_item_order_OrderId_fk
    foreign key (OrderId) references `order` (OrderId)
);

缺少什么?为什么枚举会被截断?

编辑:问题在于 Java 枚举类型的序数与 MYSQL 不同。 Java 从 0 开始计数,而 MYSQL 从 1 开始计数。为了解决差异,需要在我的枚举中的序数列表中进行修改:

    public enum Status {
    OUT_OF_STOCK (1),
    IN_STOCK (2);

    private int status;

    private Status (final int status) {
        this.status = status;
    }

    public int getStatus() {
        return status;
    }
}

然后将数据插入数据库是示例:

orderItemStmt.setInt(6, i.getStatusCode().getStatus());

【问题讨论】:

    标签: java database parsing enums truncate


    【解决方案1】:

    我相信 SQL 上的枚举类型存储为数字。它的大小是 1 或 2 个字节。如果要存储状态字段的文本版本,则将该列声明为 varchar。或者你应该存储状态序数。

    【讨论】:

    • 存储为 varchar 可以解决我的问题,但练习坚持也将作为 Enum 类型存储在数据库中。
    • 然后在枚举上使用.ordinal()方法得到整数表示
    【解决方案2】:

    将数据保存到数据库时,请使用 Status.valueOf("IN_STOCK") 和 IN_STOCK.name()。

    【讨论】:

    • 我不知道 Status 的值(它可能是 'IN_STOCK' 和 'OUT_OF_STOCK',但在读取 CSV 文件之前不知道,知道确切值并不重要)。这就是为什么我为 arrayList 使用 for 循环将其放入数据库的原因。解析似乎没问题,但仍然无法插入,并且每次都会截断数据。
    猜你喜欢
    • 1970-01-01
    • 2013-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-26
    • 2020-06-27
    • 1970-01-01
    相关资源
    最近更新 更多