Циклический просмотр файлов в папке с помощью хранимой процедуры SQL Server 2005 - PullRequest
0 голосов
/ 15 августа 2011

Подскажите, пожалуйста, как перебрать папку с файлами .txt, получить последний файл и добавить содержимое в таблицу с помощью хранимой процедуры SQL Server 2005 ??

Заранее спасибо.

SateeshChandra.

Ответы [ 4 ]

3 голосов
/ 15 августа 2011

Я бы предположил, что это лучшая работа для SQL CLR или внешних инструментов, таких как приложение командной строки C #. Вы можете сделать это различными способами в SQL, но они изначально небезопасны и потенциально проблематичны. Мой подход обычно xp_cmdshell, если CLR или внешние инструменты не вариант. Сначала нужно включить:

EXEC sp_configure 'show adv', 1;
GO
RECONFIGURE WITH OVERRIDE;
GO
EXEC sp_configure 'xp_cmdshell', 1;
GO
RECONFIGURE WITH OVERRIDE;
GO
EXEC sp_configure 'show adv', 0;
GO
RECONFIGURE WITH OVERRIDE;
GO

Тогда вы можете сделать что-то вроде этого:

SET NOCOUNT ON;

DECLARE
    @folder NVARCHAR(2048),
    @cmd NVARCHAR(MAX);

SET @folder = N'C:\path\';

SET @cmd = N'dir ' + @folder + '*.txt';

CREATE TABLE #x(n NVARCHAR(2048));

INSERT #x EXEC [master].dbo.xp_cmdshell @cmd;

DECLARE @filename NVARCHAR(2048);

;WITH x(n) AS (SELECT n FROM #x WHERE ISDATE(LEFT(n, 20)) = 1)
    SELECT TOP 1 @filename = n FROM x
    ORDER BY CONVERT(DATETIME, LEFT(n, 20)) DESC;

SET @cmd = N'type ' + @folder + SUBSTRING(@filename,
        LEN(@filename) - CHARINDEX(' ', REVERSE(@filename)) + 2,
        2048);

CREATE TABLE #y(n NVARCHAR(MAX));

INSERT #y EXEC [master].dbo.xp_cmdshell

-- no idea what "add the content into the table" means
-- but you can work with this:
SELECT n FROM #y;

DROP TABLE #x, #y;

Примечание 1: Ширина информации о дате в столбце # x.n будет варьироваться в зависимости от ваших региональных настроек / языка. Возможно, вам придется поэкспериментировать.

Примечание 2: Определение имени файла предполагает, что в именах файлов нет пробелов. Если они это сделают, то потребуется пересмотреть хотя бы одну строку выше.

1 голос
/ 15 августа 2011

В этом посте блога есть удобный udf, который вы могли бы адаптировать .Я собираюсь опубликовать содержимое сценария и использования в случае, если сайт ниже умирает:

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

Использование:

Select line from
 Dbo.uftReadfileAsTable('MyPath','MyFileName')
where line not like '#%'

Просто введите имя существующего файла и путь кфайл, который вы хотите прочитать, а не «MyPath» и «MyFileName», и все готово.

(Примечание: я включил исходный источник, потому что за него проголосовали, потому что ссылка на решение длядругой вопрос умер: ()

0 голосов
/ 14 августа 2015

Я знаю, что это очень старый пост, но я обнаружил, что решение по следующей ссылке отлично работает для меня: http://www.databaseskill.com/2219220/

0 голосов
/ 15 августа 2011

Моей первой мыслью было, что это идеальный кандидат для SSIS - за исключением того, что SSIS имеет довольно крутой курс обучения, если вы новичок в этом

TSQL Solution - пара отличных статей для начала:

http://www.mssqltips.com/tip.asp?tip=1263

http://www.simple -talk.com / SQL / T-SQL-программирования / чтения-и-письменные файлы-в-SQL-сервер, используя-T-SQL /

Решение SSIS: - одна статья, с которой можно начать:

http://www.sqlis.com/post/Looping-over-files-with-the-Foreach-Loop.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...