2010-12-14 24 views
1

我将从文件中逐行读取的字符数据逐行加载到SQL表中。该表是:通过Powershell将文本加载到SQL Server中

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. 有我制作的正确调用,SQLCMD?
  2. 是否有替代$ xy附近的单引号?
  3. 有没有更好的方法来加载文本?

我想维护db中文本文件和行的一对一关系。

感谢 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 ('$_')"} 

回答

5

您得到格式错误的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)。

+0

+1你回答第一 – 2010-12-14 19:39:25

+0

是的,如果他有SQL 2008年,他就收拾东西于1000点值的行成一个刀片声明。其他选项是创建临时存储过程,如http://code.google.com/p/poshcodegen/ – 2010-12-14 19:46:29

+0

我正在使用SQL 2K8R2。由于数据很短,我不需要比这行更多。 – 2010-12-14 20:07:21

2

您必须在字符串中增加一倍撇号

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

当性能是一个问题,你选择一些bulkcopy solultion。在SQLPSX项目 有一个模块adolib.psm1其中包含一个函数调用,bulkcopy

link text

2

一个更好的解决办法是使用ADO.NET通过SqlCommand.Parameters财产paramaterized查询。这将解决您的单撇号错误以及擦除您的输入可能会创建一个SQL错误的其他任何东西。

不幸的是,Invoke-SqlCmd不允许你这样做。但是,我修改了Chad Miller'sInvoke-SqlCmd2以允许您这样做。包括调用-SqlCmd2.ps1在您的个人资料,并改变你的脚本,像这样:

的foreach($在$ XY XY){调用-SQLCMD -serverInstance本地主机\ SQLEXPRESS -query“插入AA.dbo.PSFileOrder(psfile中)VALUES(@xy)” -SqlParamaters @ { '@xy'= $ XY}}

相关问题