Inserting a date into SQL

前端 未结 1 696
陌清茗
陌清茗 2020-12-20 09:18

I have the following datetime specified:

$dateChanged = Get-Date -Format (\"yyyy-MM-dd hh:mm:ss.fff\")
1条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-20 09:51

    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.

    0 讨论(0)
提交回复
热议问题