【问题标题】:MySQL : how to load data with fixed-row format into user variablesMySQL:如何将固定行格式的数据加载到用户变量中
【发布时间】:2010-11-23 16:17:21
【问题描述】:

我正在尝试加载所有行都使用相同规则的文件。 (假设 HEADER 是单行)

HEADER1
HEADER2
.......

但不幸的是,当我尝试使用 LOAD DATA INFILE 语句时,我收到此错误:错误代码:1409 无法将具有固定大小行的文件中的值加载到变量。

这是我写的代码:

USE test;
DROP TABLE IF EXISTS EXAMPLE_H;
CREATE TABLE EXAMPLE_H(
    ID CHAR(20),
    SP CHAR(3),
    IVA CHAR(11) PRIMARY KEY,
    NLP CHAR(6),
    DLP DATE,
    DUVI DATE,
    DELP CHAR(30),
    FILLER CHAR(39),
    VTLP CHAR(3),
    FILL CHAR(49)
);

LOAD DATA INFILE 'BTILSP.TXT' 
    INTO TABLE test.EXAMPLE_H
    FIELDS TERMINATED BY ''
    LINES TERMINATED BY '\n'
    (ID, SP, IVA, NLP, @var_date_one, @var_date_two, DELP, FILLER, VTLP, FILL)
    SET DLP = str_to_date(@var_date_one, '%Y%m%d',
        DUVI = str_to_date(@var_date_two, '%Y%m%d');

我在阅读 this page 的底部(由 Ramam Pullella 评论)产生了这个想法,我在一些网站上发现了同样的解释,但我不明白为什么会出现这个错误。

如果我不使用 @var_date_one 和 @var_date_two 变量以及 STR_TO_DATE 函数,则日期不会按照 MySql 的需要呈现 - 文件中的日期类似于“20100701” - 那么该字段将包含全零或与我预期的日期不同的日期。如果我将 DLP 和 DUVI 更改为由 CHAR(8) 表示,那么它可以工作,但我不会使用 SQL DATE 比较和类似工具。

你能帮帮我吗? :) 非常感谢。

编辑:

问题似乎是由 LINE TERMINATED BY '' 给出的,因为这种行是“固定行(未定界)”。也许由于未知原因无法将其分配给变量,但它就是这样工作的。 文档说:

用户变量不能在以下情况下使用 以固定行格式加载数据 因为用户变量没有 显示宽度。

有什么建议吗?

重新编辑: 我已经阅读了该页面底部 Ryan Neve 的评论。他给出了一个将固定行读入变量的技巧:

LOAD DATA LOCAL INFILE '<file name>' INTO TABLE <table>
(@var1)
SET Date=str_to_date(SUBSTR(@var1,3,10),'%m/%d/%Y'),
Time=SUBSTR(@var1,14,8),
WindVelocity=SUBSTR(@var1,26,5),
WindDirection=SUBSTR(@var1,33,3),
WindCompass=SUBSTR(@var1,38,3),
WindNorth=SUBSTR(@var1,43,6),
WindEast=SUBSTR(@var1,51,6),
WindSamples=SUBSTR(@var1,61,4);

您认为这是一个好方法吗? :)

【问题讨论】:

  • 在文档中提到它不适用于固定长度格式的数据。最好的最好,是重新修复您的插入文件。或者将其更改为 varchar,稍后执行类型转换。
  • @ajreal:谢谢!昨天我没有看你的答案,但我编辑了我的问题,我写了一些像你说的东西:)

标签: sql mysql database


【解决方案1】:

我不是专家,但在我看来,如果字段以空字符串终止,那么它们必须改为固定大小;必须有某种方法来确定字段之间的边界,如果没有终结符,那么它们几乎必须是固定大小的。

我观察到MySQL 5.5 手册说:

  • 加载固定行格式的数据时不能使用用户变量,因为用户变量没有显示宽度。

它还(在页面的前面)说:

  • 如果 FIELDS TERMINATED BY 和 FIELDS ENCLOSED BY 值都为空 (''),则使用固定行(非定界)格式。使用固定行格式,字段之间不使用分隔符(但您仍然可以使用行终止符)。相反,使用足够宽的字段宽度来读取和写入列值以容纳字段中的所有值。对于 TINYINT、SMALLINT、MEDIUMINT、INT 和 BIGINT,字段宽度分别为 4、6、8、11 和 20,无论声明的显示宽度是多少。

由于您的语句没有 'FIELDS ENCLOSED BY' 和空的 'FIELDS ENCLOSED BY',这就是您有固定格式的原因。因此你不能随心所欲。


有时,在 DBMS 之外处理数据更容易 - 修复数据表示可能就是这样一种操作。我确实有我称之为 DBLDFMT 的程序,我已经有几年没用过了,但它可以执行各种操作,例如使用隐式小数点转换十进制数(大型机技巧;价格字段可能是 0023199,代表价值 231.99 英镑)。它也可以处理日期操作(不一定使用特别用户友好的符号,但它能够处理我在将数据从大型机获取到 Unix DBMS 时遇到的问题 - 而不是 MySQL;当我写这篇文章时它并不存在代码。如果您对此感兴趣,请与我联系 - 请参阅我的个人资料。

【讨论】:

  • 非常感谢您的回答。但是,我解决了这个问题,您可以在底部阅读。
  • @Markon:好的 - 那么也许你应该写下你的答案作为答案,然后在必要的延迟后接受它(3天,但我不确定这是否来自于问题或提交您自己的答案)。这将实现问题的关闭 - 它不会显示为未回答或没有接受/赞成的答案。
  • 我不太喜欢回答我的问题的想法:P 顺便说一句,我在常见问题解答中看不到这个必要条件。如果是“程序”,好的,下次我会回答自己:P再次感谢你:)
【解决方案2】:

以防其他人遇到此问题。 如果你只是运行

LOAD DATA LOCAL INFILE '<file name>' INTO TABLE <table> (@var1) SET ...

不指定FIELDS TERMINATED BY,并且您的文件包含逗号,默认情况下 MySQL 将对其进行拆分。

在这种情况下,您可以告诉 MySQL 您的字段分隔符是愚蠢的。例如:

FIELDS TERMINATED BY '@@@@@@@@@@@@'

这样整行就被放入第一个“列”,即您的用户变量。然后,您可以完全按照顶部代码中所示的方式使用它。

值得注意的是 MySQL 将分隔符视为字符串,因此您甚至可以拥有
FIELDS TERMINATED BY 'this_string_thoes_not_appear_in_my_file 如果你愿意

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-06
    • 2018-06-22
    • 1970-01-01
    • 2015-08-28
    • 1970-01-01
    • 2018-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多