代码之家  ›  专栏  ›  技术社区  ›  Maurice

Powershell与Oracle数据库的连接

  •  8
  • Maurice  · 技术社区  · 9 年前

    Oracle.ManagedDataAccess.dll .

    this Technet上的教程,并以以下代码结束:

    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
    • 我把不应该透露的内容替换为 XXXX年
    • 32位和64位Powershell实例的错误相同
    • 在第一次运行之前 没有加载,在运行之后,它会一直加载,直到我关闭外壳

    5 回复  |  直到 7 年前
        1
  •  11
  •   Maurice    9 年前

    我不确定这在技术上是否是一个解决方案——我更愿意将其归类为一种变通方法,但它对我来说很有效。


    在做了更多的研究后,我找到了一个合适的替代方案 Oracle.ManagedDataAccess.dll .我找到了 System.Data.OracleClient Net Framework的类。(它需要安装一个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() }
    }
    
        2
  •  3
  •   DrFloyd5    7 年前

    使用服务器:端口/服务语法。

    $dataSource="server.network:1522/service1.x.y.z"
    
        3
  •  1
  •   Allen    5 年前

    这是我的(Powershell,但您可以使用C#)代码来使用ODP实现这一点。NET managed data access…。我使用Powershell Add类型直接加载它,但在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;
    
    }
    
    1. 获取连接:
    $con = New - OracleConnection;
    
    1. 根据需要打开/关闭(默认为打开…)

    ... if($con.State-ne[系统数据连接状态]::打开){ $con.Open()#

    1. 使用它,然后关闭/处置。。。
        $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();
            
    
        4
  •  0
  •   Dennis    7 年前

    这很可能是oracle 12.2.x的一个问题
    SQLNET.ALLOWED\u LOGON\u VERSION\u CLIENT=8 SQLNET.ALLOWED\u LOGON\u VERSION\u SERVER=8

        5
  •  -1
  •   user1783074    9 年前

    我遇到了完全相同的问题,我从ODAC版本12.2.0.1.0切换到了版本11.2.O.3,打开连接和读取数据就像一种魅力。希望这有帮助。 谢谢