I needed to query Oracle for information to use in a Powershell script. I found the following comprehensive blog post with details on how to do so using ODP.NET: Use Oracle ODP.NET and PowerShell to Simplify Data Access
The article is extremely long and goes into a lot of depth. The following is a short summary of the first steps, with just enough to get started:
- Download Oracle Data Provider for .NET (ODP.NET). (If that link doesn’t work just search for “Oracle ODP.NET”.)
- Select “Download the latest ODP.NET production release.”
- Select “64-bit ODAC Downloads”
- Select “ODP.NET_Managed_ODAC12cR4.zip”
- Extract the ZIP file to
C:\
, which createsC:\ODP.NET_Managed_ODAC12cR4
. - Run
cmd
as administrator, navigate to C:\ODP.NET_Managed_ODAC12cR4, and run:
install_odpm.bat C:\oracle\instantclient_10_2 both
In Powershell, add the DLL and set up a database connection and a query:
Add-Type -Path "C:\Users\chris\ODP.NET_Managed_ODAC12cR4\odp.net\managed\common\Oracle.ManagedDataAccess.dll"
$username = Read-Host -Prompt "Enter database username"
$password = Read-Host -Prompt "Enter database password"
$datasource = Read-Host -Prompt "Enter database TNS name"
$query = "SELECT first_name, last_name FROM users.user WHERE first_name = 'Chris' ORDER BY last_name"
$connectionString = 'User Id=' + $username + ';Password=' + $password + ';Data Source=' + $datasource
$connection = New-Object Oracle.ManagedDataAccess.Client.OracleConnection($connectionString)
$connection.open()
$command=$connection.CreateCommand()
$command.CommandText=$query
$reader=$command.ExecuteReader()
while ($reader.Read()) {
$reader.GetString(1) + ', ' + $reader.GetString(0)
}
$connection.Close()
Output of the above:
Brown, Chris
Carter, Chris
Jones, Chris
Smith, Chris
sorry if it’s a dumb question, but what exactly is the data source? i downloaded oracle XE and spun up a database, but i’m not sure how to specify the data source to connect to it..
Hi Billy Crystal.
The data source, the instance name for your oracle instance you want to connec to.
Nice post, I will try to use it.
Bill Crystal, here is the answer : you have to define the connection string on file ” tnsnames.ora” and then use the alias for the oracle server OR you can do it directly!!! Check this web page, it’ll give you all the info you need!
https://www.connectionstrings.com/oracle-data-provider-for-net-odp-net/
Thanks for this!!! I can successfully query an Oracle DB because you started me down the right path.
Regards!
Beware. If your database employs encryption this won’t work. ODP.NET shipped in a broken state and cannot support databases which use encryption. Don’t waste a day on this like I did.
Did anyone get:
Exception calling “GetString” with “1” argument(s): “Specified cast is not valid.”
Disregard my previous question. I found the issue. One of my table columns was not a string and I wasn’t aware (didn’t set the table up and this is the first time I’ve used powershell to read from an Oracle database).
Next question, what does $reader.read() do? I’m trying to comment my script and need to understand the purpose of this snippet of code.
@Josh, the
Read()
method [.NET is not, apparently, case-sensitive] advances the Reader object to the next record returned by the query. Before it is called the first time, the Reader object is not yet pointing to any records. IfRead()
is called and there are no further records, it returnsfalse
(otherwise it returnstrue
).The full documentation for the
OracleDataReader.Read()
method is available at https://msdn.microsoft.com/en-us/library/system.data.oracleclient.oracledatareader.read(v=vs.110).aspxThanks, Chris
Is there a way to check the previous row in this while statement?
Greetings, thank you very much for the information, I have an error when starting the connection and I would like to know if you can help me, in the line of “Add-Type -Path” I add the path where the dll is found and I get the following error:
Is there a way to check if the connection between Powershell and the Oracle database failed to connect? Has anyone ever done anything like this?
I built it as a function and created a test switch to check the connection if it was successful or not.
I called the function Open-OracleConnection and run it like this
Open-OracleConnection -sid -user -password -test
There’s more to it obviously. Be sure to always close the connection when done.
.....
$connectionString = 'User id=' + $User + ';Password=' + $Password + `
';Data Source=' + $SID
$Connection = New-Object Oracle.ManagedDataAccess.Client.OracleConnection($connectionString)
$connection.open()
if ($test)
{
$Connection
$Connection.Close()
break;
.....
The output should show you values like State, if closed then something happened that caused the connection to fail. If successful you should see values for ServerVersion,InstanceName, and Hostname.
I followed the same steps and getting PowerShell error,
Exception calling “Open” with “0” argument(s): “ORA-12154: TNS:could not resolve the connect identifier specified”
At C:\…..\Untitled3.ps1:8 char:1
+ $connection.open()
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : OracleException
Exception calling “ExecuteReader” with “0” argument(s): “Connection must be open for this operation”
At C:\………\Untitled3.ps1:11 char:1
+ $reader=$command.ExecuteReader()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : InvalidOperationException
You cannot call a method on a null-valued expression.
At C:\…………\Untitled3.ps1:12 char:8
+ while ($reader.Read()) {
+ ~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
This was very helpful. Thank you
I am unable to run SHUTDOWN IMMEDIATE. Will it require anything other than sysdba privileges which my user already has?
@Feby I am with the same error
Some help? Where does the TNSnames.ora file have to be?
@Feby same error: