【问题标题】:MySQL how to specify string position with LOAD DATA INFILEMySQL 如何使用 LOAD DATA INFILE 指定字符串位置
【发布时间】:2020-10-29 17:27:33
【问题描述】:

我有 ASCII 文件,每行的字符数是静态的,没有分隔符。我想使用 LOAD DATA INFILE 导入到我的表中。

文件示例:

USALALABAMA                                                               
USARARKANSAS                                                              
USFLFLORIDA                                                               

此表的结构:

country Char(2)
state Char(2)
name Varchar(70)

CREATE TABLE `states` (
  `country` char(2) COLLATE latin1_general_ci NOT NULL,
  `state` char(2) COLLATE latin1_general_ci NOT NULL,
  `name` varchar(70) COLLATE latin1_general_ci NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1_general_ci COLLATE=latin1_general_ci;

是否可以为每列指定开始和结束位置?

【问题讨论】:

    标签: mysql


    【解决方案1】:

    根据the documentation,您可以在不使用临时表的情况下加载固定格式的文件。

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

    位置来自列定义,在您的情况下与文件的结构相匹配。所以你只需要这样做:

    LOAD DATA INFILE 'your_file' INTO TABLE your_table
      FIELDS TERMINATED BY ''
      LINES TERMINATED BY '\r\n'
      SET name = trim(name);
    

    【讨论】:

    • 我用原来的例子试过了,结果很奇怪;第一行:country=US state=AB name=(62 个空格)。
    • @CorieSlate 这很奇怪,我刚刚对其进行了测试,它对我有用。你确定这是你的表结构吗?
    • 我添加了上面的SQL结构。此外,您的文本文件是否每行有 70 个字符(尾随空格?)。
    • @CorieSlate 好的,问题是因为 utf8 字符集。如果您使用多字节字符集,则固定大小格式不起作用。是的,我有尾随空格:)
    • 太棒了!设置为 latin_1 有效。你知道有什么方法可以自动修剪空白吗?
    【解决方案2】:

    首先创建一个临时表,将所有行加载到其中,然后您可以将临时表中的数据加载到主表中并使用substring拆分到字段

    类似这样的:

    CREATE TEMPORARY TABLE tmp_lines
      (countrystring TEXT);
    
    LOAD DATA INFILE 'yourfilegoeshere' INTO TABLE tmp_lines
      FIELDS TERMINATED BY ''
      LINES TERMINATED BY '\r\n';
    
    INSERT INTO main_table SELECT SUBSTRING(countrystring,1,2), SUBSTRING(countrystring,3, 2), SUBSTRING(countrystring,5) from tmp_lines;
    

    【讨论】:

    • 谢谢。那和RTRIM() 一起做我需要的。
    【解决方案3】:

    另一种方法是分配一个变量并直接在负载中拆分它。

    LOAD DATA INFILE 'yourfilegoeshere' INTO TABLE main_table
      LINES TERMINATED BY '\r\n' (@_var)
    set
      field1=TRIM(SUBSTR(@_var from 1 for 2)),
      field2=TRIM(SUBSTR(@_var from 3 for 2)),
      field3=TRIM(SUBSTR(@_var from 5 for 70));
    

    请务必不要指定任何字段分隔符,否则您将不得不使用更多变量,请注意我正在使用 TRIM 来清理同一语句中的数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-01
      • 2012-10-05
      • 2010-11-17
      • 1970-01-01
      相关资源
      最近更新 更多