"BCP copy in failed" 在 TSV 上

"BCP copy in failed" on TSV

注意:这与我在此处 post 提出的问题 () 非常相似,但我使用不同的解决方案解决了该问题,但在本例中似乎不起作用。 (问题的标题相似,以便任何其他有这些相同模糊错误的人都可以找到解决他们问题的多个潜在解决方案)。


尝试在 linux CentOS7 上使用 BCP utility (https://docs.microsoft.com/en-us/sql/tools/bcp-utility?view=sql-server-2017) 将 tsv 文件复制到远程 MSSQL Server 数据库(在 Windows Server 2012 机器中),获取

令人沮丧的简短错误消息

Starting copy...

BCP copy in failed

有问题的 BCP bash 脚本的格式为

TO_SERVER_ODBCDSN="-D -S MyMSSQLServer"
TO_SERVER_IP="-S 172.99.9.29"
DB="mydb"
TABLE="mytable" 
# getting MSSQL Server credentials
USER=$(tail -n+1 $basedir/src/mssql-creds.txt | head -1)
PASSWORD=$(tail -n+2 $basedir/src/mssql-creds.txt | head -1)
DATAFILES="$storagedir/tsv"
TARGET_GLOB="*.tsv"
RECOMMEDED_IMPORT_MODE='-c' # see 
DELIMITER="\t" # DO NOT use format like "'\t'", nested quotes seem to cause hard-to-catch error

if [[ -z "${TABLE// }" ]]; then
    echo -e "\nNo table specified"
    exit
fi

{
echo -e "Truncating destination table: $DB/$TABLE"
sqlcmd -Q "select count(*) from dbo.$TABLE; truncate table dbo.$TABLE; select count(*) from dbo.$TABLE;" \
    $TO_SERVER_ODBCDSN \
    -U $USER -P $PASSWORD \
    -d $DB
} || { echo -e "\nFailed to truncate MSSQL DB"; exit 255; }

echo -e "\nConnecting with BCP utility as $USER..."

for filename in $DATAFILES/$TARGET_GLOB; do

    if [ ! -f $filename ]; then
        echo -e "\nFile $filename not found!"
    else
        echo -e "\nImporting $filename data to $DB/$TABLE"
    fi

    echo -e "Removing header from TSV file $filename"
    echo "$(tail -n +2 $filename)" > $filename

    echo -e "Replacing null literal values with empty chars"
    NULL_WITH_TAB="null\t" # WARN: assumes the first field is prime-key so never null
    TAB="\t"
    sed -i -e "s/$NULL_WITH_TAB/$TAB/g" $filename

    echo -e "Starting BCP export threads for $filename"
    /opt/mssql-tools/bin/bcp "$TABLE" in "$filename" \
        $TO_SERVER_ODBCDSN \
        -U $USER -P $PASSWORD \
        -d $DB \
        $RECOMMEDED_IMPORT_MODE \
        -t "\t" \
        &

done

(这里提供的不仅仅是一个最小的例子,因为我完全不知道为什么 BCP 程序 仅在某些数据集上失败并在其他数据集上工作 ,因为错误信息非常模糊)并且 运行 这会产生输出

[me@mapr001 src]$ time ./hdfs2mssql.pq.sh mytable

Truncating destination table: mydb/mytable

-----------
          0

(1 rows affected)

-----------
          0

(1 rows affected)

Connecting with BCP utility as myuser...

Importing /mapr/my.cluster.local//etl/path/to/MYTABLE/tsv/0_0_0.tsv data to mydb/mytable
Removing header from TSV file /mapr/uceramapr.cluster.local//etl/path/to/MYTABLE/tsv/0_0_0.tsv
Replacing null literal values with empty chars
Starting BCP export threads for /mapr/uceramapr.cluster.local//etl/path/to/MYTABLE/tsv/0_0_0.tsv

Starting copy...

BCP copy in failed


All export tasks collected and completed

real    0m2.182s
user    0m0.826s
sys 0m0.624s

从这里,它告诉了一些调试信息。

  1. 它告诉我 sqlcmd 能够实际连接到远程数据库(因为能够成功截断并获取计数),即。不太可能是网络连接问题。
  2. 还指出问题(可能)与我在另一个 SO post 中解决的问题不同,关于 BCP 无法对 TSV 文件执行 "in" 操作(), 因为我已经用制表符“\t”替换了文字 'null' 字符串。

尝试通过 awk '{print gsub(/\t/,"")}' /path/to/0_0_0.tsv 检查 TSV 文件中每一行的制表符数量似乎显示所有行都有 149 个制表符。这似乎与远程数据库目标 table 模式中的 149+1=150 columns 相匹配(下面显示的通过 sp_help <tablename> 的模式,如果不好,请见谅格式化):

Column_name Type    Computed    Length  Prec    Scale   Nullable    TrimTrailingBlanks  FixedLenNullInSource    Collation
PROC_ID float   no  8   53      NULL    yes (n/a)   (n/a)   NULL
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    float   no  8   53      NULL    yes (n/a)   (n/a)   NULL
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    smalldatetime   no  4                   yes (n/a)   (n/a)   NULL
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    nvarchar    no  510                 yes (n/a)   (n/a)   SQL_Latin1_General_CP1_CI_AS
xxxx    smalldatetime   no  4                   yes (n/a)   (n/a)   NULL

这是来自 tsv 的模拟样本行

272647  KXXXX,XXXXSR TRNS>10KILO    31999999                                        19999               57              Y   2   9/1/17 XXX,NO VOL X XXX (XXX XXX XXXX)              Y   999                                             1999    2999                            999         3                       1   1                           Y               2012-05-31 17:41:00         1   KXX,PRXXXX T                                                                                    999                                                                                                     XXXT,PRXXXX TXXX>10KILO                                                                                                                     2018-08-21 14:04:57

此处使用制表符转义字符

272647^IKXXXX,XXXXSR TRNS>10KILO^I31999999^I^I^I^I^I^I^I^I^I^I19999^I^I^I^I57^I^I^I^IY^I2^I9/1/17 XXX,NO VOL X XXX (XXX XXX XXXX)^I^I^I^IY^I999^I^I^I^I^I^I^I^I^I^I^I^I1999^I2999^I^I^I^I^I^I^I999^I^I^I3^I^I^I^I^I^I1^I1^I^I^I^I^I^I^IY^I^I^I^I2012-05-31 17:41:00^I^I^I1^IKXX,PRXXXX T^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I999^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^IXXXT,PRXXXX TXXX>10KILO^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I2018-08-21 14:04:57

就提供最小工作示例而言,脚本中的代码为

#!/bin/bash

filename=

# can use ODBC driver...
TO_SERVER_ODBCDSN="-D -S MyMSSQLServer"
# ...or host IP
TO_SERVER_IP="-S <your MSSQL Server IP>"
DB="mydb"
TABLE="mytable"
USER=<your MSSQL Server login>
PASSWORD=<your MSSQL Server login password>
DATAFILES=</path/to/tsv/file(s)>
TARGET_GLOB="*.tsv"
RECOMMEDED_IMPORT_MODE='-c' # see 
DELIMITER="\t" # DO NOT use format like "'\t'", nested quotes seem to cause hard-to-catch error

echo -e "Removing header from TSV file $filename"
echo "$(tail -n +2 $filename)" > $filename
echo "First line of file is now..."    
echo $(head -n 1 $filename)

echo -e "Replacing null literal values with empty chars"
NULL_WITH_TAB="null\t" # WARN: assumes the first field is prime-key so never null
TAB="\t"
sed -i -e "s/$NULL_WITH_TAB/$TAB/g" $filename

echo -e "Starting BCP export threads for $filename"
/opt/mssql-tools/bin/bcp "$TABLE" in "$filename" \
    $TO_SERVER_ODBCDSN \
    -U $USER -P $PASSWORD \
    -d $DB \
    $RECOMMEDED_IMPORT_MODE \
    -t "\t" \

(其中一些值必须由用户提供,因为取决于系统如何设置 MSSQL Server 和 ODBC driver,等等)。但是,无法为此提供示例数据,因为我当前使用的数据很敏感,而且我不知道数据集是什么导致了错误(正如我所说,该脚本似乎适用于某些数据集而不适用于其他数据集) 以便在线生成一些会产生类似错误的模拟数据集。


用不同的 table 和 data-file 尝试这个 命令 工作 并且此时错误消息太简短,无法提供更多调试信息(之前从未使用过 BCP 实用程序)。如果有人有使用此工具的经验,任何调试建议或如何解决此问题将不胜感激。

终于找到了解决方案并且似乎与 BCP 没有什么关系(尽管保留问题标题原样,因为 BCP 是问题曝光的地方,其他人可能会如何找到这个 post) .

TLDR:

TSV 中的日期时间值溢出目标 table 中的目标字段,因为 table 模式需要 smalldate 类型,但在源端我们正在处理数据,就好像我们认为目标可以处理该特定列中的 datetime 类型。

故事寓意:

调试 ETL/数据传输问题时,请务必检查源和目标之间是否存在任何可疑的数据类型冲突

长版:

对导致问题的实际数据集文件使用 binarysearch debugging 方法(例如,使用数据的前半部分,看看会发生什么,后半部分,再试一次等),能够避免 "BCP copy failed" 错误,但随后看到了(即使没有抛出失败消息,也复制了 0 行(所以我真的不知道为什么 "BCP copy failed"不再弹出错误))。将 -e 选项添加到最小示例以在此处获取 bcp 复制尝试的错误日志(例如 -e filename.bcperror.log),看到错误

#@ Row 1, Column 150: Datetime field overflow. Fractional second precision exceeds the scale specified in the parameter binding. @#

在生成的错误文件的每一行的顶部(第 150 列是一行中的最后一列,例如 2018-08-29 11:34:14)。

查看 BCP 试图在 MSSQL Server 中复制到的 table,我注意到(与 BCP 成功写入的 table 不同),最后一个字段(列150) 在我的例子中被设置为 smalldate 类型,而其他 tables 使用 datetime。将此字段也更改为 datetime,BCP 能够毫无问题地将问题 TSV 复制到 table。