使用Powershell插入SQL Server日期

时间:2018-05-08 16:59:01

标签: sql powershell

我正在使用PowerShell导入.CSV文件,我需要将其内容保存到数据库中。

我正在使用以下代码从.CSV文件中提取信息,并将其放入数据库

foreach($row in $data) {
    $sql = "INSERT INTO Offerings (RATING, PARVALUE, DESCRIPTION, COUPON, MATURITY, DATEDDATE, CALLDATE, FIRSTCOUPON, CUSIP, PRICEYIELD, COM) VALUES( `
    '$(($row.rating).trim())', `
    '$(($row."PAR VALUE").trim())',`
    '$(($row.DESCRIPTION).trim())', `
    '$(($row.COUPON).trim())', `
    '$(($row.MATURITY))', `
    '$(([datetime]$row."DATED DATE"))', `
    '$(($row."CALL DATE").trim())', `
    '$(($row."FIRST COUPON"))', `
    '$(($row.CUSIP).trim())', `
    '$(($row."PRICE/YIELD").trim())',`
    '$(($row.COM).trim())' `
    )"

    $command.CommandText = $sql
    $command.ExecuteNonQuery() | out-null
}

$row.MATURITY / $row."CALL DATE"$row."FIRST COUPON"都是日期(数据库中的列的类型为DATE)。

但是插件将它作为字符串传递,数据库抱怨它无法将字符串转换为DATE。如何将其作为PowerShell命令中的日期传递,以便正确写入数据库(DATE类型)?

谢谢!

1 个答案:

答案 0 :(得分:2)

字符串连接是一个非常糟糕的主意。它不仅仅是为SQL注入打开你的代码,它非常脆弱。

使用参数化查询。假设您正在使用SQL Server:

$sql = "INSERT INTO Offerings (RATING, PARVALUE, DESCRIPTION, COUPON, MATURITY, DATEDDATE, CALLDATE, FIRSTCOUPON, CUSIP, PRICEYIELD, COM) " +
    "VALUES (@RATING, @PARVALUE, @DESCRIPTION, @COUPON, @MATURITY, @DATEDDATE, @CALLDATE, @FIRSTCOUPON, @CUSIP, @PRICEYIELD, @COM)"

$command.CommandText = $sql

# Add your parameters and define their types to match the types in the Offerings table
# The System.Data.SqlDbType type includes all SQL Server data types
# For data type mapping, see https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql-server-data-type-mappings
[void]$command.Parameters.Add('@RATING', [System.Data.SqlDbType]::NVarChar)
[void]$command.Parameters.Add('@PARVALUE', [System.Data.SqlDbType]::NVarChar)
[void]$command.Parameters.Add('@DESCRIPTION', [System.Data.SqlDbType]::NVarChar)
[void]$command.Parameters.Add('@COUPON', [System.Data.SqlDbType]::NVarChar)
[void]$command.Parameters.Add('@MATURITY', [System.Data.SqlDbType]::Date)
[void]$command.Parameters.Add('@DATEDDATE', [System.Data.SqlDbType]::Date)
[void]$command.Parameters.Add('@CALLDATE', [System.Data.SqlDbType]::Date)
[void]$command.Parameters.Add('@FIRSTCOUPON', [System.Data.SqlDbType]::NVarChar)
[void]$command.Parameters.Add('@CUSIP', [System.Data.SqlDbType]::NVarChar)
[void]$command.Parameters.Add('@PRICEYIELD', [System.Data.SqlDbType]::NVarChar)
[void]$command.Parameters.Add('@COM', [System.Data.SqlDbType]::NVarChar)
# I've defaulted to NVARCHAR here, but you should use the appropriate column data type

foreach ($row in $data) {
    # Set the values of each parameter
    $command.Parameters['@RATING'].Value      = $row.rating.trim()
    $command.Parameters['@PARVALUE'].Value    = $row."PAR VALUE".trim()
    $command.Parameters['@DESCRIPTION'].Value = $row.DESCRIPTION.trim()
    $command.Parameters['@COUPON'].Value      = $row.COUPON.trim()
    $command.Parameters['@MATURITY'].Value    = [datetime]$row.MATURITY
    $command.Parameters['@DATEDDATE'].Value   = [datetime]$row."DATED DATE"
    $command.Parameters['@CALLDATE'].Value    = [datetime]$row."CALL DATE"
    $command.Parameters['@FIRSTCOUPON'].Value = $row."FIRST COUPON"
    $command.Parameters['@CUSIP'].Value       = $row.CUSIP.trim()
    $command.Parameters['@PRICEYIELD'].Value  = $row."PRICE/YIELD".trim()
    $command.Parameters['@COM'].Value         = $row.COM.trim()

    [void]$command.ExecuteNonQuery()
}

如果您使用的是与SQL Server不同的RDBMS,则您的代码可能略有不同。

如果您在将$row中的字符串转换为日期时遇到问题,可以使用ParseExact函数:

$command.Parameters['@MATURITY'].Value    = [datetime]::ParseExact($row.MATURITY, 'dd.MM.yyyy', [cultureinfo]::InvariantCulture)

或者您可以使用Get-Date

$command.Parameters['@MATURITY'].Value    = Get-Date $row.MATURITY -Format 'dd.MM.yyyy'

参数化查询的唯一复杂部分是,如果需要在数据库中将值设置为NULL,则参数的值必须为[System.DBNull]::Value,而不是$null