I've a powershell script connecting to SQL server 2012 database running a SQL query and result set into data table to send formatted email to relevant parties. Below is the code snippet where issue is:
$CBA = New-Object System.Data.DataSet "CBAData"
$sqlConn = New-Object System.Data.SqlClient.SqlConnection("Data Source=DataSource;Initial Catalog=DataCatalog;Integrated Security = False;Connection Timeout=800;User ID = user; Password =pwd;")
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($CBAData, $sqlConn)
$adapter.Fill($CBA)
I am getting below error running the script:
Exception calling "Fill" with "1" argument(s): "Execution Timeout Expired. The timeout period elapsed prior to completion of the operation or the server is not responding."
I've tried increasing timeoutin SqlConnection string from initially set up 360 gradually and now upto 800 but still having same issue. Does anyone throw insight into what exactly issue is here? and How can I overome it?
Thank you in advance.
As mentioned by OP - default command execution timeout is 30 seconds. I found below within:
SqlDataAdapter class
that would allow you to increase command execution timeout (insert, update, delete, select command). So in my case below did the trick:
$adapter.SelectCommand.CommandTimeout=60
Hope this helps.
In addition to Zulfiqar's answer, which led me in the right direction. For me, the solution was in the SqlCommand. The error I was getting when setting the property of the adapter was as follows:
The property 'CommandTimeout' cannot be found on this object. Verify that the property exists and can be set.
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand;
$SqlCmd.CommandTimeout = 60;
Related
It's me again, I'm still getting to limited grips about how PowerShell and SQL work together, this isn't my main field of experience so please excuse the simple mistake I've probably made.
I am trying to update one field in a row. I've searched here and been able to build most of what I need but am getting an error message that states
"Exception calling "ExecuteNonQuery" with "0" argument(s): "Incorrect syntax near 'f7'."
At line:61 char:5
+ $rowsAffected = $command2.ExecuteNonQuery()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SqlException"
This is the code snippet I am using is this section, it is embedded within a foreach loop that steps through the rows of a dataset and sends an email. This section is supposed to change the bit type field "mailed" to true which ensure that only one email is sent per record.
$connect2 = New-Object System.Data.SqlClient.SqlConnection
$connect2.ConnectionString=$ServerConnection
$connect2.Open()
$command2 = New-Object System.Data.SqlClient.SqlCommand
$command2.Connection = $connect2
$MySql2="UPDATE dbo.scans SET Mailed = 'True' WHERE SessionID ="+$BT1
$command2.CommandText = $MySql2
$rowsAffected = $command2.ExecuteNonQuery()
Write-Output "Updating mailed marker"
$connect2.Close()
EBGreen's suggestion worked perfectly. Changing the text string for the $MySql2 = "UPDATE dbo.scans SET Mailed = 'True' WHERE SessionID ='"+$BT1+"'" fixed the error and the field is being updated as required.
Try displaying your sql string to make sure it looks correct. It could be that your $BT1 variable is blank.
write-host $MySql2
Also, when dealing with sql syntax errors it is helpful to log in directly to the sql server and submit the string through the sql command line shell. Once you can submit the string successfully from the command line then check that your powershell string looks exactly the same.
You can make your query string setup more basic. Within PowerShell if you reference a variable with double-quotes, PowerShell will resolve that variable to the set value.
So instead of doing this:
$MySql2="UPDATE dbo.scans SET Mailed = 'True' WHERE SessionID ="+$BT1
Or even this:
$MySql2="UPDATE dbo.scans SET Mailed = 'True' WHERE SessionID ='"+$BT1+"'"
You can simply do this:
$MySql2="UPDATE dbo.scans SET Mailed = 'True' WHERE SessionID ='$BT1'"
I am using a SQL Server job to get some wmiobject details into a table.
This code runs with default installation, but fails when I execute it on a named instance. So far I have seen only one difference in connection, for the named instance, SQL Agent is using with a user name which has "$" as part of the name (i.e. NT Service\SQLAgent$instance)
Is there anyway I can overcome this? Changing the agent account is not an option as most of the servers run with this account and my code needs to work with all accounts.
$conn = New-Object System.Data.SqlClient.SqlConnection("Data Source=$SqlSvr;Initial Catalog=$Database; Integrated Security=SSPI")
$conn.Open()
Executed as user: NT Service\SQLAgent$instance. A job step received
an error at line 21 in a PowerShell script. The corresponding line is
' $conn.Open() '... The error information returned by PowerShell
is: 'Exception calling "Open" with "0" argument(s): "Login failed for
user '(DOMAIN)(COMPUTER)$'." '. Process Exit Code -1.
I tried with "identity impersonate =true" but it didn't accept the command.
Any ideas?
Ether use ' instead of " or use the escape Char ` or use char(36)
"blahblah`$blahblah"
'blahblah$blahblah'
"blahblah$([char](36))blahblah"
I'm bringing databases out of log shipping, trying to use SMO to do it. I'm attempting to mimic the following T-SQL using SMO:
restore database <database name> with recovery
Here's my code:
# select secondary_database from msdb.dbo.log_shipping_secondary_databases
$dsSecLSDB = $secInst.Databases["MSDB"].ExecuteWithResults("select secondary_database from log_shipping_secondary_databases")
$secLSDB = $dsSecLSDB.Tables.Rows
foreach($db in $secLSDB.secondary_database) {
write-host "Restoring database (bringing online)..."
$secRestrObj = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Restore -Property #{
Action = 'Database';
Database = $db;
NoRecovery = $FALSE;
}
$secRestrObj.SqlRestore($secInst);
write-host "Done with restore."
}
The error:
Microsoft.SqlServer.Management.Smo.PropertyNotSetException: To accomplish this action, set property Devices
The available options for DeviceType (from https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.management.smo.devicetype(v=sql.105).aspx) are:
LogicalDevice
Tape
File
Pipe
VirtualDevice
The problem is, I don't know which DeviceType to create. My guess is LogicalDevice but I don't know the value of it. Has anyone done this before?
I'm facing the same trouble.
I guess that the method sqlRestore is limited to a strong database restore, from a backup file/device.
Just bringing "online" a database with the status "restoring" (ie stand by db from log shipping or from a broken AG) seems to be possible only executing the "restore database with recovery" with the invoke-sqlcmd applet.
Or if anybody has an other solution ...
I use PowerShell to query SQL databases, and I am quite familiar with that process. However, I am now tasked with building an automated task that queries Oracle for information.
It seems straight forward: Install proper Oracle DLL's, import them into PS, execute the query much like SQL. However, this is not the case. All I get when I request information is a list called FieldCount. This seems to imply that I am able to see the information, it's just not displaying correctly. I'd like the actual values, and nothing seems to get this for me.
Thanks to anyone who knows anything about this, as my hands are tied and this is the only way I can think of to get this information from Oracle on a scheduled basis. I am not the Oracle admin, I only have read access to this view.
function Get-OracleData($cmdText){
Add-Type -Path 'C:\app\client\username\product\12.1.0\client_1\odp.net\managed\common\Oracle.ManagedDataAccess.dll'
$username = 'username'
$password = 'password'
$con = New-Object Oracle.ManagedDataAccess.Client.OracleConnection('User Id=$username;Password=$password;Data Source=OracleServerName')
$con.Open()
$cmd = New-Object Oracle.ManagedDataAccess.Client.OracleCommand
$cmd.Connection = $con
$cmd.CommandText = $cmdText
$rdr = $cmd.ExecuteReader()
if($rdr.Read()){
return $rdr
}else{return 0}
}
Get-OracleData -cmdText '
SELECT em.employee_number,
em.last_name,
em.first_name,
em.middle_names,
em.email_address,
em.start_date,
em.term_date,
em.location_addr_line_1,
em.location_city,
em.location_work_state,
FROM CustomView em
'
Found the answer in the link below. I was able to get what I needed by inserting the below code at the line where $cmd.CommandText = $cmdText is located in my original post, and getting rid of what's below it.
$ds = New-Object system.Data.DataSet
$da = New-Object Oracle.ManagedDataAccess.Client.OracleDataAdapter($cmd)
[void]$da.fill($ds)
return $ds.Tables[0] | Select *
This returns to a variable, and I can get the first entry using $results[0], and $results[0].EMPLOYEE_NUMBER, etc.
Reference: http://poshcode.org/3965 #line55
I’m trying to take back-up of a large database using “Backup-SQLDatabase” cmdlet using following statement, but I’m getting time-out error after 10 minutes.
{Backup-SqlDatabase -ServerInstance $Server -Database $DatabaseName -BackupFile $BackUpFile -CompressionOption On -ConnectionTimeout 0 -Initialize -Verbose -ea Stop}
Here’s the error exactly after 600 seconds of execution :
VERBOSE: 60 percent processed.
VERBOSE: The backup or restore was aborted.
The wait operation timed out
+ CategoryInfo : InvalidOperation: (:) [Backup-SqlDatabase], Win3
2Exception
+ FullyQualifiedErrorId : ExecutionFailed,Microsoft.SqlServer.Management.P
owerShell.BackupSqlDatabaseCommand
+ PSComputerName : localhost
I looked up at internet and found a bug filled here.
However, the issue still exists in SQL Server 2012 (11.0.339).
I’ve also tried reconfiguring “remote query timeout” to 0 as given here, but the issue persists.
This is actually very weird issue. PowerShell is for automation and scripts do take more than 10 minutes to run. “Backup-SQLDatabase” should have considered this.
Please suggest a workaround by which I can fix this while using this cmdlet.
Else , I’ve to re-write the code using SMO classes or basic T-SQL.
I did some research on this and came around the following workaround :
$serverConn = new-object ("Microsoft.SqlServer.Management.Smo.Server") $server
$serverConn.ConnectionContext.StatementTimeout = 0
Backup-SqlDatabase -InputObject $serverConn -Database abc -BackupFile "L:\123\abc.bak"
When we pass Server name as a string, it tries to create it's own connection and we don't have the option to change QueryTimeout from 600 to 0.
However, we can create a SMO.Server object and use it after setting desired properties.
Hope it helps!