2012-03-21 3 views
2

У меня есть следующая часть функции, которая сводит меня с ума. Как вы можете видеть, я генерирую путь и имя файла для массового копирования данных таблицы. Когда я запускаю это в сценарии PowerShell, я получаю следующее сообщение об ошибке:Скрипт PowerShell не выполняет команду bcp правильно

C:\Program Files\Microsoft SQL Server\100\Tools\Binn\bcp.exe: unknown option 1 
usage: C:\Program Files\Microsoft SQL Server\100\Tools\Binn\bcp.exe 

Однако, когда я скопировать строку вывода, я получаю от команды Write-хоста и вставить его в командной строке я могу выполнить это просто отлично , Что дает?

ForEach($table in $db.Tables | where {$_.IsSystemObject -eq $false}) 
{ 

     $fullName = "$db.$table" 

     If($scriptTables -contains $fullName) 
     { 
       $fullFilePath = (pwd).path + "\$db.$table" + ".dat" 
       $copyExecString = "$db.$table out `"$fullFilePath`" -E -N -Sserver1\instance -Uxyz -Pxyz > Output.txt" 
       & bcp "$copyExecString" #Invoke-Expression "bcp $copyExecString" 
       Write-host "bcp $copyExecString"      
     } 

} 

Пример вывода:

bcp [DB].[dbo].[Table] out "C:\Development\ScriptDemoData\[DB].[dbo].[Table].dat" -E -N -Sserver1\instance -Uxyz -Pxyz > Output.txt 

ответ

0

Я не знаю, как расширить строку в различные свойства.

Вы могли бы просто передать их напрямую.

.\bcp.exe $db.$table out "$fullFilePath" -E -N -Sserver1\instance -Uxyz -Pxyz > Output.txt 
0

Это связано с выполнением устаревших команд Powershell иногда оператор Invoke (&) будет работать, а иногда и это не будет, особенно если там много аргументы, как в случае с Bcp.exe. Другой способ выполнения устаревших приложений - использовать start-process. Я переработал ваш код и успешно протестировал его.

try {add-type -AssemblyName "Microsoft.SqlServer.ConnectionInfo, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" -EA Stop} 
catch {add-type -AssemblyName "Microsoft.SqlServer.ConnectionInfo"} 

try {add-type -AssemblyName "Microsoft.SqlServer.Smo, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" -EA Stop; $smoVersion = 10} 
catch {add-type -AssemblyName "Microsoft.SqlServer.Smo"; $smoVersion = 9} 

$ServerInstance = "$env:computername\sql1" 
$Database = 'AdventureWorks' 
$server = new-object ("Microsoft.SqlServer.Management.Smo.Server") $ServerInstance 
$db = $server.Databases[$Database] 
$scriptTables = ,'[AdventureWorks].[Sales].[StoreContact]' 

ForEach($table in $db.Tables | where {$_.IsSystemObject -eq $false}) 
{ 

     $fullName = "$db.$table" 

     If($scriptTables -contains $fullName) 
     { 
       $fullFilePath = (pwd).path + "\$db.$table" + ".dat" 
       start-process -NoNewWindow -RedirectStandardOutput output.txt -FilePath bcp -ArgumentList @" 
$db.$table out "$fullFilePath" -E -N -S$ServerInstance -T 
"@ 
     } 

} 
0

Это из-за цитат, я подозреваю.

bcp "$copyexecstring" будет включать ваши параметры в двойные кавычки.

Для упрощения, я бы поставил $ BCP внутри строки, а затем просто использовать Invoke-Expression:.

$copyExecString = "$db.$table out `"$fullFilePath`" -E -N -Sserver1\instance -Uxyz -Pxyz > Output.txt" 
$copyexecstring = "bcp $copyexecstring" 
$return = (Invoke-expression $copyexecstring) | Out-string 
+0

'" 'вызывают переменные, которые будут расширены' ' 'не я не верю, либо передается. на исполняемую функцию (они разделяются ОС) – Guvante

Смежные вопросы