The cmdlet comes in handy very often but is built for "QueryCommands".
What I mean by that is that it assumes that your Query will return "Records".
But what if you want to execute an insert, update or delete statement ?
Some background
WFA comes with the Devart MySql DLL, which is a library to execute against MySql.
So the component is at our disposal.
How does the Invoke-MySqlQuery works ?
The Invoke-MySqlQuery works are follows.
- Record 1 contains the number of records returned
- The following records (if record 1 > 0), returns the actual dataset.
So by coding something like :
$results = Invoke-MySqlQuery "SELECT * FROM cm_storage.volume" if($results[0] -gt 0){ $results | select -skip 1 }
you get a list of volumes.
ExecuteNonQuery, how to
If you want to insert, delete or update, you could potentially use this cmdlet as well. In 99% of the cases it will work, however, it's missing 2 features :
- Return the affected row count
- Set the database (scheme)
In some rare cases (1%), MySql will give you the error "No database selected". Even if you hard-code the scheme name in the query, for some reason it just seems to ignore them. I noticed this behavior in a DELETE FROM JOIN scenario.
A connection string allows you to set a database as well, and does fix the problem.
A second feature is the affected rows. If you update, delete or insert, it's always nice to know how many records were affected. With the Invoke-MySqlQuery, you wont get the information.
So that's why I hacked the original cmdlet and created a new Invoke-MySqlNonQuery, that optionally accept the parameter "Database".
And it returns the affected row count !
And it returns the affected row count !
So here it is :
function Invoke-MySqlNonQuery { Param( [Parameter(Mandatory = $true, HelpMessage="Query to Execute")] [string]$Query, [Parameter(Mandatory = $false, HelpMessage="Database Host to connect.")] [string]$HostName="localhost", [Parameter(Mandatory = $false, HelpMessage="Database Username")] [string]$User="wfa", [Parameter(Mandatory = $false, HelpMessage="Database Port")] [string]$Port="3306", [Parameter(Mandatory = $false, HelpMessage="Database Password")] [string]$Password="Wfa123", [Parameter(Mandatory = $false, HelpMessage="Database")] [string]$Database ) $ConnectionString = "server=" + $HostName + ";port=" + $Port + ";uid=" + $User + ";pwd=" + $Password try { [void][System.Reflection.Assembly]::LoadWithPartialName("Devart.Data.Mysql") $Connection = New-Object Devart.Data.MySql.MySqlConnection } catch { throw("Failed to get MySql Connection. " + $_.exception) } try { $Connection.ConnectionString = $ConnectionString if($Database){ $Connection.Database = $Database } $Connection.Open() $Command = New-Object Devart.Data.MySql.MySqlCommand($Query, $Connection) $affectedRows = $Command.ExecuteNonQuery() return $affectedRows } catch { throw($_.exception) } finally { $Connection.Close() } }
Great Mirko. Like your posts and thank you for sharing your knowledge with us. Very helpful.
ReplyDeleteThanks
Marcel