我正在编写代码,每天将数十个中等大小的文本文件导入SQL SERVER。目前,这些都被导入FOXPRO数据库。我正在转换为使用SQL SERVER。我已经完成了所有固定长度的文件,但最后三个数据文件有一个可变长度字段作为每行中的最后一个字段。最后一个字段最长可达32,000字节。在数据库中,我已将其声明为VARCHAR(MAX)。
字段终止符是行终止符,它是换行符。也就是说,该行以单个“0x0a”结束,以标记字段的结尾和行的结尾,而不是两个换行符。
这是我正在使用的SQL:
BULK INSERT
[MyDB].[dbo].[X]
FROM 'C:\temp\eep.dat'
WITH
(
DATAFILETYPE ='CHAR',
FORMATFILE='C:\temp\translate_eep.xml',
ERRORFILE='C:\temp\ERR_eep.TXT',
FIELDTERMINATOR='0X0A',
ROWTERMINATOR='0X0A'
)
GO
Translate_eep.xml如下所示:
<?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="5"/>
<FIELD ID="2" xsi:type="CharFixed" LENGTH="5"/>
<FIELD ID="3" xsi:type="CharFixed" LENGTH="5"/>
<FIELD ID="4" xsi:type="CharTerm" TERMINATOR="0X0A"/>
</RECORD>
<ROW>
<COLUMN SOURCE="1" NAME="c1" xsi:type="SQLCHAR"/>
<COLUMN SOURCE="2" NAME="c2" xsi:type="SQLCHAR"/>
<COLUMN SOURCE="3" NAME="c3" xsi:type="SQLCHAR"/>
<COLUMN SOURCE="4" NAME="c4" xsi:type="SQLCHAR"/>
</ROW>
</BCPFORMAT>
不幸的是,当我使用它时,它导入一行然后终止。如何才能读取整个文件?
示例数据:
ABCDE12345EMILYLove is not all. It is not meat, nor drink, nor slumber<lf>
FGHIJ67890SNL Oh, no! Mr. bill!<lf>
KLMNO24680ALEX All Nature is but art, unknown to thee<lf>
PQRST13579FROSTSome say the world will end in fire,<lf>
答案 0 :(得分:0)
我无法使用BULK INSERT解决此问题。对于最后3个表,那些具有可变长度字段的表,我使用Perl来上传具有存储过程的数据。它看起来像这样:
#!/usr/bin/perl
use strict;
use DBI;
# Open the database
my ($dbh,$sth);
my $db_name="MyDB";
my $db_instance="AMACHINE";
$dbh = DBI->connect("DBI:ODBC:Driver={SQL Server};Server=$db_instance;Database=$db_name;") or die "Unable to connect";
my $sql = "DELETE [MyDB].[dbo].[X]" ;
my $sth = $dbh->prepare($sql);
$sth->execute();
my $sql = "{call MyDB.dbo.Import_X_table(?, ?, ?, ?)}" ;
my $sth = $dbh->prepare($sql);
my $in_datafile = "eep.dat";
open INF, $in_datafile || die "Unable to open file $in_datafile\n";
my $lc = 0; # line counter;
my $buffer;
while ( $buffer = <INF> )
{
$lc++;
my $reference = substr($buffer, 0, 5);
my $code = substr($buffer, 5, 5);
my $name = substr($buffer, 10, 5);
my $narrative = substr($buffer, 15); #everything after character 14
$sth->execute($reference, $code, $name, $narrative);
}
存储过程如下:
USE [MyDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[Import_X_table]
@ent varchar(5),
@cd varchar(5),
@nm varchar(5),
@narr varchar(max)
AS
BEGIN
SET NOCOUNT ON
INSERT INTO [MyDB].[dbo].[X] VALUES (@ent,@cd,@nm, @narr)
END
我不喜欢这个解决方案,但这是我能想到的最快的解决方法。 它通过不妥协地绕过眼前的问题而不是解决它来实现目标。
我不知道我是否应该接受这个问题的“解决方案”。