定长数据文件,BULK INSERT前预览结果

Fixed length datafile, preview the result before BULK INSERT

我正在尝试批量插入几个固定长度的数据文件。我已经创建了数据库 tables 和格式文件。然后我尝试以下操作。例如我有一个这样的格式文件:

<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <RECORD>
        <FIELD ID="1" xsi:type="CharFixed" LENGTH="4"/>
        <FIELD ID="2" xsi:type="CharFixed" LENGTH="1"/>
        <FIELD ID="3" xsi:type="CharFixed" LENGTH="20"/>
        <FIELD ID="4" xsi:type="CharFixed" LENGTH="50"/>
        <FIELD ID="5" xsi:type="CharFixed" LENGTH="8"/>
        <FIELD ID="6" xsi:type="CharFixed" LENGTH="4"/>
        <FIELD ID="7" xsi:type="CharFixed" LENGTH="8"/>
        <FIELD ID="8" xsi:type="CharFixed" LENGTH="8"/>
        <FIELD ID="9" xsi:type="CharFixed" LENGTH="8"/>
        <FIELD ID="10" xsi:type="CharFixed" LENGTH="1"/>
        <FIELD ID="11" xsi:type="CharFixed" LENGTH="8"/>
        <FIELD ID="12" xsi:type="CharFixed" LENGTH="8"/>
        <FIELD ID="13" xsi:type="CharFixed" LENGTH="8"/>
        <FIELD ID="14" xsi:type="CharFixed" LENGTH="8"/>
        <FIELD ID="15" xsi:type="CharFixed" LENGTH="8"/>
    </RECORD>
    <ROW>
        <COLUMN SOURCE="1" NAME="BSTNUM" xsi:type="SQLCHAR" LENGTH="4"/>
        <COLUMN SOURCE="2" NAME="MUTKOD" xsi:type="SQLCHAR" LENGTH="1"/>
        <COLUMN SOURCE="3" NAME="MDBST" xsi:type="SQLCHAR" LENGTH="20"/>
        <COLUMN SOURCE="4" NAME="MDOBST" xsi:type="SQLCHAR" LENGTH="50"/>
        <COLUMN SOURCE="5" NAME="MDBCOD" xsi:type="SQLCHAR" LENGTH="8"/>
        <COLUMN SOURCE="6" NAME="MDRECL" xsi:type="SQLCHAR" LENGTH="4"/>
        <COLUMN SOURCE="7" NAME="MDDATI" xsi:type="SQLCHAR" LENGTH="8"/>
        <COLUMN SOURCE="8" NAME="MDDATW" xsi:type="SQLCHAR" LENGTH="8"/>
        <COLUMN SOURCE="9" NAME="MDDATU" xsi:type="SQLCHAR" LENGTH="8"/>
        <COLUMN SOURCE="10" NAME="MDSTAT" xsi:type="SQLCHAR" LENGTH="1"/>
        <COLUMN SOURCE="11" NAME="MDANM0" xsi:type="SQLCHAR" LENGTH="8"/>
        <COLUMN SOURCE="12" NAME="MDANM1" xsi:type="SQLCHAR" LENGTH="8"/>
        <COLUMN SOURCE="13" NAME="MDANM2" xsi:type="SQLCHAR" LENGTH="8"/>
        <COLUMN SOURCE="14" NAME="MDANM3" xsi:type="SQLCHAR" LENGTH="8"/>
        <COLUMN SOURCE="15" NAME="MDANTL" xsi:type="SQLCHAR" LENGTH="8"/>
    </ROW>
</BCPFORMAT>

然后在 SQL Server 2008 命令提示符下我试试这个:

BULK INSERT
    BST012018_testtable
from
    'D:\testimport\BST012018T.txt'
WITH (
    FORMATFILE='D:\testimport\BST012018T_format.xml',
    ROWS_PER_BATCH = 1000,
    KEEPNULLS
)

并收到一条错误消息:

The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.

错误可能在数据文件、定长格式文件或数据库table中的datatype/columns。换句话说,要使这三件事(table、数据文件、格式​​文件)必须完全对齐。

我正在处理的数据集有更多这样的文件,其中一些有 50 多列和 >100.000 条记录。所以找出错误发生的地方需要调整格式文件,也许调整tables,试错等

所以我的问题是,是否可以通过某种方式预览 BULK INSERT?从固定长度的数据+格式文件中执行 SELECT 而不是直接插入?或者换句话说,我如何以 SQL 服务器从此类 BULK INSERT 命令解释它的方式预览数据?

我只想回答我自己的问题。感谢 Jeroen Mostert 的评论,我一直在寻找从数据文件中使用 OPENROWSET(BULK.. 到 select 的方法。

您可以select TOP 10 或类似的东西来只查看前几条记录并检查是否有任何错误。顺便说一句,数据文件和格式文件必须放在服务器上的一个文件夹中,SQL服务器不能只读取你的本地电脑。

SELECT
    TOP 5 *
FROM 
    OPENROWSET(
        BULK 'D:\testimport\BST012018T.txt',
        FORMATFILE = 'D:\testimport\BST012018T_format.xml'
        --,CODEPAGE = '65001' -- 65001 = UTF-8 supported in SQL Server 2016
    ) AS a

看到这样生成的数据集的预览,我发现格式文件末尾缺少一列,而且格式文件中也没有行终止符(在我的例子中是 Cr Lf)。在 RECORD 部分,我添加了一个类型为 "CharTerm" 且属性为 TERMINATOR 的最后一个字段,因此如下所示:

<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <RECORD>
        <FIELD ID="1" xsi:type="CharFixed" LENGTH="4"/>
        <FIELD ID="2" xsi:type="CharFixed" LENGTH="1"/>
        <FIELD ID="3" xsi:type="CharFixed" LENGTH="20"/>
        <FIELD ID="4" xsi:type="CharFixed" LENGTH="50"/>
        <FIELD ID="5" xsi:type="CharFixed" LENGTH="8"/>
        <FIELD ID="6" xsi:type="CharFixed" LENGTH="4"/>
        <FIELD ID="7" xsi:type="CharFixed" LENGTH="8"/>
        <FIELD ID="8" xsi:type="CharFixed" LENGTH="8"/>
        <FIELD ID="9" xsi:type="CharFixed" LENGTH="8"/>
        <FIELD ID="10" xsi:type="CharFixed" LENGTH="1"/>
        <FIELD ID="11" xsi:type="CharFixed" LENGTH="8"/>
        <FIELD ID="12" xsi:type="CharFixed" LENGTH="8"/>
        <FIELD ID="13" xsi:type="CharFixed" LENGTH="8"/>
        <FIELD ID="14" xsi:type="CharFixed" LENGTH="8"/>
        <FIELD ID="15" xsi:type="CharFixed" LENGTH="8"/>
        <FIELD ID="16" xsi:type="CharFixed" LENGTH="8"/>
        <FIELD ID="17" xsi:type="CharTerm" TERMINATOR="\r\n"/>
    </RECORD>
    <ROW>
        <COLUMN SOURCE="1" NAME="BSTNUM" xsi:type="SQLCHAR"/>
        <COLUMN SOURCE="2" NAME="MUTKOD" xsi:type="SQLCHAR"/>
        <COLUMN SOURCE="3" NAME="MDBST" xsi:type="SQLCHAR"/>
        <COLUMN SOURCE="4" NAME="MDOBST" xsi:type="SQLCHAR"/>
        <COLUMN SOURCE="5" NAME="MDBCOD" xsi:type="SQLCHAR"/>
        <COLUMN SOURCE="6" NAME="MDRECL" xsi:type="SQLCHAR"/>
        <COLUMN SOURCE="7" NAME="MDDATI" xsi:type="SQLCHAR"/>
        <COLUMN SOURCE="8" NAME="MDDATW" xsi:type="SQLCHAR"/>
        <COLUMN SOURCE="9" NAME="MDDATU" xsi:type="SQLCHAR"/>
        <COLUMN SOURCE="10" NAME="MDSTAT" xsi:type="SQLCHAR"/>
        <COLUMN SOURCE="11" NAME="MDANM0" xsi:type="SQLCHAR"/>
        <COLUMN SOURCE="12" NAME="MDANM1" xsi:type="SQLCHAR"/>
        <COLUMN SOURCE="13" NAME="MDANM2" xsi:type="SQLCHAR"/>
        <COLUMN SOURCE="14" NAME="MDANM3" xsi:type="SQLCHAR"/>
        <COLUMN SOURCE="15" NAME="MDANTL" xsi:type="SQLCHAR"/>
        <COLUMN SOURCE="16" NAME="EMPTY" xsi:type="SQLCHAR"/>
    </ROW>
</BCPFORMAT>