使用Oracle Managed Driver Core的asp.net core docker容器。打开连接时抛出ORA-00604和ORA-01882

时间:2018-11-27 23:50:54

标签: c# oracle docker .net-core

当我尝试从Docker容器内部使用针对dotnet core(https://www.nuget.org/packages/Oracle.ManagedDataAccess.Core/)的Oracle托管数据访问连接到oracle数据库时,收到以下异常。我没有在docker

之外收到异常

复制步骤:

  1. 打开VS 2017
  2. 文件>新建>项目...
  3. Visual C#> .Net Core> ASP.Net Core Web应用程序
  4. 点击确定
  5. 选择“ Web应用程序(模型-视图-控制器)”
  6. 取消选中“已启用Docker支持”
  7. 取消选中“配置HTTPS”
  8. 点击确定
  9. 在程序包管理器控制台中,执行Install-Package Oracle.ManagedDataAccess.Core -Source nuget.org -Version 2.18.3
  10. 将代码粘贴到HomeController.Index方法中
  11. 在行con.Open();上设置断点
  12. 单击“调试”“ IIS Express”按钮
  13. 尝试打开连接时不会引发异常。
  14. 停止调试
  15. 在解决方案资源管理器中右键单击Web项目>添加> Docker支持
  16. 选择“ Linux”单选按钮,然后单击“确定”
  17. 在解决方案资源管理器中右键单击Web项目>添加>容器协调器支持
  18. 在下拉列表中选择“ Docker Compose”,然后单击“确定”(取决于安装的Visual Studio 2017版本,这可能会有所不同)
  19. 如果显示任何弹出窗口要求覆盖文件,请单击“是”。
  20. 单击“调试”“ Docker Compose”按钮
  21. 尝试打开连接时将引发异常

代码:

var strm = new Oracle.ManagedDataAccess.Client.OracleConnectionStringBuilder();
strm.UserID = "<username>";
strm.Password = "<password>";
strm.DataSource = "(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=<db_host>)(PORT = 1521))) (CONNECT_DATA=(SERVICE_NAME=<service_name>)))";
using (var con = new Oracle.ManagedDataAccess.Client.OracleConnection(strm.ConnectionString))
{
     con.Open(); // Exception thrown here.
}

例外:

Exception in VS

Oracle.ManagedDataAccess.Client.OracleException
  HResult=0x80004005
  Message=ORA-00604: error occurred at recursive SQL level 1
ORA-01882: timezone region not found
  Source=Oracle Data Provider for .NET, Managed Driver
  StackTrace:
   at OracleInternal.ConnectionPool.PoolManager`3.Get(ConnectionString csWithDiffOrNewPwd, Boolean bGetForApp, OracleConnection connRefForCriteria, String affinityInstanceName, Boolean bForceMatch)
   at OracleInternal.ConnectionPool.OraclePoolManager.Get(ConnectionString csWithNewPassword, Boolean bGetForApp, OracleConnection connRefForCriteria, String affinityInstanceName, Boolean bForceMatch)
   at OracleInternal.ConnectionPool.OracleConnectionDispenser`3.Get(ConnectionString cs, PM conPM, ConnectionString pmCS, SecureString securedPassword, SecureString securedProxyPassword, OracleConnection connRefForCriteria)
   at Oracle.ManagedDataAccess.Client.OracleConnection.Open()
   at WebApplication8.Controllers.HomeController.Index() in C:\Users\me\source\repos\WebApplication8\WebApplication8\Controllers\HomeController.cs:line 22
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__12.MoveNext()

更新:

我根据下面的@silent答案进行了其他测试,发现了一些有趣的东西。如果我回滚到ODP.Net核心(2.12.0-beta3)的版本https://www.nuget.org/packages/Oracle.ManagedDataAccess.Core,并删除了TZ = America / Denver环境变量,则可以正确打开连接。似乎在2.18.3中引入了一些内容,导致在docker容器内打开连接时导致需要TZ环境变量。

1 个答案:

答案 0 :(得分:4)

我只是在类似的环境(Oracle DB 11.2.0.4.0和NuGet包Oracle.ManagedDataAccess.Core 2.18.3)中找到了该解决方案:

在容器中添加一个名为TZ的环境变量,并将其值设置为您的时区,例如CET

这使我可以打开连接。然后,我还可以使用this解决方案中的部分来设置会话信息

this.Connection = new OracleConnection();
this.Connection.ConnectionString = ...
this.Connection.Open();
OracleGlobalization info = this.Connection.GetSessionInfo();
info.TimeZone = "America/New_York";
this.Connection.SetSessionInfo(info);