防止单引号破坏sql命令

时间:2018-03-29 19:27:26

标签: sql-server powershell

我有一个powershell模块,它可以从多个变量中构建一个字符串,以便插入到sql server中。

$QueryInsert =
"
insert into dbo.Table
(
    data
)
values
(
    '$data'
)
"

Invoke-Sqlcmd -ServerInstance 'server_name' `
        -Database db_name `
        -Query $QueryInsert `
        -QueryTimeout 20 `
        -OutputSqlErrors $True `
        -ConnectionTimeout 5 `
        -ErrorAction Continue

这种方法的问题在于它不是特别安全,如果变量$ data包含任何单引号,则会失败。有办法防止这种情况吗?是否有一种方法可以使其保持安全?

1 个答案:

答案 0 :(得分:4)

如果您有权访问数据库,则可以将查询编写为存储过程,然后使用PowerShell调用存储过程。您可以以安全的方式将参数传递给存储过程,这样就不会像上面的代码一样通过字符串注入代码。

您可能需要查看this question以了解如何编写存储过程以及this one.

为了从PowerShell调用SPROC,您可以使用与此类似的代码。

    $sql='NameOfSprocBeingCalled'
    $sqlConnection = new-object System.Data.SqlClient.SqlConnection
    $sqlConnection.ConnectionString = $SqlConnectionString
    $sqlConnection.Open()

    $sqlCommand = new-object System.Data.SqlClient.SqlCommand
    $sqlCommand.Connection = $sqlConnection
    $sqlCommand.CommandText= $sql
    $sqlCommand.CommandType = [System.Data.CommandType]::StoredProcedure
    $sqlCommand.Parameters.Add("@Param1",[system.data.SqlDbType]::VarChar).value =$Param1
    $sqlCommand.Parameters.Add("@Param2",[system.data.SqlDbType]::VarChar).value =  $EventType


    $Datatable = New-Object System.Data.DataTable
    $DataReader = $sqlCommand.ExecuteReader()
    $Datatable.Load($DataReader)

    $sqlConnection.Close()

您只需确保使用[System.Data.SqlDbType] ::

传递参数的正确类型

这是一个包含以下类型的枚举:

# [enum]::GetValues([System.Data.SqlDbType])
BigInt
Binary
Bit
Char
DateTime
Decimal
Float
Image
Int
Money
NChar
NText
NVarChar
Real
UniqueIdentifier
SmallDateTime
SmallInt
SmallMoney
Text
Timestamp
TinyInt
VarBinary
VarChar
Variant
Xml
Udt
Structured
Date
Time
DateTime2