My helper function for executing a DMV query:
Function DMV_Query($DMV_Query) {
## Prepare the connection string based on information provided
$connectionString = "Provider=msolap;Data Source=$AS_Server;Initial Catalog=$CUBE;"
## Connect to the data source and open
$connection = New-Object System.Data.OleDb.OleDbConnection $connectionString
$command = New-Object System.Data.OleDb.OleDbCommand
$command.Connection = $connection
$command.CommandText = $DMV_Query
$connection.Open()
## Fetch the results, and close the connection
$adapter = New-Object System.Data.OleDb.OleDbDataAdapter #$command
$adapter.SelectCommand = $command
$dataset = New-Object System.Data.DataSet
[void] $adapter.Fill($dataSet)
$connection.Close()
## Return all of the rows from their query
$dataSet.Tables[0]
}
Sample call:
$dmvResult = DMV_Query 'SELECT [SESSION_ID], [SESSION_SPID]
FROM $SYSTEM.DISCOVER_SESSIONS'
$dmvResult
Sample of the content stored in $dmvResult
:
PS> $dmvResult | ConvertTo-Csv
"SESSION_ID","SESSION_SPID"
"D0kl8975r6df65","5567"
"fghu5r67f65","2234"
I want to select all columns from the $dmvResult
variable and insert them into a SQL table. Is this the way I can select from a variable?
# Doesn't work.
INSERT INTO [dbo].[Table]
SELECT * FROM @dmvResult
Note: The answer below may be of interest as an exercise in advanced string interpolation in PowerShell, but given that $dmvResult
contains the rows of an existing DataTable
object returned form a previous query, using a bulk-copy operation is simpler and far more efficient, as discovered by Cataster themselves: see this post.
It looks like you're trying to create a T-SQL statement by constructing a string in PowerShell that incorporates the result of a previous query, $dmvResult
.
Since T-SQL knows nothing about PowerShell variables, you need to explicitly incorporate all values to pass to your INSERT INTO
statement in the statement string.
Here's an example, based on your sample data, using PowerShell's powerful expandable strings (string interpolation; for background, see this answer):
# Sample query result / imported CSV.
$dmvResult =
[pscustomobject] @{ SESSION_ID = 'D0kl8975r6df65'; SESSION_SPID = 5567 },
[pscustomobject] @{ SESSION_ID = 'fghu5r67f65'; SESSION_SPID = 2234 }
# Construct the INSERT INTO statement from $dmvResult, using an expandable
# string ("..." with $variable and $(<command> references))
$insertStatement = @"
INSERT INTO [dbo].[Table]
($($dmvResult[0].psobject.properties.name -join ', '))
VALUES
$(
@(foreach ($obj in $dmvResult) {
$values = foreach ($value in $obj.psobject.properties.value) {
if ($value -is [string]) { "`"$value`"" } else { $value }
}
'(' + ($values -join ', ') + ')'
}) -join ",`n "
)
"@
# Output the constructed statement string.
$insertStatement
Note that the stringification of the property values may need to be made more sophisticated, depending on your data; the code above distinguishes just between strings and non-strings: the former are stringified with enclosing "..."
, the latter as-is.
The above yields:
INSERT INTO [dbo].[Table]
(SESSION_ID, SESSION_SPID)
VALUES
("D0kl8975r6df65", 5567),
("fghu5r67f65", 2234)