将数据导入SQL Server数据库的存储过程...错误

时间:2014-10-07 19:19:50

标签: sql sql-server sql-server-2008 sql-server-2005 sql-server-2012

我有以下格式的文本文件file1.txt。第1列是AGUSR1&第2列是AGUSR2。文件中有3条记录:

"AGUSR1"|"AGUSR2"
"JASON   "|"DEBBIE    "
"JOY   "|"JASON     "
"ANNA   "|"JOHN      "

我编写了一个存储过程来将此文本文件上传到SQL Server数据库中,如下所示:

CREATE PROCEDURE sp_Import
    @TableName varchar(200),
    @FilePath varchar(200)
AS
    DECLARE @SQL varchar(5000)

    SET @SQL = 'BULK INSERT ' + @TableName + ' FROM ''' + @FilePath + 
               ''' WITH (FIELDTERMINATOR = ''|'', ROWTERMINATOR = ''{CR}{LF}'')' 

    EXEC (@SQL)  

为了执行它,我使用了这句话:

EXEC sp_Import '[DB_DEMO].[dbo].[file1]' , '\\kacl1tsp048\DEMO\file1.txt'

注意:kacl1tsp048是输入文本文件所在的远程服务器。

执行时,我收到以下错误 -

  

Msg 4863,Level 16,State 1,Line 1
  第1行第2列(AGUSR2)的批量加载数据转换错误(截断)。

导入到表架构是

CREATE TABLE [dbo].[file1]
(
    [AGUSR1] [varchar](10) NULL, 
    [AGUSR2] [varchar](10) NULL 
)

1 个答案:

答案 0 :(得分:1)

对于ad-hoc样式数据导入,我有时不使用BULK INSERTS,而是选择从文件本身进行处理。您可以通过创建一个以文件形式读取文件的过程来执行类似的操作:

CREATE FUNCTION [dbo].[uftReadfileAsTable]
(
@Path VARCHAR(255),
@Filename VARCHAR(100)
)
RETURNS 
@File TABLE
(
[LineNo] int identity(1,1), 
line varchar(8000)) 

AS
BEGIN

DECLARE  @objFileSystem int
        ,@objTextStream int,
        @objErrorObject int,
        @strErrorMessage Varchar(1000),
        @Command varchar(1000),
        @hr int,
        @String VARCHAR(8000),
        @YesOrNo INT

select @strErrorMessage='opening the File System Object'
EXECUTE @hr = sp_OACreate  'Scripting.FileSystemObject' , @objFileSystem OUT


if @HR=0 Select @objErrorObject=@objFileSystem, @strErrorMessage='Opening file "'+@path+'\'+@filename+'"',@command=@path+'\'+@filename

if @HR=0 execute @hr = sp_OAMethod   @objFileSystem  , 'OpenTextFile'
    , @objTextStream OUT, @command,1,false,0--for reading, FormatASCII

WHILE @hr=0
    BEGIN
    if @HR=0 Select @objErrorObject=@objTextStream, 
        @strErrorMessage='finding out if there is more to read in "'+@filename+'"'
    if @HR=0 execute @hr = sp_OAGetProperty @objTextStream, 'AtEndOfStream', @YesOrNo OUTPUT

    IF @YesOrNo<>0  break
    if @HR=0 Select @objErrorObject=@objTextStream, 
        @strErrorMessage='reading from the output file "'+@filename+'"'
    if @HR=0 execute @hr = sp_OAMethod  @objTextStream, 'Readline', @String OUTPUT
    INSERT INTO @file(line) SELECT @String
    END

if @HR=0 Select @objErrorObject=@objTextStream, 
    @strErrorMessage='closing the output file "'+@filename+'"'
if @HR=0 execute @hr = sp_OAMethod  @objTextStream, 'Close'


if @hr<>0
    begin
    Declare 
        @Source varchar(255),
        @Description Varchar(255),
        @Helpfile Varchar(255),
        @HelpID int

    EXECUTE sp_OAGetErrorInfo  @objErrorObject, 
        @source output,@Description output,@Helpfile output,@HelpID output
    Select @strErrorMessage='Error whilst '
            +coalesce(@strErrorMessage,'doing something')
            +', '+coalesce(@Description,'')
    insert into @File(line) select @strErrorMessage
    end
EXECUTE  sp_OADestroy @objTextStream
    -- Fill the table variable with the rows for your result set

    RETURN 
END

现在你有一个proc来将你的文件转换为一个表。你仍然需要处理分隔符的格式化,这样就可以运行这样的东西来填充[dbo]。[file1]:

;WITH Split_Names (Value,Name, xmlname)
AS
(
    SELECT 
        [LineNo],
        line,
        CONVERT(XML,'<Lines><line>'  
        + REPLACE(line,'"|"', '</line><line>') + '</line></Lines>') AS xmlname
    from [dbo].[uftReadfileAsTable]('\\kacl1tsp048\DEMO\file1.txt')
    where line not like '"AGUSR1"%'
)
 SELECT 
    Value,      
    RTRIM(REPLACE(xmlname.value('/Lines[1]/line[1]','varchar(100)'),'"', '')) AS AGUSR1,    
    RTRIM(REPLACE(xmlname.value('/Lines[1]/line[2]','varchar(100)'),'"', '')) AS AGUSR2
 INTO [dbo].[file1]
 FROM Split_Names

希望有所帮助?!