Crystal Reports 13.0.35运行时连接Oracle 11g取错库数据问题
Crystal Reports 13连接Oracle 11g时运行时切换数据库失效问题解决
问题描述
使用Crystal Reports 13.0.35版本,通过本地Oracle客户端连接远程Oracle 11g数据库,web.config中Oracle提供者为OraOLEDB.Oracle,框架版本为4.0。尽管已在运行时修改连接配置,但使用数据源中表的报表仍显示错误数据库的数据。
- 特殊情况:使用命令或.xsd文件的报表可正常工作;所有Crystal Reports在SQL Server环境下均运行正常。
代码问题分析
- 语法与拼写错误:代码存在多处变量名拼写错误(如
crConninto应为crConnInfo、user ID应为userID、tableLogin Info应为tableLoginInfo),还有未闭合的括号、路径分隔符错误(crdb_oracle/dll应为crdb_oracle.dll),这些错误直接导致连接逻辑未正确执行。 - Oracle连接配置逻辑混乱:
- 先将
dataBase设为空,后续又从连接字符串读取Database赋值给crConnInfo.DatabaseName,之后再清空,逻辑冲突。 - 错误配置了Oracle原生驱动
crdb_oracle.dll,但当前使用的是OraOLEDB.Oracle提供者,应匹配OLEDB驱动配置。
- 先将
- 数据源连接处理错误:
- 执行
crReportDocument.DataSourceConnections.Clear()后直接访问DataSourceConnections[0],会引发索引越界,导致后续连接设置失效。 - 子报表处理中存在变量大小写不一致(
userId/PasswordvsuserID/password),导致登录信息错误。
- 执行
- 表连接信息未强制更新:仅调用
ApplyLogOnInfo后未强制刷新表的连接状态,Crystal Reports可能仍使用旧缓存连接。
修正后的代码
public static void ConnectDocToDB(CrystalDecisions.CrystalReports.Engine.ReportDocument crReportDocument, bool? IsDataset = false) { string serverName = GetConnStrSection(connectionstring.ConnectionString, "Data Source"); string dataBase = GetConnStrSection(connectionstring.ConnectionString, "Database"); string userID = GetConnStrSection(connectionstring.ConnectionString, "User Id"); string password = GetConnStrSection(connectionstring.ConnectionString, "Password"); // Oracle不需要DatabaseName参数,直接置空 if (globals.DataBaseEngine == "Oracle") dataBase = string.Empty; TableLogOnInfo tableLoginInfo = new TableLogOnInfo(); ConnectionInfo crConnInfo = new ConnectionInfo(); if (globals.DataBaseEngine == "Oracle" && IsDataset == false) { // 针对OraOLEDB.Oracle提供者配置连接属性 crConnInfo.Attributes.Collection.Add(new NameValuePair2(DbConnectionAttributes.CONNINFO_DATABASE_DLL, "crdb_oledb.dll")); crConnInfo.Attributes.Collection.Add(new NameValuePair2("QE_DatabaseType", "OLEDB")); crConnInfo.Attributes.Collection.Add(new NameValuePair2("QE_SQLDB", "1")); crConnInfo.Attributes.Collection.Add(new NameValuePair2("QE_ServerDescription", serverName)); crConnInfo.Attributes.Collection.Add(new NameValuePair2("Provider", "OraOLEDB.Oracle")); } // 配置核心连接信息 crConnInfo.ServerName = serverName; crConnInfo.DatabaseName = dataBase; crConnInfo.UserID = userID; crConnInfo.Password = password; tableLoginInfo.ConnectionInfo = crConnInfo; // 处理主报表的所有表,强制更新连接避免缓存 foreach (CrystalDecisions.CrystalReports.Engine.Table table in crReportDocument.Database.Tables) { table.ApplyLogOnInfo(tableLoginInfo); table.Location = table.Location; } // 处理子报表 foreach (CrystalDecisions.CrystalReports.Engine.ReportDocument supReport in crReportDocument.Subreports) { try { supReport.SetDatabaseLogon(userID, password, serverName, dataBase); } catch { } foreach (CrystalDecisions.CrystalReports.Engine.Table table in supReport.Database.Tables) { table.ApplyLogOnInfo(tableLoginInfo); table.Location = table.Location; } // 子报表数据源连接设置,先判断是否存在连接项 if (supReport.DataSourceConnections.Count > 0) { supReport.DataSourceConnections[0].SetConnection(serverName, dataBase, userID, password); } } // 主报表数据源连接设置,先判断是否存在连接项 if (crReportDocument.DataSourceConnections.Count > 0) { crReportDocument.DataSourceConnections[0].SetConnection(serverName, dataBase, userID, password); } }
额外注意事项
- 驱动匹配:确保服务器安装对应版本的Oracle OLEDB驱动(OraOLEDB.Oracle),且Crystal Reports的
crdb_oledb.dll存在于应用程序bin目录或Crystal Reports安装路径中。 - Oracle客户端配置:本地Oracle客户端需正确配置
tnsnames.ora,确保Data Source对应的服务名能正确解析到远程Oracle 11g数据库。 - 缓存清理:若报表仍显示旧数据,可在加载报表前调用
crReportDocument.Refresh()强制刷新数据,或禁用Crystal Reports的数据缓存。 - 权限验证:确保配置的数据库账号拥有访问目标表的权限,避免因权限问题导致数据读取异常。
内容的提问来源于stack exchange,提问作者sara
相关产品推荐
相关产品推荐

