2016-07-11 6 views
0

Мне нужно обновить таблицу с помощью текстового файла. В настоящее время мой код работает нормально, если я выполняю Get-Content из txt-файла, а затем запускаю запрос SQL-запроса, но только в случае небольших данных. Если размер текста слишком длинный или содержит специальные символы, он выдает ошибку следующим образом: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() 
} 
+0

'MySQL' или' SQL-SERVER'? –

+0

Что такое содержимое 'script.txt'? –

+1

Похоже, вы активировали уязвимость [SQL injection] (https://powershellstation.com/2009/09/15/executing-sql-the-right-way-in-powershell/) в своем коде. –

ответ

0

Спасибо за ответ, я придумал способ, чтобы выполнить запрос, только с помощью функции замены, как это было путаться между одиночными кавычками

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

трудно писать полное решение, если содержимое файла и структура базы данных не указаны. Вы наверняка столкнулись с какой-то инъекцией SQL. Конкатенация SQL Query считается вредной, и вам следует избегать ее. Используйте параметры 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 [email protected] WHERE [email protected]' ` 
    -Parameters @{name = "'DROP DATABASE Death;! %&@!$"; id=1} 
Смежные вопросы