繁体   English   中英

SQL Server BULK INSERT - 插入DateTime值

[英]SQL Server BULK INSERT - Inserting DateTime values

我有600万行数据要插入到我的SQL Server数据库中。 我可以用600万INSERT语句(通过我的计算运行需要18个小时)来缓慢地进行,或者我可以尝试BULK INSERT。

BULK INSERT存在无法转义字符的问题,但这种情况下的数据非常简单,所以不应该遇到这个问题。

但是,SQL Server似乎不喜欢将任何形式的日期/时间数据插入到字段中。

这是表(psuedo-SQL)

CREATE TABLE Tasks (
    TaskId bigint NOT NULL IDENTITY(1,1) PRIMARY KEY,
    TriggerId bigint NOT NULL FOREIGN KEY,
    Created datetime NOT NULL,
    Modified datetime NOT NULL,
    ScheduledFor datetime NULL,
    LastRan datetime NULL,
    -- and about 10 more fields after this
)

这是我的BULK INSERT声明:

SET DATEFORMAT dmy
BULK INSERT Tasks
FROM 'C:\TasksBulk.dat'
WITH (
    -- CHECK_CONSTRAINTS is not necessary as the only constraints are always enforced regardless of this option (UNIQUE, PRIMARY KEY, and NOT NULL)
    CODEPAGE = 'RAW',
    DATAFILETYPE = 'native',

    KEEPIDENTITY,
    MAXERRORS = 1,
    ORDER ( CallId ASC ),

    FIELDTERMINATOR = '\t',
    ROWTERMINATOR   = '\0'
)

这是TasksBulk.dat中的第一行数据:

1000\t1092\t01/01/2010 04:00:17\t01/01/2010 04:00:17\t\t01/01/2010 04:00:14\0

(为了便于阅读,重新格式化了用4个空格替换的制表符:)

1000    1092    01/01/2010 04:00:17    01/01/2010 04:00:17        01/01/2010 04:00:14\0

但是,当我运行BULK INSERT语句时,我收到此错误:

消息4864,级别16,状态1,行2第1行第3列(已创建)的批量装入数据转换错误(指定代码页的类型不匹配或无效字符)。

我尝试使用不同的行和字段终止符以及每种不同的日期/时间格式(包括“01/01/2010”,“2010-01-01”,有和没有“04:00:17”时间组件)。 我不知道我在这里做错了什么。

事实证明,将DATAFILETYPE从“native”更改为“char”解决了这个问题。 “native”类型意味着一切都是严格的数据格式,而“char”意味着更多的纯文本文件。

您将CODDEPAGE设置为RAW (可能是为了速度)。

错误消息表示您的数据包含代码页外的字符。

 CODEPAGE [ = 'ACP' | 'OEM' | 'RAW' | 'code_page' ] 

指定数据文件中数据的代码页。 仅当数据包含字符值大于127或小于32的char,varchar或text列时,CODEPAGE才相关。

但这可能会产生误导 您的示例数据行包含缺少的列。 如果不使用格式文件,则必须使用表中的每个字段。

因此,您可以创建格式文件或使用varchar(25)为日期时间列创建临时表,导入然后从登台表执行更新到目标表。 这样您就可以更好地控制转化和丢失数据。

我熟悉的方法是以整数的形式插入日期。

我使用从某个日期开始的秒数(过去使用10年以上的一个,因为我没有访问任何数据或者生成的数据比那个旧)

使用2000年1月1日的参考点,2012-01-02 12:15:10.000的日期将存储为378637886。

查询数据库时,可以使用DateAdd (SS,column_name,'2000-01-01')返回列。

如果需要那种精度,你也可以在几毫秒内完成。

我使用自己的自定义函数将我的时间转换成我想要的任何格式,并使用另一个自定义函数将日期转换回秒。

我意识到这可能不是一个好方法,因为它可能需要对您进行数据库更改和代码更改,但也许它可能是其他人认为有用的解决方案概念。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM