I am new to perl. I am given a task to connect to SQL server management 2012 and print a table from the database. Can you please guide me how to install all the drivers required and advise me what is wrong with my code, as i get no error and no required output.
use DBI;
my $host = 'programer'; #servername
my $database = 'DW'; #database name
my $user = 'prg'; #username
my $pwd = 'prg#123'; #password
my $dsn = "dbi:ODBC:Driver={SQL Server};Server=$host;Database=$database";
my $dbh = DBI->connect($dsn, $user, $pwd) or die("database not found");
$query="select * from Banking_AccountSummary_Citibank";
$exe=$dbh->prepare($query) or die("cannot prepapre query");
$exe->execute()or die("cannot execute");
$dbh->disconnect
Please guide me...
There is nothing wrong with your code. You don't need to install anything if you have use strict and use warnings and your code does not issue any warnings and does not die.
All you need to do is fetch your results and output them, or do whatever you want to do.
use Data::Dump;
my $exe = $dbh->prepare("select * from Banking_AccountSummary_Citibank")
or die("cannot prepapre query");
$exe->execute()
or die("cannot execute");
while (my $res = $exe->fetchrow_hashref) {
dd $res;
}
There are several ways to fetch your data and fetchrow_hashref is only one of them. I suggest you read the documentation of DBI and look at the examples given there.
Note: the convention is to name your statement handles $sth, just like the database handle is named $dbh. That will help others read your code.
Related
We are going to migrate from SQL Server 2008 to 2016. I am in the process of identifying errors and I get the following error in a trigger:
Incorrect syntax near '51001'.
I looked through the Raiserror documentation on the Microsoft website and it did not help. The following is the SQL. Any help would be appreciated.
IF (SELECT count(*) FROM dbo.u_sample_concrete ref, deleted
WHERE ref.lab_cd = deleted.lab_id) > 0
BEGIN
RAISERROR 51001 ''Trigger td_tblLAB on table dbo.tblLAB: Primary key values found in table dbo.u_sample_concrete (lab_cd). Delete restricted; the transaction is being rolled back.''
ROLLBACK TRANSACTION
RETURN
END
Adding to #DaleK's answer with the proper syntax, the problem RAISERRROR syntax is long obsolete. IIRC, it was deprecated 20 years ago (with the SQL Server 2000 release) and removed entirely in SQL Server 2012.
Below is a powershell script that uses the T-SQL Script DOM (also available with the Dacfx NuGet package) to identify existing T-SQL modules with invalid syntax. It won't catch problems in dynamic SQL, though.
$connectionString = "Data Source=.;Initial Catalog=YourDatabase;Integrated Security=SSPI"
try {
$query = #"
SELECT
QUOTENAME(OBJECT_SCHEMA_NAME(object_id)) + N'.' + QUOTENAME(OBJECT_NAME(object_id)) AS ObjectName
, OBJECTPROPERTY(object_id, 'ExecIsQuotedIdentOn') AS ExecIsQuotedIdentOn
, definition
FROM sys.sql_modules;
"#
Add-Type -Path "C:\Program Files (x86)\Microsoft SQL Server\140\DAC\bin\Microsoft.SqlServer.TransactSql.ScriptDom.dll"
$connection = New-Object Data.SqlClient.SqlConnection($connectionString)
$command = New-Object Data.SqlClient.SqlCommand($query, $connection)
$connection.Open()
$reader = $command.ExecuteReader()
while ($reader.Read()) {
# use TSqlParser appropriate for your SQL Server version
$parser = New-Object Microsoft.SqlServer.TransactSql.ScriptDom.TSql130Parser($reader["ExecIsQuotedIdentOn"])
$parseErrors = New-Object Collections.Generic.List[Microsoft.SqlServer.TransactSql.ScriptDom.ParseError]
$scriptReader = New-Object IO.StringReader($($reader["definition"]))
Write-Host "Parsing $($reader["ObjectName"]) ..."
[void]$parser.Parse($scriptReader, [ref]$parseErrors)
if($parseErrors.Count -ne 0) {
Write-Host "Parsing errors for object $($reader["ObjectName"]): $($parseErrors | ConvertTo-Json)" -ForegroundColor Yellow
}
}
$connecton.Close()
}
catch {
throw
}
The Microsoft Documentation does indeed show 4 things wrong with your statement.
The parameters must be inside brackets raiserror().
4 parameters are expected when msd_id (51001) is used - you are providing 2.
Parameters should be separated by commas ,.
You are double quoting the string, when it should be single quoted.
RAISERROR (51001, -1,- 1, 'Trigger td_tblLAB on table dbo.tblLAB: Primary key values found in table dbo.u_sample_concrete (lab_cd). Delete restricted; the transaction is being rolled back.')
Note: its best practice now to use throw rather than raiserror.
I'm trying to call a maintenance SP from within an Azure runbook:
inlinescript {
.........
$Cmd = New-object System.Data.SqlClient.SqlCommand
$Cmd.Connection = $Conn
$Cmd.CommandText = "EXEC [dbo].[BackupLogTable] #tableName, #olderThan"
$Cmd.Parameters.AddWithValue("#tableName", $TableName)
$Cmd.Parameters.AddWithValue("#olderThan", $OlderThan)
$Cmd.ExecuteNonQuery()
.....
}
The SP is declared like this:
alter procedure [dbo].[BackupLogTable] (
#tableName nvarchar(512),
#olderThan int
)
with execute as owner as
and I can successfully run it from SSMS under the same user my runbook uses. But when testing it in Azure portal I'm getting the following error:
Exception calling "ExecuteNonQuery" with "0" argument(s): "The
parameterized query '(#tableName nvarchar(4000),#olderThan
nvarchar(4000))EXEC [dbo].' expects the parameter '#tableName', which
was not supplied."
I tried every other variants of passing the parameters found on the net like this one:
$Cmd.CommandText = "[BackupLogTable]"
$Cmd.CommandType = [System.Data.CommandType]::StoredProcedure
$Cmd.Parameters.Add("#tableName", [System.Data.SqlDbType]::NVarChar, 512) | Out-Null
$Cmd.Parameters["#tableName"].Value = $TableName
$Cmd.Parameters.Add("#olderThan", [System.Data.SqlDbType]::Int) | Out-Null
$Cmd.Parameters["#olderThan"].Value = $OlderThan
and many others but it always fails:
Exception calling "ExecuteNonQuery" with "0" argument(s): "Procedure
or function 'BackupLogTable' expects parameter '#tableName', which
was not supplied."
What am I doing wrong?
How are you passing your parameters to your inline script?
There's some limitations; e.g. Get-AutomationVariable / AutomationCredential is not available in the InlineScript.
"The InlineScript activity runs a block of commands in a separate, non-workflow session and returns its output to the workflow. While commands in a workflow are sent to Windows Workflow Foundation for processing, commands in an InlineScript block are processed by Windows PowerShell. The activity uses the standard workflow common parameters including PSComputerName and PSCredential which allow you to specify that the code block be run on another computer or using alternate credentials."
So, there's some limitations on how to pass and get variables.
However you can pass values into the inlinescript using $Using.
E.g: InlineScript { Write-output $using:TableName }
Hopefully that'd do the trick.
See also the recommendations for inlinescript on: https://technet.microsoft.com/en-us/library/dn469257(v=sc.16).aspx#bkmk_InlineScript
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
#!/usr/bin/perl
use DBI;
use Data::Dumper;
use strict;
my $DSN = q/dbi:ODBC:SQLSERVER/;
my $uid = q/username/;
my $pwd = q/password/;
my $first_param=723454;
my $current_date="2012-10-25 00:30:21";
my $after_2min="2012-10-25 05:47:41";
my $dbh = DBI->connect($DSN,$uid,$pwd) or die "Coudn't Connect SQL";
my $sql2 = "insert reverise_call_main_menu call_number,call_originate_time,call_inbetween_time,call_after_2min_time) values(?,?,?,?)";
my $sth2 = $dbh->prepare($sql2);
$sth2->execute($first_param,$current_date,'null',$after_2min);
$sth2->finish;
$dbh->disconnect;
whenever i execute a program i got following error:
output:-
DBD::ODBC::st execute failed: [unixODBC][FreeTDS][SQL Server]Conversion failed when converting datetime from character string. (SQL-22007)
The error message indicates that SQL Server does not like the format of your datetime strings. You may wish to use DateTime::Format::DBI to help get the formatting right.