Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

powershell - Inserting a date into SQL

I have the following datetime specified:

$dateChanged = Get-Date -Format ("yyyy-MM-dd hh:mm:ss.fff")

I would like to insert this into a SQL datetime field using the following PowerShell:

INSERT INTO myTable (name, dateChanged) VALUES ($name, $dateChanged);

I get the following error:

Exception calling "ExecuteNonQuery" with "0" argument(s): "Incorrect syntax near '11'."

NOTE: The current time here is 11:28.

I have tried reformatting the dateChanged variable to no avail.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can absolutely do SQL in PowerShell by simple string replacement, like the "parameters" you can pass to Invoke-Sqlcmd. I suggest you don't: it leaves you open to injection and you have to take special care to format dates, NULL values, floating-point values, strings... Here's two functions that help you do it the .NET way:

function ConvertFrom-DataReader($datareader) {
    $values = New-Object Object[] $datareader.FieldCount
    $names = New-Object string[] $datareader.FieldCount
    $anyNameEmpty = $false
    for ($i = 0; $i -lt $values.Length; $i++) {
        $names[$i] = $datareader.GetName($i)
        if (-not $names[$i]) { $anyNameEmpty = $true }
    }
    while ($datareader.Read()) {
        $v = $datareader.GetValues($values)
        if ($anyNameEmpty) {
            Write-Output $values
        } else {
            $result = New-Object psobject
            for ($i = 0; $i -lt $v; $i++) {
                Add-Member `
                    -InputObject $result `
                    -MemberType NoteProperty `
                    -Name $names[$i] `
                    -Value $values[$i]
            }
            Write-Output $result
        }
    }
}

function Invoke-SqlCommand(
    [string] $ConnectionString, 
    [string] $CommandText, 
    [hashtable] $Parameters = @{}
) {
    $connection = New-Object System.Data.SqlClient.SqlConnection($ConnectionString)
    try {
        $connection.Open()
        $command = New-Object System.Data.SqlClient.SqlCommand
        $command.Connection = $connection
        $command.CommandText = $commandText
        $command.CommandType = [System.Data.CommandType]::Text
        foreach ($Name in $Parameters.Keys) {
            $command.Parameters.AddWithValue($Name, $Parameters[$Name]) | Out-Null
        }
        ConvertFrom-DataReader $command.ExecuteReader()
    } finally {
        $connection.Close()
    }
}

Sample use:

Invoke-SqlCommand `
    -ConnectionString "Data Source=(localdb)mssqllocaldb" `
    -CommandText "DECLARE @myTable TABLE(name VARCHAR(100), dateChanged DATETIME); 
        INSERT INTO @myTable (name, dateChanged) VALUES (@name, @dateChanged);
        SELECT * FROM @myTable" `
    -Parameters @{
        name = "Winston"
        dateChanged = Get-Date
    }

This is not perfect (you could use proper cmdlets, AddWithValue has issues) and you might consider it overkill for a one-off query, but it's still a much better thing to build on than textual replacement.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...