我无法使用Oracle.ManagedDataAccess.dll
从Powershell连接到Oracle数据库。
我在Technet上关注了this教程,最后得到了这段代码:
add-type -path "C:\oracle\product\12.1.0\client_1\ODP.NET\managed\common\Oracle.ManagedDataAccess.dll"
$username = "XXXX"
$password = "XXXX"
$data_source = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=XXXX)(PORT=XXXX))(CONNECT_DATA = (SERVER=dedicated)(SERVICE_NAME=XXXX)))"
$connection_string = "User Id=$username;Password=$password;Data Source=$data_source"
try{
$con = New-Object Oracle.ManagedDataAccess.Client.OracleConnection($connection_string)
$con.Open()
} catch {
Write-Error (“Can’t open connection: {0}`n{1}” -f `
$con.ConnectionString, $_.Exception.ToString())
} finally{
if ($con.State -eq ‘Open’) { $con.close() }
}
不幸的是我收到了这个错误:
C:\Users\XXXX\Desktop\oracle_test.ps1 : Can’t open connection: User Id=XXXX;Password=XXXX;Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=XXXX)(PORT=XXXX))(CONNECT_DATA =
(SERVER=dedicated)(SERVICE_NAME=XXXX)))
System.Management.Automation.MethodInvocationException: Exception calling "Open" with "0" argument(s): "The type initializer for 'Oracle.ManagedDataAccess.Types.TimeStamp' threw an exception." --->
System.TypeInitializationException: The type initializer for 'Oracle.ManagedDataAccess.Types.TimeStamp' threw an exception. ---> System.Runtime.Serialization.SerializationException: Unable to find assembly
'Oracle.ManagedDataAccess, Version=4.121.2.0, Culture=neutral, PublicKeyToken=XXXX'.
at OracleInternal.Common.OracleTimeZone.GetInstance()
at Oracle.ManagedDataAccess.Types.TimeStamp..cctor()
--- End of inner exception stack trace ---
at OracleInternal.ConnectionPool.PoolManager`3.CreateNewPR(Int32 reqCount, Boolean bForPoolPopulation, ConnectionString csWithDiffOrNewPwd, String instanceName)
at OracleInternal.ConnectionPool.PoolManager`3.Get(ConnectionString csWithDiffOrNewPwd, Boolean bGetForApp, String affinityInstanceName, Boolean bForceMatch)
at OracleInternal.ConnectionPool.OraclePoolManager.Get(ConnectionString csWithNewPassword, Boolean bGetForApp, String affinityInstanceName, Boolean bForceMatch)
at OracleInternal.ConnectionPool.OracleConnectionDispenser`3.Get(ConnectionString cs, PM conPM, ConnectionString pmCS, SecureString securedPassword, SecureString securedProxyPassword)
at Oracle.ManagedDataAccess.Client.OracleConnection.Open()
at CallSite.Target(Closure , CallSite , Object )
--- End of inner exception stack trace ---
at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,oracle_test.ps1
tnsping
)Oracle.ManagedDataAccess.dll
没有加载,运行后它会一直加载,直到我关闭那个shell 不幸的是,我既不是Oracle也不是Powershell专家(我更喜欢MySQL和Python),因此我非常感谢您的任何想法和/或见解。
答案 0 :(得分:3)
我不确定这在技术上是否是一个解决方案 - 我将其更多地归类为解决方法,但它对我有用。
在做了一些研究后,我找到了Oracle.ManagedDataAccess.dll
的合适替代方案。我找到了.Net Framework的System.Data.OracleClient类。 (它需要一个已安装的Oracle客户端,幸运的是该机器)
以下是对我有用的解决方案概要:
add-type -AssemblyName System.Data.OracleClient
$username = "XXXX"
$password = "XXXX"
$data_source = "XXXX"
$connection_string = "User Id=$username;Password=$password;Data Source=$data_source"
$statement = "select level, level + 1 as Test from dual CONNECT BY LEVEL <= 10"
try{
$con = New-Object System.Data.OracleClient.OracleConnection($connection_string)
$con.Open()
$cmd = $con.CreateCommand()
$cmd.CommandText = $statement
$result = $cmd.ExecuteReader()
# Do something with the results...
} catch {
Write-Error (“Database Exception: {0}`n{1}” -f `
$con.ConnectionString, $_.Exception.ToString())
} finally{
if ($con.State -eq ‘Open’) { $con.close() }
}
答案 1 :(得分:1)
这是我的(Powershell,但您可以适应 C#)代码,用于通过 ODP.NET 托管数据访问来执行此操作......我使用 Powershell Add-Type 直接加载,但在 C# 中将是使用/引用...
function New - OracleConnection { <
#
.SYNOPSIS# generate a well - formed connection string with individual properties
Create and open a new Oracle connection using optional connectionstring argument
.DESCRIPTION
Create and open a new Oracle connection using optional connectionstring argument
.EXAMPLE
New - OracleConnection
New - OracleConnect - connectionString "My well-formed Oracle connections string"
.NOTES
Connection is opened here by
default# > #Add - Type - Path ".\Oracle.ManagedDataAccess.dll" [OutputType([Oracle.ManagedDataAccess.Client.OracleConnection])]
Param(
[Parameter(Mandatory = $false)]
[string] $theConnectionString, [Parameter(Mandatory = $false)]
[string] $openOnCreate = "1"#
means true - open the connection...
)[Oracle.ManagedDataAccess.Client.OracleConnection] $con = New - Object - TypeName Oracle.ManagedDataAccess.Client.OracleConnection;
if ([string]::IsNullOrEmpty($theConnectionString)) {#
$dataSource = "*********:1521/******;"
$conStringBuilder = New - Object Oracle.ManagedDataAccess.Client.OracleConnectionStringBuilder;
$conStringBuilder["Data Source"] = $dataSource;
$conStringBuilder["User ID"] = "*******";
$conStringBuilder["Password"] = "*******";
$conStringBuilder["Persist Security Info"] = $True;
$conStringBuilder["Connection Lifetime"] = 180;
$conStringBuilder["Connection Timeout"] = 10;
$conStringBuilder["Pooling"] = $true;
$conStringBuilder["Min Pool Size"] = 10;
$conStringBuilder["Max Pool Size"] = 20;
$conStringBuilder["Incr Pool Size"] = 5;
$conStringBuilder["Decr Pool Size"] = 2;
$conStringBuilder["Statement Cache Size"] = 200;
$conStringBuilder["Statement Cache Purge"] = $false;#
default
$con.ConnectionString = $conStringBuilder.ConnectionString;
} else {
$con.ConnectionString = $theConnectionString;
}
if (Get - IsTrue - yesNoArg $openOnCreate) {
if (-not(Get - ConnectionStateIsOpen($con))) {#
attempt open, ignore error
if already open.State is normally open after successful create
try {
$con.Open();
} catch {
$null;
}
}
}
Write - Output - NoEnumerate $con;
}
$con = New - OracleConnection;
... ... if ($con.State - ne[System.Data.ConnectionState]::Open) { $con.Open();# 没有我所知道的论据...... }
$sql = "SELECT * FROM YOUR_TABLE t WHERE t.SOMETHING = :the_parm";
[Oracle.ManagedDataAccess.Client.OracleCommand]$cmd = New-Object -TypeName Oracle.ManagedDataAccess.Client.OracleCommand;
$cmd.Connection = Get-OracleConnection;
$cmd.CommandText = $sql;
$cmd.BindByName = $true;
$dbType = ([Oracle.ManagedDataAccess.Client.OracleDbType]::VarChar2);
$cmd.Parameters.Add(( New-Param -name "the_parm" -type $dbType -size 15 )).Value = $the_criteria_value ;
Write-Output -NoEnumerate ($cmd.ExecuteScalar());
$cmd.Connection.Close();
$cmd.Dispose();
答案 2 :(得分:0)
我有完全相同的问题,我从ODAC版本12.2.0.1.0切换到版本11.2.0.3,它就像打开连接和读取数据的魅力一样。希望这可以帮助。 谢谢, SK
答案 3 :(得分:0)
这很可能是oracle 12.2.x的问题
我必须将以下行添加到数据库服务器上的sqlnet.ora文件中,以允许来自较早的oracle客户端的连接:
SQLNET.ALLOWED_LOGON_VERSION_CLIENT = 8
SQLNET.ALLOWED_LOGON_VERSION_SERVER = 8
一旦添加,我就可以使用oracle 10g和11g客户端登录
答案 4 :(得分:0)
使用server:port / service语法。
$dataSource="server.network:1522/service1.x.y.z"