从CURSOR到基于SET的方法,利用没有ID的临时表?

时间:2015-10-01 17:47:14

标签: sql sql-server tsql

我目前有一个CURSOR循环遍历一个临时表,该表包含数百个各种.txt文件的路径,这些文件需要BULK INSERTPersons表中。临时表也是从没有标识列的单个.txt文件建立的。 FileList.txt文本文件如下所示:

...
E:\Dept1\Type1\2005.txt
E:\Dept1\Type1\2006.txt
E:\Dept1\Type1\2007.txt
E:\Dept2\Type1\2005.txt
E:\Dept2\Type1\2006.txt
...

我正在将FileList.txt加载到一个BULK INSERT的临时表中。鉴于此,临时表中唯一的列是Path列。如果我有一个额外的标识列,BULK INSERT会因列号不匹配而失败。

我想对此进行微调以使用WHILE循环。然而,我已经在如何最好地利用它上面打了一个死脑。使用我见过的WHILE循环的每个解决方案都假定存在顺序标识列。我目前的查询如下:

CREATE TABLE #NAMES_filelist (Path VARCHAR(MAX))
BULK INSERT #NAMES_filelist FROM 'E:\FileList.txt' WITH 
    ( 
    ROWTERMINATOR = '\n'
    )
DECLARE @FILEPATH VARCHAR(MAX)
DECLARE @SQLBULK VARCHAR(MAX)
-- Beginning the cursor to loop through the file list.
DECLARE C1 CURSOR
FOR SELECT Path FROM #NAMES_filelist
OPEN C1
FETCH NEXT FROM C1 INTO @FILEPATH
WHILE
    @@FETCH_STATUS <> -1
    BEGIN
       -- Setting @SQLBULK to do the bulk insert of the index files.
       SET @SQLBULK = 
       -- Utilizing a view due to additional columns in dbo.Persons in comparison to the index file.
       'BULK INSERT Persons_view FROM ''' + @FILEPATH + ''' WITH 
          ( 
           MAXERRORS = 0
          ,FIELDTERMINATOR = ''|''
          ,ROWTERMINATOR = ''\n''
          )'
       EXEC (@SQLBULK)
       -- Updating the DEPT and INDEXFILE columns for lookup purposes.
       UPDATE
          Persons
       SET
          DEPT = REVERSE(SUBSTRING(REVERSE(@FILEPATH), CHARINDEX('\',REVERSE(@FILEPATH)) + 1, CHARINDEX('\',REVERSE(@FILEPATH), CHARINDEX('\',REVERSE(@FILEPATH)) + 1) - CHARINDEX('\',REVERSE(@FILEPATH)) - 1))
          ,INDEXFILE = REVERSE(LEFT(REVERSE(@FILEPATH),CHARINDEX('\', REVERSE(@FILEPATH), 1) - 1))
       WHERE
          DEPT IS NULL
          AND INDEXFILE IS NULL
    FETCH NEXT FROM C1 INTO @FILEPATH
    END
CLOSE C1
DEALLOCATE C1
DROP TABLE #NAMES_filelist

你们有任何新鲜的想法都会非常有用。

1 个答案:

答案 0 :(得分:0)

您可以批量插入视图。所以:

CREATE TABLE NAMES_filelist (
    NAMES_filelist int identity(1, 1) primary key,
    Path VARCHAR(MAX)
);

CREATE VIEW v_NAMES_filelist as
    select NAMES_filelist
    from NAMES_filelist;

BULK INSERT  v_NAMES_filelist FROM 'E:\FileList.txt' WITH (ROWTERMINATOR = '\n');

那就是说,光标是一种很好的方法。但是,这将在文件名表中为您提供自动递增的ID。