Загрузка текста в SQL Server через Powershell - PullRequest
1 голос
/ 14 декабря 2010

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

CREATE TABLE [dbo].[PSFileOrder](
    [PSFOrder_Id] [int] IDENTITY(0,1) NOT NULL,
    [PSFile] [varchar](255) NOT NULL,
 CONSTRAINT [PK_PSFileOrder] PRIMARY KEY CLUSTERED 
(
    [PSFOrder_Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

Код powershell, который я использую:

#LoadPSFile
$PSFile = "d:\ps\xx.ps1"
cls
$xy = Get-content $PSFile
$xy
foreach($xy in $xy) {invoke-sqlcmd -serverInstance localhost\sqlexpress -query "Insert AA.dbo.PSFileOrder(PSFile) Values ('$xy')"}

Если загружаемый файл:

#Filename
#The first line will always be the file name
cls
$filter = "*.*"
$folder = "\\localhost\d$\Master\men and their toys"
$filecount = (Get-ChildItem -literalpath $folder -filter $filter).Countem -literalpath $folder -filter $filter).Countem -literalpath $folder -filter $filter).Countem -literalpath $folder -filter $filter).Count
If ($filecount -lt 1) {$filecount = 0}
"There are {0} files in the {1} directory" -f $filecount, $folder

файл загружается без ошибок. Если в тексте есть одинарная кавычка

"There are {0} files in the {1} d'irectory" -f $filecount, $folder

тогда я получу эту ошибку

Invoke-Sqlcmd : Incorrect syntax near 'irectory'.
Unclosed quotation mark after the character string ' -f $filecount, $folder')
;'.
At C:\Users\RC\AppData\Local\Temp\2ed13f21-5b46-4df4-a5ee-2488c3dd5ee4.ps1:6 char:35
+ foreach($xy in $xy) {invoke-sqlcmd <<<<  -serverInstance localhost\sqlexpress -query "Insert AA.dbo.PSFileOrder(PSFile) Values ('$xy')"}
    + CategoryInfo          : InvalidOperation: (:) [Invoke-Sqlcmd], SqlPowerShellSqlExecutionException
    + FullyQualifiedErrorId : SqlError,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand

Я верю, что ошибка вызвана тем, как я написал оператор "-query", используя одинарные кавычки вокруг переменной $ xy.
Мои вопросы:

  1. Правильно ли я создал Invoke-sqlcmd?
  2. Есть ли замена для одинарной кавычки около $ xy?
  3. Есть ли лучший способ загрузить текст?

Я хочу сохранить однозначное отношение текстового файла и строки в БД.

Спасибо RC

Два ответа указывают мне правильный путь удвоения одинарных кавычек перед загрузкой в ​​SQL. Пересмотренный код

#LoadPSFile
cls
Get-content "d:\ps\xx.ps1" | 
Foreach-Object {$_ -replace "'", "''"} |
ForEach-Object{invoke-sqlcmd -serverInstance localhost\sqlexpress -query "Insert AA.dbo.PSFileOrder(PSFile) Values ('$_')"}

Ответы [ 3 ]

5 голосов
/ 14 декабря 2010

Вы получаете искаженный синтаксис SQL.Я считаю, что быстрое решение состоит в том, чтобы заменить любую одинарную кавычку двумя одинарными кавычками в $xy:

$escaped = $xy.Replace("'", "''")
invoke-sqlcmd -serverInstance localhost\sqlexpress -query "Insert AA.dbo.PSFileOrder(PSFile) Values ('$escaped')"

# or (the same but without the intermediate variable):

invoke-sqlcmd -serverInstance localhost\sqlexpress -query @"
Insert AA.dbo.PSFileOrder(PSFile) Values ('$($xy.Replace("'", "''"))')
"@

Но, возможно, это не лучший способ.К сожалению, я не знаком с возможностями invoke-sqlcmd.Если бы он поддерживал параметризованные запросы, я бы пошел по этому пути и поставил бы значение $xy в том виде, как оно есть в качестве значения параметра (в этом случае подготовка $xy не потребуется).

2 голосов
/ 10 сентября 2011

Лучшим решением было бы использование параметризованных запросов ADO.NET через свойство SqlCommand.Parameters . Это решит вашу единственную ошибку апостроф, а также очистит ваш ввод от всего, что может создать ошибку sql.

К сожалению, Invoke-SqlCmd не позволяет вам сделать это. Однако я изменил Chad Miller Invoke-SqlCmd2 , чтобы позволить вам сделать это. Включите Invoke-SqlCmd2.ps1 в свой профиль и измените ваш скрипт следующим образом:

foreach ($ xy in $ xy) {invoke-sqlcmd -serverInstance localhost \ sqlexpress -query "Вставить значения AA.dbo.PSFileOrder (PSFile) (@xy)" -SqlParamaters @ {'@xy' = $ xy} }

2 голосов
/ 14 декабря 2010

Вы должны удвоить апострофы внутри строки

foreach($xy in $xy) 
{
    $xy = $xy -replace "'", "''"
    invoke-sqlcmd -serverInstance localhost\sqlexpress -query "Insert AA.dbo.PSFileOrder(PSFile) Values ('$xy')"
}

когда производительность является проблемой, вы выбираете решение для массового копирования. В проекте SQLPSX есть модуль adolib.psm1, который содержит функцию invoke-bulkcopy

текст ссылки

...