Вставить в SQL Server дату с помощью Powershell - PullRequest
0 голосов
/ 08 мая 2018

Я использую 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 голосов
/ 08 мая 2018

Конкатенация строк - очень плохая идея. Он не просто открывает ваш код для 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.

Если у вас возникли проблемы с преобразованием строк в $row в datetime, вы можете использовать функцию 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...