批量更新

时间:2016-07-11 09:04:50

标签: sql-server powershell qsqlquery sql-query-store

我需要使用文本文件更新表。目前我的代码工作正常,如果我从txt文件执行Get-Content然后运行SQL更新查询,但仅在小数据的情况下。如果文本的大小太长或者包含一些特殊字符,则会引发错误,如下所示:

Exception calling "ExecuteReader" with "0" argument(s): "Incorrect syntax near
')</td><td style=\"border:1px solid #cccccc\">#fieldValueEmpty($issue.getCustom
FieldValue($componentTypeCf),'."
At C:\Users\d-mansings\Desktop\Scripted Field Configuration\Script\Prod_UpdateS
cript.ps1:78 char:37
+     $Reader = $Command.ExecuteReader <<<< ()
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

以下是我使用的代码:

Function DatabaseQueries(){
    #To connect to the SQL database
    $Connection = New-Object System.Data.SQLClient.SQLConnection
    $Connection.ConnectionString = "Server=$IPSource ; Database=$DBNameSource ; User ID=$UserIDSource ; Password=$LoginPwdSource;"
    $Connection.Open()

    #Query to get the ID of the stored script field from propertyentry 
    $Command1 = New-Object System.Data.SQLClient.SQLCommand
    $Command1.Connection = $Connection
    $Command1.CommandText = "SELECT [ID]    FROM [dbo].[propertyentry] WHERE [PROPERTY_KEY]='com.onresolve.jira.groovy.groovyrunner:customfields' "
    $Reader = $Command1.ExecuteReader() 
    while ($Reader.Read()) {
        $ID = $Reader.GetValue($1)
    }

    #To get the updated script file
    $ScriptDir = $ParentDir + '\Script.txt'
    $ScriptData = Get-Content "$ScriptDir"
    $Connection.Close()

    #Query to update the Script in JIRA database 
    $Connection.Open()
    $Command = New-Object System.Data.SQLClient.SQLCommand
    $Command.Connection = $Connection
    $Command.CommandText = @"
    Update [dbo].[propertytext] set [propertyvalue] ='$ScriptData' Where ID=$ID
"@
    $Reader = $Command.ExecuteReader()

    $Connection.Close()
}

2 个答案:

答案 0 :(得分:1)

如果未指定文件内容和数据库结构,则很难编写完整的解决方案。你肯定遇到过某种SQL注入。 SQL查询连接被认为是有害的,您应该避免它。使用ADO.NET参数传递变量(示例中为$Command.Parameters.AddWithValue)。请参阅以下示例:

function Invoke-Sql(
    $ConnectionString,
    $Query,
    $Parameters
) {
    $conn = New-Object System.Data.SqlClient.SqlConnection -ArgumentList $ConnectionString
    $cmd = New-Object System.Data.SqlClient.SqlCommand -ArgumentList $Query,$conn
    $conn.Open()
    foreach ($arg in $Parameters.GetEnumerator()){
        $cmd.Parameters.AddWithValue($arg.Key, $arg.Value) | Out-Null;
    }
    $reader = $cmd.ExecuteReader()
    if ($reader.Read()) {
      [string[]]$columns = 0..($reader.FieldCount-1) |
          % { if ($reader.GetName($_)) { $reader.GetName($_) } else { "(no name $_)" } }
      do {
        $obj = @{}
        0..($reader.FieldCount-1) | % { $obj.Add($columns[$_], $reader[$_]) }
        New-Object PSObject -Property $obj
      } while ($reader.Read())
    }
    $reader.Dispose()
    $cmd.Dispose()
    $conn.Dispose()
}

Invoke-Sql `
    -ConnectionString "Server=.\SQL2014;Database=Test1;Integrated Security=true" `
    -Query 'SELECT Name, Id [ObjectId], Id + 3, @arg FROM IdNameTest' `
    -Parameters @{arg = 'Some text'''}
Invoke-Sql `
    -ConnectionString "Server=.\SQL2014;Database=Test1;Integrated Security=true" `
    -Query 'UPDATE IdNameTest SET Name=@name WHERE Id=@id' `
    -Parameters @{name = "'DROP DATABASE Death;! %&@!$"; id=1}

答案 1 :(得分:0)

感谢您的回复,我找到了一种通过使用替换函数来执行查询的方法,因为它在单个引号之间感到困惑

select REPLACE(Cast(propertyvalue AS varchar(Max)), '''', '''''') FROM [dbo].[propertytext] WHERE ID=$ID