I am trying to fetch count of table from SQL server by connecting using Powershell, but I am getting the below error message, but if I just do select on the table instead of count then the same code is returning results, please suggest as I am not getting a solution to this problem.
Error Message:
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."
+ $DataAdapter.Fill($Dataset)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SqlException
Script:
[string] $Server= "Server_nm"
[string] $Database = "DB_nm"
[string] $UserSqlQuery = $("SELECT count(1) AS cnt FROM [tbl]")
##$resultsDatatable = ExecuteSqlQuery $Server $Database $UserSqlQuery
function GenericSqlQuery ($Server, $Database, $SQLQuery) {
$Datatable = New-Object System.Data.DataTable
$Connection = New-Object System.Data.SQLClient.SQLConnection
$Connection.ConnectionString = "server='$Server';database='$Database';trusted_connection=true;"
$Connection.Open()
$Command = New-Object System.Data.SQLClient.SQLCommand
$Command.Connection = $Connection
$Command.CommandText = $SQLQuery
$DataAdapter = new-object System.Data.SqlClient.SqlDataAdapter $Command
$Dataset = new-object System.Data.Dataset
$DataAdapter.Fill($Dataset)
$Connection.Close()
return $Dataset.Tables[0]
} $resultsDatatable = GenericSqlQuery $Server $Database $UserSqlQuery
#validate we got data
Write-Host ("The table contains: " + $resultsDatatable.Rows.Count + " rows")
You can use the Invoke-Sqlcmd function instead.
# initialize Variables
[string] $Server= "Server_nm"
[string] $Database = "DB_nm"
[string] $UserSqlQuery = $("SELECT count(1) AS cnt FROM [tbl]")
# Invoke-SqlCmd
$resultsDatatable = Invoke-Sqlcmd -ServerInstance $Server -Database $Database -Query $UserSqlQuery
# validate we got data
Write-Host ("The table contains: " + $resultsDatatable.cnt + " rows")
Related
while i passed the value from splunk by running this script and inserted into database, i got below error :
Exception calling "ExecuteNonQuery" with "0" argument(s): "String or binary data would be truncated. The statement has been terminated."
could you help to suggest how to fix that issue?
passing date time value from splunk is
$jsonObj.result.F10="2.312" $jsonObj.result.F11="3.212" $jsonObj.result.F15="6.412" $jsonObj.result.datetime = "2021-12-29 19:00:00" and in database table date time column value also same format "yyyy-mm-dd hh:mm:ss"
below is my code:
param ($jsonContent)
$jsonObj = $jsonContent | ConvertFrom-Json
write-host $jsonObj.result.F10
write-host $jsonObj.result.F11
write-host $jsonObj.result.F15
write-host $jsonObj.result.datetime
$serverName = "FSMSSTEST132,3067"
$databaseName = "ITReport"
$tableName = "dbo.SPK_ITMetricsChart"
$YourUserID = "MES123";
$YourPassword="Asd123";
$hostName = "$jsonObj.result.F10","$jsonObj.result.F11" ,"$jsonObj.result.F15"
$value1 = "Delivery"
$time = $jsonObj.result.datetime
$site = "F10N","F11","F15"
$Connection = New-Object System.Data.SQLClient.SQLConnection
$Connection.ConnectionString = "server='$serverName';database='$databaseName';User ID= '$YourUserID'; Password= '$YourPassword'"
$Connection.Open()
$Command = New-Object System.Data.SQLClient.SQLCommand
$Command.Connection = $Connection
for($i=0;$i -lt $hostName.Length; $i++)
{
$insertquery="
INSERT INTO $tableName
([Datetime],[Value],[Category],[Site])
VALUES
('$time','$($hostName[$i])','$value1','$($site[$i])')"
$Command.CommandText = $insertquery
$Command.ExecuteNonQuery()
}
$Connection.Close();
Working with an API, I believe I need to create a WebserviceProxy object and add the property "ExternalID" to it, but I can't seem to get the right code to do that.
This is the error I am getting...
Cannot convert argument "0", with value: "002374E4DBEC", for "LaunchClientApplication" to type "WebServiceProxy.ExternalId": "Cannot convert the "002374E4DBEC" value of type "System.String" to type "WebServiceProxy.ExternalId"."
At C:\PowerShellScripts\Crawler.ps1:72 char:50
+ $guid = $OSSNBranchWS.LaunchClientApplication <<<< ($FTCSTBExternalID.Ext_Device_ID,$applicationUri)
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
This is my code...
### Crawler
### SQL Login
$SQLUser = "USERNAME"
$SQLPassword = "PASSWORD"
$SQLServer = "SQLSERVER\DB"
$SQLDBName = "SQLDB"
$SqlQuery = "select a.externalID as Acct_Number, d.externalId as Ext_Device_ID
from bm_account a inner join
bm_device d on a.accountId = d.accountId
where a.externalId='9999999999'
order by Acct_Number,Ext_Device_ID"
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server = $SQLServer; Database = $SQLDBName; User ID = $SQLUser; Password = $SQLPassword;"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $SqlQuery
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$rowCount = $SqlAdapter.Fill($DataSet)
$SqlConnection.Close()
$FTCSTBExternalIDs = $DataSet.Tables[0]
$Domain = 'DM'
$UserName = 'USERNAME'
$Password = 'PASSWORD'
$UsernameDomain = $Domain+'\'+$UserName
$SecurePassword=ConvertTo-SecureString -String $Password -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential $UsernameDomain,$SecurePassword
$OSSNBranchWS = New-WebServiceProxy -Uri "http://mediaroomserver/ossNotificationsWS/UI.asmx?wsdl" -Namespace WebServiceProxy -Credential $Credential
$applicationUri = "page:http://mediaroomserver.com/FTCPFApps/STBScrollingMessages/MediaroomPage.aspx"
ForEach ($FTCSTBExternalID in $FTCSTBExternalIDs)
{
$msg_time = Get-Date -UFormat "%Y-%m-%d %r"
$message = $msg_time+' - FTC Account Number: "'+$FTCSTBExternalID.Acct_Number+'", Device ID: "'+$FTCSTBExternalID.Ext_Device_ID+'"' | Out-File $log_file -Append
$guid = $OSSNBranchWS.LaunchClientApplication($FTCSTBExternalID.Ext_Device_ID,$applicationUri)
}
It looks like I need to change "$FTCSTBExternalID" into the WebserviceProxy object and add the property "ExternalID" to it, and add "$FTCSTBExternalID.Ext_Device_ID" to it. But I cannot seem to get that right.
Any help would be greatly appreciated.
Thanks.
I'm doing a script to import CSVs (commands) that update the stock in SQL Server. But I encounter this error when I run the following script:
Invoke-Sqlcmd : La conversion de la valeur varchar '2200100001' a dépassé une colonne int.
L'instruction a été arrêtée.
Au caractère C:\Users\admin\Desktop\updateDb.ps1:36 : 19
+ ... $impcsv = Invoke-Sqlcmd -Database $db_name -Query $query -ServerIns ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation : (:) [Invoke-Sqlcmd], SqlPowerShellSqlExecutionException
+ FullyQualifiedErrorId : SqlError,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand
Here is my powershell script:
$sql_instance_name = 'SERVER\SAGE100'
$db_name = 'SERVER_DB'
$table = "dbo.F_ARTSTOCK"
$csv_folder = 'F:\EUR'
$csv_completed_folder = 'F:\EUR\done'
$batchsize = 50000
$csv_files = Get-Childitem -Path $csv_folder -Filter '*.csv'
$connectionstring = "Data Source=$sql_instance_name;Integrated Security=true;Initial Catalog=$db_name;"
$bulkcopy = New-Object Data.SqlClient.SqlBulkCopy($connectionstring, [System.Data.SqlClient.SqlBulkCopyOptions]::TableLock)
$bulkcopy.DestinationTableName = $table
$bulkcopy.bulkcopyTimeout = 0
$bulkcopy.batchsize = $batchsize
foreach($file in $csv_files) {
$impcsv = $file.FullName
write-host "Processing file ..........$impcsv" -foregroundcolor green
$data = import-csv -Delimiter ";" $impcsv
$count = 1
foreach($i in $data) {
Write-Host $i.Reference
$reference = $i.Reference
$quantity = $i.Quantity
$query = "UPDATE dbo.F_ARTSTOCK (AR_Ref,AS_QteSto)
SET dbo.F_ARTSTOCK.AS_QteSto = dbo.F_ARTSTOCK.AS_QteSto - $quantity
WHERE dbo.F_ARTSTOCK.AR_Ref = $reference"
Write-Host $query
$impcsv = invoke-sqlcmd -Database $db_name -Query $query -ServerInstance $sql_instance_name
write-host "Processing row ..........$count" -foregroundcolor green
$count = $count + 1
}
}
Do you have any idea where the problem would come from?
Thank you for your help.
The error message is in french. Translated it reads: The conversion of the '2200100001' varchar value has exceeded an int column. The instruction has been stopped.
Basically what that means is you have a 32-bit int column on that table and it needs to be of bigint type to handle a larger value... Or go through the data that you're trying to submit and verify that it is accurate (aka: remove that row from the csv. Depending on how sensitive of data you are working on).
I have my method which (unless I did something stupid) worked perfectly yesterday for exporting to csv. However, today I keep getting this erro:
Exception calling "Fill" with "1" argument(s): "ExecuteReader: CommandText property has not been initialized"
$rowCount=$SqlAdapter.Fill($dt)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : NotSpecified: (:) [], MethodInvocationException
FullyQualifiedErrorId : InvalidOperationException
And this is my syntax:
$server = "serverinstance"
$database = "databaseinstance"
$savefile = "C:\Test\sqlresults.csv"
$SelectQuery = "Select Top 1 * from madeuptable"
$connectionTemplate = "Data Source={0};Integrated Security=SSPI;Initial Catalog={1};"
$connectionString = [string]::Format($connectionTemplate, $server, $database)
$connection=New-Object System.Data.SqlClient.SqlConnection($connectionString)
$cmd=$connection.CreateCommand()
$cmd.CommandText = $SelectQuery
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
$dt = New-Object System.Data.DataTable
$rowCount=$SqlAdapter.Fill($dt)
if ($rowCount -gt 0) { $dt| Export-Csv $savefile -encoding UTF8 -NoTypeInformation }
$connection.Close()
Try creating the SqlDataAdaper using the query and the connection instead (and drop the cmd).
Example:
$SqlAdapter = new-object system.data.sqlclient.sqldataadapter ($SelectQuery, $connection)
I would check your $server and $database variables. I just ran your script against my own SQL server and it worked just fine for me.
EDIT:
Here is what I ran:
$server = "FAR-L2484\HOLDER_SQL" ## Hostname\InstanceID
$database = "MASTER"
$savefile = "C:\Test\sqlresults.csv"
$SelectQuery = "SELECT * FROM information_schema.tables"
$connectionTemplate = "Data Source={0};Integrated Security=SSPI;Initial Catalog={1};"
$connectionString = [string]::Format($connectionTemplate, $server, $database)
$connection=New-Object System.Data.SqlClient.SqlConnection($connectionString)
$cmd=$connection.CreateCommand()
$cmd.CommandText = $SelectQuery
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
$dt = New-Object System.Data.DataTable
$rowCount=$SqlAdapter.Fill($dt)
$dt| Export-Csv $savefile -encoding UTF8 -NoTypeInformation
$connection.Close()
and this is what I got in C:\test\sqlresults.csv
"TABLE_CATALOG","TABLE_SCHEMA","TABLE_NAME","TABLE_TYPE"
"master","dbo","spt_fallback_db","BASE TABLE"
"master","dbo","spt_fallback_dev","BASE TABLE"
"master","dbo","spt_fallback_usg","BASE TABLE"
"master","dbo","spt_values","VIEW"
"master","dbo","spt_monitor","BASE TABLE"
"master","dbo","MSreplication_options","BASE TABLE"
Is there a way to execute an arbitrary query on a SQL Server using Powershell on my local machine?
For others who need to do this with just stock .NET and PowerShell (no additional SQL tools installed) here is the function that I use:
function Invoke-SQL {
param(
[string] $dataSource = ".\SQLEXPRESS",
[string] $database = "MasterData",
[string] $sqlCommand = $(throw "Please specify a query.")
)
$connectionString = "Data Source=$dataSource; " +
"Integrated Security=SSPI; " +
"Initial Catalog=$database"
$connection = new-object system.data.SqlClient.SQLConnection($connectionString)
$command = new-object system.data.sqlclient.sqlcommand($sqlCommand,$connection)
$connection.Open()
$adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
$dataset = New-Object System.Data.DataSet
$adapter.Fill($dataSet) | Out-Null
$connection.Close()
$dataSet.Tables
}
I have been using this so long I don't know who wrote which parts. This was distilled from others' examples, but simplified to be clear and just what is needed without extra dependencies or features.
I use and share this often enough that I have turned this into a script module on GitHub so that you can now go to your modules directory and execute git clone https://github.com/ChrisMagnuson/InvokeSQL and from that point forward invoke-sql will automatically be loaded when you go to use it (assuming your using PowerShell v3 or later).
You can use the Invoke-Sqlcmd cmdlet
Invoke-Sqlcmd -Query "SELECT GETDATE() AS TimeOfQuery;" -ServerInstance "MyComputer\MyInstance"
http://technet.microsoft.com/en-us/library/cc281720.aspx
This function will return the results of a query as an array of powershell objects so you can use them in filters and access columns easily:
function sql($sqlText, $database = "master", $server = ".")
{
$connection = new-object System.Data.SqlClient.SQLConnection("Data Source=$server;Integrated Security=SSPI;Initial Catalog=$database");
$cmd = new-object System.Data.SqlClient.SqlCommand($sqlText, $connection);
$connection.Open();
$reader = $cmd.ExecuteReader()
$results = #()
while ($reader.Read())
{
$row = #{}
for ($i = 0; $i -lt $reader.FieldCount; $i++)
{
$row[$reader.GetName($i)] = $reader.GetValue($i)
}
$results += new-object psobject -property $row
}
$connection.Close();
$results
}
Here's an example I found on this blog.
$cn2 = new-object system.data.SqlClient.SQLConnection("Data Source=machine1;Integrated Security=SSPI;Initial Catalog=master");
$cmd = new-object system.data.sqlclient.sqlcommand("dbcc freeproccache", $cn2);
$cn2.Open();
if ($cmd.ExecuteNonQuery() -ne -1)
{
echo "Failed";
}
$cn2.Close();
Presumably you could substitute a different TSQL statement where it says dbcc freeproccache.
If you want to do it on your local machine instead of in the context of SQL server then I would use the following. It is what we use at my company.
$ServerName = "_ServerName_"
$DatabaseName = "_DatabaseName_"
$Query = "SELECT * FROM Table WHERE Column = ''"
#Timeout parameters
$QueryTimeout = 120
$ConnectionTimeout = 30
#Action of connecting to the Database and executing the query and returning results if there were any.
$conn=New-Object System.Data.SqlClient.SQLConnection
$ConnectionString = "Server={0};Database={1};Integrated Security=True;Connect Timeout={2}" -f $ServerName,$DatabaseName,$ConnectionTimeout
$conn.ConnectionString=$ConnectionString
$conn.Open()
$cmd=New-Object system.Data.SqlClient.SqlCommand($Query,$conn)
$cmd.CommandTimeout=$QueryTimeout
$ds=New-Object system.Data.DataSet
$da=New-Object system.Data.SqlClient.SqlDataAdapter($cmd)
[void]$da.fill($ds)
$conn.Close()
$ds.Tables
Just fill in the $ServerName, $DatabaseName and the $Query variables and you should be good to go.
I am not sure how we originally found this out, but there is something very similar here.
There isn't a built-in "PowerShell" way of running a SQL query. If you have the SQL Server tools installed, you'll get an Invoke-SqlCmd cmdlet.
Because PowerShell is built on .NET, you can use the ADO.NET API to run your queries.
Invoke-Sqlcmd -Query "sp_who" -ServerInstance . -QueryTimeout 3
To avoid SQL Injection with varchar parameters you could use
function sqlExecuteRead($connectionString, $sqlCommand, $pars) {
$connection = new-object system.data.SqlClient.SQLConnection($connectionString)
$connection.Open()
$command = new-object system.data.sqlclient.sqlcommand($sqlCommand, $connection)
if ($pars -and $pars.Keys) {
foreach($key in $pars.keys) {
# avoid injection in varchar parameters
$par = $command.Parameters.Add("#$key", [system.data.SqlDbType]::VarChar, 512);
$par.Value = $pars[$key];
}
}
$adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
$dataset = New-Object System.Data.DataSet
$adapter.Fill($dataset) | Out-Null
$connection.Close()
return $dataset.tables[0].rows
}
$connectionString = "connectionstringHere"
$sql = "select top 10 Message, TimeStamp, Level from dbo.log " +
"where Message = #MSG and Level like #LEVEL"
$pars = #{
MSG = 'this is a test from powershell'
LEVEL = 'aaa%'
};
sqlExecuteRead $connectionString $sql $pars
You can even format string and pass parameters as you want.
case "ADDSQLSERVERUSER":
//0 = coprorateName;
//1 = user password
//2 = servername
command = #"$sqlQuery = Use JazzUWS_'{0}'
Create login UWSUser_'{0}' with password='{1}';
Create user UWSUser_'{0}' for login UWSUser_'{0}';
Grant Execute to UWSUser_'{0}';
Use ReportSvrUWS_'{0}'
Create user UWSUser_'{0}' for login UWSUser_'{0}';
Grant Execute to UWSUser_'{0}';
Invoke-Sqlcmd -Query $sqlQuery -ServerInstance '{2}'";
break;
C# Code for remote execution(you can organize your way)
string script = PowershellDictionary.GetPowershellCommand("ADDSQLSERVERUSER");
script = String.Format(script, this.CorporateName, password, this.SQLServerName)
PowerShellExecution.RunScriptRemote(_credentials.Server, _credentials.Username, _credentials.Password, new List<string> { script });
You could use the best SQL Server module around: DBATOOLS. You would also benefit from running a query to multiple sql instances.
Install-Module dbatools -Scope CurrentUser
$sql = 'SQL1','SQL1\INSTANCE1','SQL2'
$query = "SELECT 'This query would run on all SQL instances'"
Invoke-DbaQuery -SqlInstance $sqlinstances -Query $query -AppendServerInstance