Как выполнить массовый импорт многих документов Word в таблицу базы данных SQL Server - PullRequest
0 голосов
/ 03 октября 2019

Мне нужно импортировать ~ 50 000 документов Word (.doc и .docx) из одного каталога в таблицу базы данных SQL Server 2016, чтобы я мог использовать полнотекстовую индексацию и затем искать содержимое документов.

Поскольку это одноразовая задача, и база данных не потребуется долго, меня не интересует производительность или аргументы в пользу использования FILESTREAM или FileTables.

Я только что создал базу данных с одной таблицей:

CREATE TABLE [dbo].[MyDocument]
(
    [ID] INT IDENTITY(1,1) NOT NULL,
    [DocumentName] NVARCHAR(255) NOT NULL,
    [Extension] NCHAR(10) NOT NULL,
    [DocumentContent] VARBINARY(MAX) NOT NULL,
    CONSTRAINT [PK_MyDocument] PRIMARY KEY CLUSTERED ([ID] ASC)
)

Теперь я ищу способ поместить мои документы в таблицу. В Интернете есть множество примеров импорта отдельного документа в таблицу базы данных SQL Server с использованием OPENROWSET, но они требуют от меня указать имя файла, что, очевидно, бесполезно для моих требований.

IЯ не могу поверить, что нет хорошо документированного и простого способа сделать это, но несколько часов поиска ничего не дали, и это заставляет меня сомневаться, что это даже возможно, но, конечно, это так?

Кто-нибудь может привести пример фрагмента T-SQL для импорта нескольких файлов в базу данных? Или предложить, как еще этого можно достичь?

1 Ответ

1 голос
/ 03 октября 2019

Ниже приведен сценарий PowerShell для импорта всех файлов «.docx» в указанной папке с помощью параметризованного запроса вместе со значением параметра FileStream для потоковой передачи содержимого файла в базу данных вместо загрузки всего содержимого файла в память клиента.

# import all documents in specified directory using file stream parameter
try {

    $timer = [System.Diagnostics.Stopwatch]::StartNew()
    $insertQuery = @"
    INSERT INTO dbo.MyDocument (DocumentName, Extension, DocumentContent)
        VALUES(@DocumentName, @Extension, @DocumentContent);
"@
    $connection = New-Object System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=YourDatabase;Integrated Security=SSPI")
    $command = New-Object System.Data.SqlClient.SqlCommand($insertQuery, $connection)
    $documentNameParameter = $command.Parameters.Add("@DocumentName", [System.Data.SqlDbType]::NVarChar, 255)
    $documentExtensionParameter = $command.Parameters.Add("@Extension", [System.Data.SqlDbType]::NVarChar, 10)
    $documentContentParameter = $command.Parameters.Add("@DocumentContent", [System.Data.SqlDbType]::VarBinary, -1)
    $connection.Open()

    $filesToImport = Get-ChildItem "E:\DocumentsToImport\*.docx"
    $importedFileCount = 0
    foreach($fileToImport in $filesToImport) {
        $documentContentStream = [System.IO.File]::Open($fileToImport.FullName, [System.IO.FileMode]::Open)
        $documentNameParameter.Value = [System.IO.Path]::GetFileNameWithoutExtension($fileToImport.FullName)
        $documentExtensionParameter.Value = [System.IO.Path]::GetExtension($fileToImport.Name)
        $documentContentParameter.Value = $documentContentStream
        [void]$command.ExecuteNonQuery()
        $documentContentStream.Close()
        $importedFileCount += 1
    }
    $connection.Close()

    $timer.Stop()

    Write-Host "$importedFileCount files imported. Duration $($timer.Elapsed)."
}
catch {
    throw
}
...