Outputting large XML file from SQL with Powershell - sql-server

I have a Powershell script that calls a stored procedure in SQL server and outputs the resulting XML directly to a file. It works for a smaller test file but falls down with the full size (~1.5gb file).
The stored procedure works fine. I can call it within SQL server - the problem is that I have to open it in the SQL server then manually save it to a file, then edit that file to remove newlines. When I run the script it falls down when it tries to delete the intermediary files at the end. However, when I run it line by line it falls down at the invoke-sql line.
#net use S: "\\processStore\projects"
# Create variables
$SQLquery = "DECLARE #return_value int; EXEC #return_value = [XML].[XMLdata];"
$outpath = "D:\MyDocuments\XML\XML files"
$outfile = "TestOutput"
# Run the SQL command and store the object to a variable. Need to extend the timeout from the default.
$sql = invoke-sqlcmd -Database 'APP2021' -Query $SQLquery -serverinstance 'statdata' -QueryTimeout 100000
cd C:
# Store the SQL output as an interim text file
$sql.{XML_F52E2B61-18A1-11d1-B105-00805F49916B} | out-file -Filepath "$outpath\$outfile.txt"
# Remove Linebreaks
(Get-Content "$outpath\$outfile.txt" -Raw).Replace("`r`n","") | Set-Content "$outpath\${outfile}_del.xml" -Force
format-xml "$outpath\${outfile}_del.xml" | Set-Content "$outpath\$outfile.xml" -Force
# Delete interim text files
del "$outpath\$outfile.txt"
del "$outpath\${outfile}_del.xml"
When running lines one by one the code falls down at the invoke-sqlcmd line with the error:
invoke-sqlcmd : A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote
host.)
At line:1 char:8
+ $sql = invoke-sqlcmd -Database 'APP2021' -Query $SQLquery -serverinst ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Invoke-Sqlcmd], SqlPowerShellSqlExecutionException
+ FullyQualifiedErrorId : SqlError,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand

Change from
invoke-sqlcmd -Database 'APP2021' -Query $SQLquery -serverinstance 'statdata' -QueryTimeout 100000
to
invoke-sqlcmd -Database 'APP2021' -Query $SQLquery -serverinstance 'statdata' -QueryTimeout 0
Setting QueryTimeout = 0 will prevent the query from timing out

Related

Capture messages output from SQL Server

I have below PS script which creates a table. I would like to capture messages output (Command(s) completed successfully.) from sql server. Is there a way to achieve that?
I tried -Verbose switch but that didn't helped.
PS File:
$CreateTableFile = "C:\DBScripts\CreateTable.sql"
Invoke-Sqlcmd -ServerInstance xyz -InputFile $CreateTableFile -Database "PSLearning" -Verbose
CreateTable.sql:
CREATE TABLE abc (
column_1 int,
)
You don't say what you want to capture. Everything or just errors.
Errors, you can use try/catch, everything you can use Start-Transcript, or write your own log code, or stuff like print script.
Example:
Invoke-Sqlcmd -Query "update your database set column_name ={expression} where <search_condition>; PRINT 'update successfully';" –Verbose
As documented in the Bulit-In Help files …
# get function / cmdlet details
(Get-Command -Name Invoke-SqlCmd).Parameters
Get-help -Name Invoke-SqlCmd -Full
Get-help -Name Invoke-SqlCmd -Online
Get-help -Name Invoke-SqlCmd -Examples
Get-help -Name Invoke-SqlCmd -Examples
# -------------------------- EXAMPLE 5 --------------------------
C:\PS>Invoke-Sqlcmd -Query "PRINT N'abc'" -Verbose
VERBOSE: abc
# Description
# -----------
# This example uses the PowerShell -Verbose parameter to return the message output of the PRINT command.
... or the online ones.
Invoke-Sqlcmd
You can display SQL Server message output, such as those that result
from the SQL PRINT statement, by specifying the Verbose parameter
Example 5: Run a query and display verbose output
PSet-Location "SQLSERVER:\SQL\MyComputer\MainInstance"
Invoke-SqlCmd -Query "PRINT N'abc'" -Verbose
VERBOSE: abc

Powershell SQL Server Agent CmdExec job step multiple line code

Why does code like this execute in PowerShell ISE:
$var = 'dog';Invoke-SqlCmd -ServerInstance 'servername' -Query "insert into DB.dbo.tbl values ('$($var)')"
But not in SQL Server Agent as a CmdExec job step? Despite enclosing it as per usual. I believe it is the multiple queries as individual queries work
powershell.exe -ExecutionPolicy Bypass -Command {$var = 'dog';Invoke-SqlCmd -ServerInstance 'servername' -Query "insert into DB.dbo.tbl values ('$($var)')"}
TL;DR;
I have a SQL Server Agent job with a CmdExec step. I wish to assign a variable and then use it in an insert statement.
So far the following insert will work:
powershell.exe -ExecutionPolicy Bypass -Command "Invoke-SqlCmd -ServerInstance 'servername' -Query 'insert into DB.dbo.tbl values (''cat'')'"
This inserts a cat. Now I need a dog, something along the lines of:
powershell.exe -ExecutionPolicy Bypass -Command "$var = 'dog'; Invoke-SqlCmd -ServerInstance 'servername' -Query ""insert into DB.dbo.tbl values (''$($var)'')"""
There are two issues here, the comma terminator which I have used successfully in other jobs to separate commands. The second issue is escaping the double quotes. I understand they are required to process the variable into the string.
I have tried escaping with double quotes as well as one of these `. I've also tried separating the variable declaration into one server agent job step and using the variable in another.
Based on #gvee answer below, I put the code in a script block, which executes perfectly in PowerShell, but not as a SQL Agent CmdExec job step
powershell.exe -ExecutionPolicy Bypass -Command {$var = '''dog'''; Invoke-SqlCmd -ServerInstance 'servername' -Query "insert into DB.dbo.tbl values ($($var))"}
Note I had to escape the variable three times, which inserted into the table as 'dog' with the quotes included. I removed the single quotes from the insert statement, however I cannot get this to run in Server Agent as a CmdExec step
-Command accepts a ScriptBlock, so give this a whirl:
powershell.exe -ExecutionPolicy Bypass -Command {
Invoke-SqlCmd -ServerInstance "servername" -Query "insert into DB.dbo.tbl values ('cat')"
}

How to capture SSMS event log from Powershell into file?

Using a Powershell. I'm calling stored procedure containing batch of insert statements. Now I would like to capture the event log of the insert statements (both success message and error) into file like.
(1 row(s) affected).
Msg 8146, Level 16, State 1, Procedure test, Line 0 [Batch Start Line 0]
Procedure test has no parameters and arguments were supplied.
I'm trying this, but it not work. The execution happens, but file loads empty.
$conn = New-Object System.Data.SqlClient.SqlConnection SqlConnection
$conn.ConnectionString = "Server=$server;Database=$databaseName;User=$userName;password=$password;trusted_connection=true;" # set the connection string
$conn.Open();
$cmd = $conn.CreateCommand();
Invoke-Sqlcmd -ServerInstance $server -Database $databaseName -Query "exec batch_insert_statements" -Verbose
out-file -filepath C:\Logs\Test.txt
I found the answer here: https://www.sqlservercentral.com/Forums/Topic914307-391-1.aspx
$sql = "sqlcmd.exe -S ServerName -E -d DatabaseName -Q ""EXEC YourProc"""
Invoke-Expression $sql | Out-File C:\temp\outfile.txt
I just tried it (ps version 5.1.16299.98) and it wrote (1 rows affected) to outfile.txt
This would of course require SQLCMD.EXE to be installed, but I think that's a given if you are already using Invoke-Sqlcmd
You shouldn't need the first few lines, you also haven't piped the command to Out-File, try this:
$server = "."
$databaseName = "dbName"
Invoke-Sqlcmd -ServerInstance $server -Database $databaseName -Query "exec batch_insert_statements" -Verbose -OutputSqlErrors 1 -IncludeSqlUserErrors | out-file -filepath C:\Logs\Test.txt
I found much similar way, but it is totally powershell.
$Query = 'EXEC tes'
$log = "c:\logs\Lead_Scoring_Log_$(get-date -f dd-MM-yyyy-HH-mm-ss).txt"
$SqlcmdOptions = #"
-S"$ServerInstance" -d "$Database" -v User=$userName Password=$password -Q
"$Query"
"#
Start-Process -FilePath "sqlcmd.exe" -ArgumentList #"
$SqlcmdOptions
"# -Wait -NoNewWindow -RedirectStandardOutput $log -PassThru

execute .sql script using powershell and store the output in .sql file

I’m trying to run the sql script .sql file from powershell and save the result into .sql file. Overview : SQL database restore requires a user and permission backup pre-restore and once the restore is complete we need to execute the output( users permissions backup which we did pre-restore ) on the database.
here’s my script and when i execute i see an empty file.
Add-PSSnapin SqlServerProviderSnapin100;
$server = 'DBA_Test';
$database = 'Test';
$mydata = invoke-sqlcmd -inputfile "C:\users\security.sql" -serverinstance $server -database $database | Format-Table -HideTableHeaders -AutoSize
$mydata | out-file C:\users\output.sql;
Remove-PSSnapin SqlServerCmdletSnapin100;
Can someone help me on this ?
Thanks in advance
invoke-sqlcmd -inputfile "C:\users\security.sql" -serverinstance $server -database $database | Format-Table -HideTableHeaders -AutoSize >> C:\users\output.sql
or
Invoke-sqlcmd -inputfile "C:\users\security.sql" -serverinstance $server -database $database | Format-Table -HideTableHeaders -AutoSize | Out-File –FilePath C:\users\output.sql –Append
should do the trick.
Your problem is that you're only capturing one output stream. Your code would work as expected if your query was running "Select 'Hello World!'".
In order to get all output streams (verbose, error, and output), into a single file, you can do the following:
invoke-sqlcmd -inputfile "C:\users\security.sql" -serverinstance $server -database $database -verbose *>&1 | out-file C:\users\output.sql
The -verbose flag turns on a lot of the messages you'd expect to see. The * indicates you want all output streams (you can look up the definitions if you'd like. The verbose stream itself is 4, so 4>&1 would just redirect that one stream). Then you are just redirecting the output to out-file.

Invoke-sqlcmd - to export the output of a sql query to an xml file using powershell

I have a sql query with for xml explicit clause. Result i need to store in an xml file.
I am using a powershell command to do so :
invoke-sqlcmd -inputFile $inputFilePath | Out-File -filePath $outputFilePath
this gives me an output file similar to
XML_F52E2B61-18A1-11d1B1000805F49916B
'<'person>dsugfiugds'<'/person>...
'<'student>sdgfdg<\student>'<'id>45<\id>'<'cla...
ss>sdfsdfsfd<....
This file has also been truncated , you can see the ... appears
Where as i need the xml to be in the correct format i.e an xml file itself.
Instead of Out-File have you tried Export-Clixml?
invoke-sqlcmd -inputFile $inputFilePath | Export-Clixml -filePath $outputFilePath

Resources