Date Variable is not Carry Over to Function for Query String - sql

I receive this error:
ExecuteSqlQuery : Must declare the scalar variable "#date".
I call the query as such: ExecuteSqlQuery -server "sqlbox" -database "dbname" and I receive the date variable error. You can see my query statement uses the variable m.created_date >= #date.
How do I correctly pass the date variable to query string so it runs in the function without an issue? NOTE: the code works when I hardcode the date value.
Function ExecuteSqlQuery {
Param(
[Parameter(Mandatory=$true)][string]$server,
[Parameter(Mandatory=$true)][string]$database
)
Process
{
$date= $((get-date).AddSeconds(-120).ToString("MM-dd-yyyy HH:mm:ss"))
$getscriptinfo = "select m.created_date, a.engine_full_hierarchy as Location, e.exciter_name, e.engine_exciter_id as ExciterID, m.additional_data as ReasonDown from HugsAdminAmador.mv_audit m, HugsAdminAmador.exciter e, HugsAdminAmador.area_map a where m.object_id = e.exciter_id and e.area_map_id = a.area_map_id and m.created_date >= #date and m.additional_data like '%NewStatus=DOWN%' and m.additional_data not like '%autonomous%'"
$scriptscon = New-Object System.Data.SqlClient.SqlConnection
$scriptscon.ConnectionString = "Data Source=$server;Initial Catalog=$database;Integrated Security=true"
$scriptcmd = New-Object System.Data.SqlClient.SqlCommand
$scriptcmd.Connection = $scriptscon
$scriptcmd.CommandText = $getscriptinfo
$scriptcmd.CommandTimeout = 0
$ErrorActionPreference = 'Stop'
try
{
$scriptscon.Open()
$Reader = $scriptcmd.ExecuteReader()
# if reader returns data create an array of the error data for the potential alert.
If ($Reader.HasRows) {
$obj = $Reader | foreach {
$row = $_;
#the left naming is for the column headers in the email.
new-object psObject -Property #{
CreateDate = $row.Item("created_date")
ReasonDown = $row.Item("ReasonDown")
ObjectID = $row.Item("object_id")
}
}
}
return $obj
}
catch [Exception]
{
# Write-Warning "Get-ExecuteScripts (Connection: [$server].[$database])"
# Write-Warning $_.Exception.Message
# Write-Warning "Query: $getscriptinfo --Id $scriptid"
Write-Error $_
$ErrorEvent = #{
LogName = 'Exciter_Log'
Source = 'Exciter_Health'
EventID = 333
EntryType = 'Information'
Message = $_
}
Write-EventLog #ErrorEvent
}
finally
{
$ErrorActionPreference = 'Continue'
$scriptscon.Dispose()
$scriptcmd.Dispose()
}
}
}

Related

Trying to extract data form SQL using PS script

I have been trying to get a PS script to work in extracting files (pdf, word, etc.) from an SQL Server database. I came across the PowerShell script below. The script runs and populates the destination folder but all files are 0 bytes and during the script execution. It throws the error:
"Exporting Objects from FILESTREAM container: .docx
Exception calling "GetBytes" with "5" argument(s): "Invalid attempt to GetBytes on column 'extension'. The GetBytes function can only be used on columns of typ
e Text, NText, or Image.""
Can anyone point me in what am I doing wrong and how to fix this please? Much appreciated.
$Server = ".\xxxxxx";
$Database = "xxxxxx";
$Dest = "C:\DATA\";
$bufferSize = 8192;
$Sql = "
SELECT
[extension]
FROM [XXXXXXXX].[dbo].[XXXXXXdocuments]
";
$con = New-Object Data.SqlClient.SqlConnection;
$con.ConnectionString = "Data Source=$Server;" +
"Integrated Security=True;" +
"Initial Catalog=$Database";
$con.Open();
Write-Output ((Get-Date -format yyyy-MM-dd-HH:mm:ss) + ": Started ...");
$cmd = New-Object Data.SqlClient.SqlCommand $Sql, $con;
$cmd.CommandTimeout = 120
$rd = $cmd.ExecuteReader();
$out = [array]::CreateInstance('Byte', $bufferSize)
While ($rd.Read())
{
try
{
Write-Output ("Exporting Objects from FILESTREAM container: {0}" -f $rd.GetString(0));
$fs = New-Object System.IO.FileStream ($Dest + $rd.GetString(0)), Create, Write;
$bw = New-Object System.IO.BinaryWriter $fs;
$start = 0;
enter code here
$received = $rd.Getbytes(0, $start, $out, 0, $bufferSize - 1);
While ($received -gt 0)
{
$bw.Write($out, 0, $received);
$bw.Flush();
$start += $received;
$received = $rd.Getbytes(0, $start, $out, 0, $bufferSize - 1);
}
$bw.Close();
$fs.Close();
}
catch
{
Write-Output ($_.Exception.Message)
}
finally
{
$fs.Dispose();
}
}
$rd.Close();
$cmd.Dispose();
$con.Close();
Write-Output ("Finished");
Read-Host -Prompt "Press Enter to exit"
BinaryWriter is unnecessary. It's for writing primitive types to a Stream.
And there's no need to muck around with buffers; you can simply use SqlDataReader.GetStream(int).CopyTo(Stream), eg
$Server = "localhost";
$Database = "adventureworks2017";
$Dest = "C:\temp\";
$Sql = "
SELECT concat('photo', ProductPhotoID, '.jpg') name, LargePhoto from Production.ProductPhoto
";
$con = New-Object Data.SqlClient.SqlConnection;
$con.ConnectionString = "Data Source=$Server;Integrated Security=True;Initial Catalog=$Database;TrustServerCertificate=true";
$con.Open();
Write-Output ((Get-Date -format yyyy-MM-dd-HH:mm:ss) + ": Started ...");
$cmd = New-Object Data.SqlClient.SqlCommand $Sql, $con;
$cmd.CommandTimeout = 120
$rd = $cmd.ExecuteReader();
While ($rd.Read())
{
try
{
Write-Output ("Exporting: {0}" -f $rd.GetString(0));
$fs = New-Object System.IO.FileStream ($Dest + $rd.GetString(0)), Create, Write;
$rd.GetStream(1).CopyTo($fs)
$fs.Close()
}
catch
{
Write-Output ($_.Exception.Message)
}
finally
{
$fs.Dispose();
}
}
$rd.Close();
$cmd.Dispose();
$con.Close();
Write-Output ("Finished");

How to export the output of SQL query to excel using powershell

I am trying to export the result of SQL to excel sheet. below is my query.
function Get-SQLData {
Param(
[parameter(Mandatory = $true)]
[String]$db_server,
[parameter(Mandatory = $true)]
[String]$sql_query,
[parameter(Mandatory = $true)]
[String]$database_name,
[parameter(Mandatory = $true)]
[String]$user_name,
[parameter(Mandatory = $true)]
[String]$password
)
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server = $db_server; Database = $($database_name); User ID = $user_name ; Password = $password;"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $sql_query
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet) | Out-Null
$SqlConnection.Close()
return $DataSet
}
$db_name = 'emp';
$user_name = 'deploy' ; $password= 'deploy#1';"
$sql_query1 = "select * from emp;"
$report_path = "D:\Newfolder"
$SendMail = 0
$report_files = #()
try {
$output1 = Get-SQLData -db_server $db_server -sql_query $sql_query1 -database_name $db_name -user_name $user_name -password $password
for ($k=0;$k -lt $output1.tables.count;$k++){
[Array]$outputArray = $output1.tables[$k]
if ($outputArray.count -ge 0 )
{
$report_file = $report_path.ToString()+"Report_File_"+($k+1)+".csv"
$outputArray | Export-Csv -Path $report_file -NoTypeInformation
$report_files += $report_file
$html1 = $outputArray | ConvertTo-Html -head $HeaderStyle
}
}
catch{
$ErrorMessage = $_.Exception.Message
Write-Error $ErrorMessage
}
while printing the $output1 I am getting the below
RemotingFormat : Xml SchemaSerializationMode : IncludeSchema
CaseSensitive : False DefaultViewManager :
{System.Data.DataViewManagerListItemTypeDescriptor} EnforceConstraints
: True DataSetName : NewDataSet Namespace :
Prefix : ExtendedProperties : {} HasErrors
: False IsInitialized : True Locale : en-US
Site : Relations : {} Tables
: {System.Data.DataRow System.Data.DataRow System.Data.DataRow
System.Data.DataRow System.Data.DataRow System.Data.DataRow
System.Data.DataRow
System.Data.DataRow System.Data.DataRow System.Data.DataRow System.Data.DataRow System.Data.DataRow,
System.Data.DataRow} Container : DesignMode
: False ContainsListCollection : True
But excel sheet is not creating in the mentioned location.
You can use a ImportExcel module from the PSgallery:
Install-Module ImportExcel,dbatools -Scope CurrentUser
$result = Invoke-DbaQuery -SqlInstance $db_server -Query 'select * from emp;'
$result | Export-Excel -Path empl.xlsx -WorksheetName Empl -TableName Empl
In this example, I use 2 modules. You really need ony Export-Excel for your needs but DBATOOLS really make this code easier to read.

Sending the results from a ForEach loop containing the Same SQL Query to 2 separate variables via PowerShell

Doing this query in sql server - it returns 3 rows of data. Running the script with the write-host $1_resultsDataTable and comment out the other variable $2_resultsDataTable- it returns only one row of the data array. Now if I reverse the comments so the $2_resultsDataTable is active for the write-host, it returns 6 rows of data.
How do I set this up so I would see the same 3 rows assigned to both $1_resultsDataTable and $2_resultsDataTable when I dump these variables to view the data results?
[string] $Server= "SERVER"
[string] $Database = "mvTest"
[string] $UserSqlQuery= $("select m.created_date, m.additional_data as ReasonDown from aeroscout.mv_audit m where m.created_date >= '2020-01-18' and m.additional_data like '%query-text%'")
#
$1_resultsDataTable, $2_resultsDataTable = foreach ($x in 1..2) {
$resultsDataTable = New-Object System.Data.DataTable
$resultsDataTable = ExecuteSqlQuery $Server $Database $UserSqlQuery
$resultsDataTable # first loop sends output to $1_resultsDataTable, second loop send to $2_resultsDataTable
Start-Sleep 3
}
# executes a query and populates the $datatable with the data
function ExecuteSqlQuery ($Server, $Database, $SQLQuery) {
$Datatable = New-Object System.Data.DataTable
$Connection = New-Object System.Data.SQLClient.SQLConnection
$Connection.ConnectionString = "server='$Server';database='$Database';Integrated Security=True;"
$Connection.Open()
$Command = New-Object System.Data.SQLClient.SQLCommand
$Command.Connection = $Connection
$Command.CommandText = $SQLQuery
$Reader = $Command.ExecuteReader()
If ($Reader.HasRows) {
while($Reader.Read()) {
$props = #{}
for($i = 0; $i -lt $Reader.FieldCount; $i+=1) {
$name = $Reader.GetName($i)
$value = $Reader.item($i)
$props.Add($name, $value)
}
$obj = new-object PSObject -Property $props
Write-Output $obj
}
}
return $obj
$SqlConnection.Close()
}
#validate we got data
write-host $1_resultsDataTable
Start-Sleep 3
write-host $2_resultsDataTable

How to return a reference value with a method from an extended Powershell object?

I'm trying to extend a Powershell object with a method that
returns a true or false to indicate success
outputs a value by reference ([ref])
I have in my module MyExtensions.psm1.
Update-TypeData -TypeName [MyType] -MemberType ScriptMethod -memberName TryGetValue -force -value `
{
param(
$myInput,
[ref]$myOutput
)
try
{
# do something with $myInput
$myOutput = …
return $true
}
catch
{
return $false
}
}
The goal is to be able to write in a script or in another module:
Import-Module MyExtensions
$myInput = …
$value = $null
if($myTypeItem.TryGetValue($myInput, $value)
{
# I know that the $value is good
}
Using argument by reference (you just miss $myOutput.Value ="")
function addition ([int]$x, [int]$y, [ref]$R)
{
$Res = $x + $y
$R.value = $Res
}
$O1 = 1
$O2 = 2
$O3 = 0
addition $O1 $O2 ([ref]$O3)
Write-Host "values from addition $o1 and $o2 is $o3"
A more comple answer here.

Get output parameter from procedure Phalconphp

My Code :
$item = new Items2;
$connection = $item->getReadConnection();
$sql = "CALL `OLViewItemsListViewAllWithCount`('','','',0,0,0,0,0,0,0,'2018-05-15',0,0,10,#aa);";
$items = new Resultset(null,$robot,$connection->query($sql));
i need to get the #aa from this Result as a output parameter
how can i get it ?
Need to select out parameters in second query like..
$item = new Items2;
$connection = $item->getReadConnection();
$sql = "CALL `OLViewItemsListViewAllWithCount`('','','',0,0,0,0,0,0,0,'2018-05-15',0,0,10,#aa);";
$items = $robot,$connection->query($sql)->fetchAll(\Phalcon\Db::FETCH_ASSOC);;
$sql2 = "SELECT #aa";
$aa = $connection->query($sql2)->fetch();
echo $aa['#aa];