Powershell Invoke-Sqlcmd Use result in another query - powershell

I'm attempting to use a result returned from Invoke-Sqlcmd $ORDUNIQ as a variable in a second query. However the second $query2 returns 0 records. Substituting the variable for the actual string value '35973189' works fine.
I'm assuming that $ORDUNIQ.ORDUNIQ is the wrong way to use this?, although running $ORDUNIQ.ORDUNIQ on the command line does return '35973189' correctly
Here is my code
$RAWFiles = Get-ChildItem D:\Imports\Test\*.csv
$content = Import-Csv $RAWFiles | Where-Object 'Order Type' -eq 'B2B'
ForEach ($row in $content) {
$ORDNUMBER = $row.'OrderRef'
$SQLServer = "XXXXX-XXX"
$db1 = "XXXXXX"
$query1 = "SELECT ORDUNIQ FROM OEORDH WHERE ORDNUMBER = '$ORDNUMBER'"
$query2 = "SELECT OEORDD.ITEM FROM OEORDD WHERE ORDUNIQ = '$ORDUNIQ.ORDUNIQ'"
$ORDUNIQ = Invoke-Sqlcmd -ServerInstance $SQLServer -Database $db1 -Query $query1
$ORDDATA = Invoke-SQLcmd -ServerInstance $SQLServer -Database $db1 -Query $query2
}

Related

Passing a single value from a SQL query to a PowerShell variable

I am trying to a single value from a SQL query to a PowerShell variable. I know the connection and query are running successfully because I am getting the output I expected when using Invoke-DbaQuery or Invoke-Sqlcmd. But when I try to assign the query results to a variable, all I see is System.Data.DataRow
Any suggestions on how to get this query's results assigned to a variable?
$SQLInstance = "SQLInstance"
$Database = "DatabaseName"
$Query = "SELECT TOP (1) Password FROM dbo.Connections WHERE VendorName = 'YYY' ORDER BY VendorName;"
#Invoke-DbaQuery -SqlInstance $SQLInstance -Database $Database -Query $Query
#$password = (Invoke-DbaQuery -SqlInstance $SQLInstance -Database $Database -Query $Query)
$password = Invoke-Sqlcmd -ServerInstance $SQLInstance -Database $Database -Query $Query
Write-Host $password
You've seen that $password is a [DataRow], and Write-Host can only use [string]. Try one of these two:
Output the result by itself (no write-host). Powershell will format all of the fields and rows for you:
$password
# outputs:
password
--------
hunter2
Output just the string from your query result instead of the table format above:
$password.Password
# Outputs:
hunter2
DataRow objects are made to contain multiple rows and multiple fields, so it can get confusing when you're expecting just a single value as a result.

How to process multiple columns from sql in powershell

I have this PowerShell script:
$QUERY = "SELECT name FROM sys.databases";
$Databases = invoke-sqlcmd -serverinstance "SQLInstanceName" -database "master" -Query $QUERY
foreach ($dbname in $Databases)
{
$dbname
}
Let's say I want the recovery model for the databases as below, how do I get them into PowerShell variables?
$QUERY = "SELECT name, recovery_model_desc FROM sys.databases";
May be you are looking for
$QUERY = "SELECT * from sys.databases";
$Databases = invoke-sqlcmd -serverinstance "SQLInstanceName" -database "master" -Query $QUERY
# This is just to print the individual value of column (name and recovery_model)
$Databases | ForEach {
Write-Host '----------------------------------------'
Write-Host 'Database :' $_.name
Write-Host 'Recovery model :' $_.recovery_model
Write-Host '----------------------------------------'
Write-Host
}
# This will give you name and recovery_model of database
$Databases | Select name, recovery_model

How to get values from workflow parallel code block?

I'm trying to run two Invoke-Sqlcmd in parallel and then wait all the results.
$server1 = '...'
$server2 = '...'
workflow work {
parallel {
$r1 = Invoke-Sqlcmd -ServerInstance $server1 'select 1 a'
$r2 = Invoke-Sqlcmd -ServerInstance $server2 'select 2 a'
}
}
work
# do something with $r1 and $r2. How to access the variables here?
How to pass $server1 and $server2 to the code block?
How to get $r1 and $r2 from the parallel block?
So pass in servers with param, and return a hashtable of both results.
$server1 = '...'
$server2 = '...'
workflow work {
param ($server1, $server2)
parallel {
#{r1 = Invoke-Sqlcmd -ServerInstance $server1 'select 1 a'}
#{r2 = Invoke-Sqlcmd -ServerInstance $server2 'select 2 a'}
}
}
$r = work $server1 $server2
$r.r1
$r.r2

Unable to insert PowerShell variables from array into Invoke-Sqlcmd call

I have an array that loops through a string assigning values to elements. If I then assign those elements to a variable and pass that variable into the invoke-sqlcmd I get an error. However, if I assign the value directly to the variable and pass it in it works fine:
Assign value to array:
for ($i=0; $i -lt $somearray.length; $i++) {
$somearray[$i] = $somearray[$i].Replace('$(query)', $query.text)
}
Lets say somearray[0] = "select * from DB". We'll assign to a variable:
$query = somearray[0]
Now I pass this to my Invoke-Sqlcmd:
Invoke-Sqlcmd -Query $query -Database "local" -ServerInstance "somedb" |
Export-Csv ".\somefile.csv"
This fails:
Invoke-Sqlcmd : Could not find stored procedure 'select * from ALERTS'.
At C:\Migration\ExportTool\ExportTool\Gavs.ps1:95 char:17
+ ... Invoke-Sqlcmd -Query $query -Database $db -ServerInstance ...
However, if I do this:
$query = "select * from DB"
Invoke-Sqlcmd -Query $query -Database "local" -ServerInstance "somedb" |
Export-Csv ".\somefile.csv"
it works perfectly.
So the reason appears to be, if you do this:
$query = somearray[0]
When you view $query in the Invoke-sql command it looks like this:
"select * from DB"
And when you do this:
$query = "select * from DB"
It looks like this:
select * from DB
So directly referencing a string removes the quotes in the Invoke-sqlcmd command. Seems very odd.
Hope this helps someone in the future.

powershell - variable inside a string variable shall update even after it was declared

As you can see, the variable $SQLRCNumberNew is inside another variable $SQLUpdateRC which has been declared before $SQLRCNumberNew did.
When I am running the script $SQLRCNumberNew is empty, which makes sense because it is declared inside $SQLUpdateRC at the beginning.
What I want to ask if someone has an idea how I can update $SQLRCNumberNew even it is declared at the beginning.
I know I can just put the string Variable right below, but this is not what I am looking for.
Thanks for any help!
$RCFirstDigit = 0
$RCSecondDigit = 0
$PhoenixDBServer = "Servername"
$PhoenixDBName = "Databasename"
$ProductionDBServer = "Servername"
$ProductionDBName = "Databasename"
$SQLSelectRC = $("SELECT [Char_Value_01] FROM [dbo].[TABLENAME] WHERE [Keyword] = 'Version Number'")
$SQLUpdateRC = $("UPDATE TABLENAME set Char_Value_01 = '$SQLRCNumberNew' where Keyword = 'Version Number'")
Switch ($env:COMPUTERNAME) {
$PhoenixDBServer {
$Server = $PhoenixDBServer + "." + $env:USERDNSDOMAIN
$Database = $PhoenixDBName
}
$ProductionDBServer {
$Server = $ProductionDBServer + "." + $env:USERDNSDOMAIN
$Database = $ProductionDBName
}
default {
Write-Verbose "This script does not run on this computer"
exit
}
}
$SQLRCNumber = Invoke-Sqlcmd -ServerInstance $Server -Database $Database -Query $SQLSelectRC
[int]$RCFirstDigit = $SQLRCNumber.Char_Value_01.split(".")[1]
[int]$RCSecondDigit = $SQLRCNumber.Char_Value_01.split(".")[2]
$RCSecondDigit++
# put string back together with updated RC number
[string]$SQLRCNumberNew = $SQLRCNumber.Char_Value_01.Split(".")[0] + "." + $RCFirstDigit + "." + $RCSecondDigit
# Update RC Version on Database
Invoke-Sqlcmd -ServerInstance $Server -Database $Database -Query $SQLUpdateRC
Just to be clear - this is not how PowerShell scripting works. When you assign data to your variables, at least when working with strings.
You could have a function inside your script file, that you could call and have it return the concatenated string.
Function StringBuilder {
Param ($Value)
"UPDATE TABLENAME set Char_Value_01 = '$Value' where Keyword = 'Version Number'"
}
...
$SQLRCNumber = Invoke-Sqlcmd -ServerInstance $Server -Database $Database -Query $SQLSelectRC
$SQLUpdateRC = StringBuild $SQLRCNumber
Invoke-Sqlcmd -ServerInstance $Server -Database $Database -Query $SQLUpdateRC
...
Something like that should work. But I would say you should have a string format defined in the top and simply format when you need it.
$SQLUpdateRCBase = "UPDATE TABLENAME set Char_Value_01 = '{0}' where Keyword = 'Version Number'"
...
$SQLRCNumber = Invoke-Sqlcmd -ServerInstance $Server -Database $Database -Query $SQLSelectRC
$SQLUpdateRC = $SQLUpdateRCBase -f $SQLRCNumber
Invoke-Sqlcmd -ServerInstance $Server -Database $Database -Query $SQLUpdateRC