将 SSMS .rpt 文件加载到 MySQL

Posted

技术标签:

【中文标题】将 SSMS .rpt 文件加载到 MySQL【英文标题】:Loading an SSMS .rpt file to MySQL 【发布时间】:2020-06-14 11:24:08 【问题描述】:

我有一个来自 SSMS 的 .rpt 文件输出。我可以在文本编辑器或 Excel 中打开它,但格式似乎不是空格、制表符或逗号分隔,因此导致 Excel 中的格式不正确。

我在使用LOAD DATA INFILE 调用加载到 mysql 时遇到了类似的问题。

即,加载“完成”,但由于明显的格式差异,大多数行/列被跳过。

输入:

EffectiveDate           family Instrument  SedolCode    Name                                                         ICB         QZ                     VZ                     MZ                     SZ                     volZ                   LZ                     DYZ                    QS                     VS                     MS                     SS                     volS                   LS                     DYS                    price_o                fx_o                   shares                 cap_o_usd
----------------------- ------ ----------- ------------ ------------------------------------------------------------ ----------- ---------------------- ---------------------- ---------------------- ---------------------- ---------------------- ---------------------- ---------------------- ---------------------- ---------------------- ---------------------- ---------------------- ---------------------- ---------------------- ---------------------- ---------------------- ---------------------- ---------------------- ----------------------
1998-03-23 00:00:00.000 RU1000 1010846     2046789      Arco Chemical                                                1           0.332041753946526      3                      -0.701907649892818     0                      1.12824639032619       1.25544514744965       1.60431785387846       0.630071248806063      0.998650187313827      0.241368465365155      0.5                    0.870392090484651      0.895341500804304      0.945678041846726      48.56                  1                      16794000               815555357.27
1998-03-23 00:00:00.000 RU1000 1004415     2048804      Pinnacle West Capital Corp                                   7           0.197368136475134      0.295748219600254      0.0886833678439797     0                      1.05597173533583       -0.0327467636082814    0.75373010240488       0.578230241112579      0.616288903631446      0.535333094702153      0.5                    0.854509410778738      0.486938352167234      0.774494234589535      44.44                  1                      84718000               3764645032.54
1998-03-23 00:00:00.000 RU1000 1003705     2050832      Ameren Corp                                                  7           0.482269760349473      -0.0732144149931671    -0.623013812458784     0                      1.29932391788085       -0.218587562254685     1.72709462374024       0.685192934274198      0.470817875898523      0.266637746506796      0.5                    0.903083725664561      0.413485670414547      0.9579246320922        42.31                  1                      137215000              5805918920.82

表格格式:

create table myTable(
    effectiveDate DATE NOT NULL,
    family CHAR(6) NOT NULL,
    instrument INT NOT NULL,
    sedol CHAR(8),
    name VARCHAR(100),
    icb INT,
    QZ DOUBLE,
    VZ DOUBLE,
    MZ DOUBLE,
    SZ DOUBLE,
    volZ DOUBLE,
    LZ DOUBLE,
    DYZ DOUBLE,
    QS DOUBLE,
    VS DOUBLE,
    MS DOUBLE,
    SS DOUBLE,
    volS DOUBLE,
    LS DOUBLE,
    DYS DOUBLE,
    priceO DOUBLE,
    fxO DOUBLE,
    capOUSD DOUBLE,
    PRIMARY KEY (effectiveDate, instrument));

加载调用

load data infile '/ru/z1.rpt'
into table myTable
(effectiveDate, family, instrument, sedol, name, icb, qz, vz, mz, sz, volz, lz, dyz, qs, vs, ms, ss, vols, dys, priceO, fxO, @dummy, capOUSD);

【问题讨论】:

LOAD DATA LOCAL INFILE 在源文件不是本地文件时使用 - 此关键字导致 src 文件在导入之前复制到本地驱动器。 是否有人成功地将 .rpt 文件加载到 MySQL 数据库/表中。 显示此文件内容示例(将 3-4 行复制为文本)和目标表结构(其 CREATE TABLE 脚本)。一般来说,从位置文本文件导入数据是没有问题的。 @Akina,谢谢。更新了详细信息。另外,最初尝试缺席LOCAL 添加最初的结果相似。 【参考方案1】:

如果您使用的是 unix/linux,那么您可以通过 sed 来去除空格。 The solution is here

我使用 PHP 为自己找到了解决方案:

<?php

$mysqli  =  new mysqli(
"***",
"***",
"***",
"***",
3306
);
mysqli_options($mysqli, MYSQLI_OPT_LOCAL_INFILE, true);

if (mysqli_connect_errno()) 
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();


function createTempFileWithDelimiter($filename, $path)
    $content = file_get_contents($filename);
    $replaceContent = preg_replace('/\ +/', ',', $content); 
    
    $onlyFileName = explode('\\',$filename);

    $newFileName = $path.end($onlyFileName);
    file_put_contents($newFileName, $replaceContent);
    
    return $newFileName;


$pathTemp = 'C:\\Temp\\';

$pathToFile = 'C:\\ProgramData\\MySQL\\MySQL Server 8.0\\Uploads\\z1.rpt';

$file = createFileWithDelimiter($pathToFile, $pathTemp);
$file = str_replace(DIRECTORY_SEPARATOR, '/', $file);

$sql = "LOAD DATA INFILE '".$file."' INTO TABLE `myTable` 
    COLUMNS TERMINATED BY ','
    LINES TERMINATED BY '\n'
    IGNORE 2 LINES
    (effectiveDate, family, instrument, sedol, name, icb, qz, vz, mz, sz, volz, lz, dyz, qs, vs, ms, ss, vols, dys, priceO, fxO, @dummy, capOUSD);";

if (!($stmt = $mysqli->query($sql))) 
    echo "\nQuery execute failed: ERRNO: (" . $mysqli->errno . ") " . $mysqli->error;
;

unlink($file);
?>

不要在 preg_replace 中使用 '/\s+/' 因为 \s 匹配任何空白字符(相当于 [\r\n\t\f\v ])并且格式会改变, 列和换行符将消失。

【讨论】:

【参考方案2】:

您必须加载整个数据行,然后使用适当的数据类型转换对其进行解析:

LOAD DATA INFILE 'C:\\ProgramData\\MySQL\\MySQL Server 8.0\\Uploads\\z1.rpt'
INTO TABLE myTable
IGNORE 2 ROWS /* skip header */
(@tmp) /* load whole line into vartiable */
SET  /* then parse separate field values from the variable */
EffectiveDate = SUBSTRING(@tmp,1,23), /* datetime literal - get as-is */
family        = SUBSTRING(@tmp,25,6), /* string data - get needed length */
Instrument    = 0+SUBSTRING(@tmp,32,11), /* numeric data - convert from string implicitly */
Sedol         = SUBSTRING(@tmp,44,8),
Name          = SUBSTRING(@tmp,57,60),
ICB           = 0+SUBSTRING(@tmp,118,12),
QZ            = 0+SUBSTRING(@tmp,130,22),
VZ            = 0+SUBSTRING(@tmp,153,22),
MZ            = 0+SUBSTRING(@tmp,176,22),
SZ            = 0+SUBSTRING(@tmp,199,22),
volZ          = 0+SUBSTRING(@tmp,222,22),
LZ            = 0+SUBSTRING(@tmp,245,22),
DYZ           = 0+SUBSTRING(@tmp,268,22),
QS            = 0+SUBSTRING(@tmp,291,22),
VS            = 0+SUBSTRING(@tmp,314,22),
MS            = 0+SUBSTRING(@tmp,337,22),
SS            = 0+SUBSTRING(@tmp,360,22),
volS          = 0+SUBSTRING(@tmp,383,22),
LS            = 0+SUBSTRING(@tmp,406,22),
DYS           = 0+SUBSTRING(@tmp,429,22),
priceO        = 0+SUBSTRING(@tmp,452,22),
fxO           = 0+SUBSTRING(@tmp,475,22),
/* shares=0+SUBSTRING(@tmp,498,22), */ /* field is absent in table structure - skipped */
capOUSD       = 0+SUBSTRING(@tmp,521,22)
;

    源数据包含shares字段,该字段在表结构中不存在(已注释);

    name在表结构中定义为VARCHAR(100),而其值在数据文件中只有60个符号。

    每个文件都可能有自己的字段长度 - 因此在导入之前检查这一点(并在需要时进行更正)。

【讨论】:

以上是关于将 SSMS .rpt 文件加载到 MySQL的主要内容,如果未能解决你的问题,请参考以下文章

通过消除重复将数据从文本文件加载到mysql数据库

无法使用 pymysql 将数据文件加载到 MySQL - 找不到文件

将 CSV 文件加载到 MySQL Workbench

将多个 CSV 文件加载到 MYSQL 中的单个表中 [重复]

通过验证将 csv 文件内容加载到 mysql 表中

在 SSMS 中导入平面文件时的小数分隔符