on ‎2010 Feb 09 8:40 AM
<p>
I would like to use the <b>same report for several data base providers</b> (ODBC, OLEDB SqlServer and OLEDB Oracle).<br />
My original report is designed with ODBC by another department. When I try to change the data base provider to Oracle or SqlServer I have an error at line:<br />
<br /></p>
<code>
//this line throw an exception if the report was not designed with the
same database provider.<br />
switch (provider)<br />
{<br />
case Provider.SqlServer:<br />
crTable.Location =
String.Format("{0}.dbo.", crConnectionInfo.DatabaseName, crTable.Name); //database.dbo.tablename<br /> break;<br /> case Provider.Oracle:<br /> crTable.Location = String.Format(".", crConnectionInfo.DatabaseName, crTable.Name);
//schema.tablename<br />
break;<br />
default:<br />
break;<br />
}</code>
<p>Even setting the same location, like this crTable.Location = crTable.Location; the code throws an exception.
I have to change the report schema location at runtime because we have several databases (SqlServer) or schemas (Oracle) and we have to use the same report.
I use Crystal Reports Version=12.0.2000.0</p>
<br />
Here is my complete code:<br />
<code>
private CrystalDecisions.Shared.ConnectionInfo FixDatabaseSqlServer()<br />
{<br />
CrystalDecisions.Shared.DbConnectionAttributes dbAttributes = new
DbConnectionAttributes();<br />
dbAttributes.Collection.Set("Server", this.ServerName.Text);<br />
dbAttributes.Collection.Set("Trusted_Connection", "false");<br />
dbAttributes.Collection.Set("Data Source", this.ServerName.Text);<br />
dbAttributes.Collection.Set("Initial Catalog", this.DatabaseName.Text);<br />
dbAttributes.Collection.Set("Integrated Security", "false");<br />
dbAttributes.Collection.Set("Provider", "SQLOLEDB");<br />
<br />
//setup the connection <br />
CrystalDecisions.Shared.ConnectionInfo crConnectionInfo = new ConnectionInfo();<br />
crConnectionInfo.DatabaseName = this.DatabaseName.Text;<br />
crConnectionInfo.ServerName = this.ServerName.Text;<br />
crConnectionInfo.UserID = this.UserID.Text;<br />
crConnectionInfo.Password = this.Password.Text;<br />
crConnectionInfo.IntegratedSecurity = false;<br />
crConnectionInfo.Attributes.Collection.Set("Database DLL", "crdb_ado.dll");<br />
crConnectionInfo.Attributes.Collection.Set("QE_DatabaseName",
this.DatabaseName.Text);<br />
crConnectionInfo.Attributes.Collection.Set("QE_DatabaseType", "OLE DB (ADO)");<br />
crConnectionInfo.Attributes.Collection.Set("QE_LogonProperties", dbAttributes);<br />
crConnectionInfo.Attributes.Collection.Set("QE_ServerDescription",
this.ServerName.Text);<br />
crConnectionInfo.Attributes.Collection.Set("QE_SQLDB", "True");<br />
crConnectionInfo.Attributes.Collection.Set("SSO Enabled", "False");<br />
crConnectionInfo.Type = CrystalDecisions.Shared.ConnectionInfoType.CRQE;<br />
crConnectionInfo.LogonProperties = dbAttributes.Collection;<br />
<br />
return (crConnectionInfo);<br />
}<br />
<br />
private CrystalDecisions.Shared.ConnectionInfo FixDatabaseOracle()<br />
{<br />
CrystalDecisions.Shared.DbConnectionAttributes dbAttributes = new
DbConnectionAttributes();<br />
dbAttributes.Collection.Set("Server", this.ServerName.Text);<br />
dbAttributes.Collection.Set("Trusted_Connection", "False");<br />
dbAttributes.Collection.Set("Data Source", this.ServerName.Text);<br />
dbAttributes.Collection.Set("Provider", "MSDAORA");<br />
<br />
//setup the connection <br />
CrystalDecisions.Shared.ConnectionInfo crConnectionInfo = new ConnectionInfo();<br />
crConnectionInfo.DatabaseName = "";<br />
crConnectionInfo.ServerName = this.ServerName.Text;<br />
crConnectionInfo.UserID = this.UserID.Text;<br />
crConnectionInfo.Password = this.Password.Text;<br />
crConnectionInfo.IntegratedSecurity = false;<br />
crConnectionInfo.Attributes.Collection.Set("Database DLL", "crdb_oracle.dll");<br />
crConnectionInfo.Attributes.Collection.Set("QE_DatabaseName", "");<br />
crConnectionInfo.Attributes.Collection.Set("QE_DatabaseType", "OLE DB (ADO)");<br />
crConnectionInfo.Attributes.Collection.Set("QE_LogonProperties", dbAttributes);<br />
crConnectionInfo.Attributes.Collection.Set("QE_ServerDescription",
this.ServerName.Text);<br />
crConnectionInfo.Attributes.Collection.Set("QE_SQLDB", "True");<br />
crConnectionInfo.Attributes.Collection.Set("SSO Enabled", "False");<br />
crConnectionInfo.Type = CrystalDecisions.Shared.ConnectionInfoType.CRQE;<br />
crConnectionInfo.LogonProperties = dbAttributes.Collection;<br />
<br />
return (crConnectionInfo);<br />
}<br />
<br />
private void FixDatabase(ReportDocument report, Provider provider)<br />
{<br />
bool setLocationError = false;<br />
string tableLocationPattern = String.Empty;<br />
CrystalDecisions.Shared.ConnectionInfo crConnectionInfo = null;<br />
<br />
switch (provider)<br />
{<br />
case Provider.SqlServer:<br />
crConnectionInfo = FixDatabaseSqlServer();<br />
tableLocationPattern = String.Format("{0}..", crConnectionInfo.DatabaseName, "");<br /> break;<br /> case Provider.Oracle:<br /> crConnectionInfo = FixDatabaseOracle();<br /> tableLocationPattern = String.Format(".", crConnectionInfo.UserID, "");<br /> break;<br /> <br /> case Provider.Undefinded:<br /> default:<br /> break;<br /> }<br /> <br /> //set database login information for the entire report object<br /> report.SetDatabaseLogon(crConnectionInfo.UserID, crConnectionInfo.Password, crConnectionInfo.ServerName, crConnectionInfo.DatabaseName);<br /> <br /> <br /> CrystalDecisions.CrystalReports.Engine.Database crDatabase = report.Database; //Set the CrDatabase Object to the Report's Database <br /> CrystalDecisions.CrystalReports.Engine.Tables crTables = crDatabase.Tables; //Set the CrTables object to the Tables collection of the Report's dDtabase<br /> <br /> foreach (CrystalDecisions.CrystalReports.Engine.Table crTable in crTables)<br /> {<br /> TableLogOnInfo crTableLogOnInfo = null;<br /> crTableLogOnInfo = crTable.LogOnInfo;<br /> if (crTableLogOnInfo != null)<br /> {<br /> crTableLogOnInfo.ConnectionInfo = crConnectionInfo;<br /> crTable.ApplyLogOnInfo(crTableLogOnInfo);<br /> <br /> //<br /> //Set location.<br /> //<br /> try<br /> {<br /> //this line throw an exception if the report was not designed with the same database provider.<br /> switch (provider)<br /> {<br /> case Provider.SqlServer:<br /> crTable.Location = String.Format(".dbo.", crConnectionInfo.DatabaseName, crTable.Name); //database.dbo.tablename<br /> break;<br /> case Provider.Oracle:<br /> crTable.Location = String.Format(".", crConnectionInfo.DatabaseName,
crTable.Name); //schema.tablename<br />
break;<br />
default:<br />
break;<br />
}<br />
crTable.Location = crTable.Location;<br />
<br />
}<br />
catch (Exception ex)<br />
{<br />
setLocationError = true;<br />
//throw;<br />
}<br />
crTable.TestConnectivity();<br />
}<br />
}<br />
<br />
//call this method recursively for each subreport<br />
foreach (ReportObject reportObject in report.ReportDefinition.ReportObjects)<br />
{<br />
if (reportObject.Kind == ReportObjectKind.SubreportObject)<br />
{<br />
FixDatabase(report.OpenSubreport(((SubreportObject)reportObject).SubreportName),
provider);<br />
}<br />
}<br />
}
</code>
<p>
I tried everything I found at forums with no success.<br />
Please, Is there anyone with the same problem who had solved it?
Is it possible to have the same report and several database providers?
<br />
What have do I have to do?
Thank you very much.</p>
Edited by: jporcar on Feb 9, 2010 9:41 AM
Request clarification before answering.
I'd simplify things significantly.
1) do not use any subreports
2) create a report on MS SQL, make sure the code you use connects there
3) create a report off of Oracle, make sure the code you use connects there
4) the reports above should be one table, one field
5) the reports should be using the same type of connectivity (ODBC, or OLEDB)
6) reports using ODBC can not be made to go to an OLEDB datasource with the CR APIs for .NET. to change from ODBC to OLEDB and vice versa, you'd need to use inprocRas
7) once you have both of the reports working, try to switch them - first in the designer, then at runtime (e.g.; if these can not be changed in the designer, runtime will do the same)
Your Oracle connectivity code would look something like this:
Dim connection As ConnectionInfo
connection = New ConnectionInfo()
With connection
.ServerName = Our Server Name Here
.UserID = Our User ID Here
.Password = Our Password Here
.DatabaseName = Our Database Name Here
.Type = ConnectionInfoType.SQL
End With
Dim CRTableLogOnInfo As TableLogOnInfo
For Each Tbl As Table In Report.Database.Tables
CRTableLogOnInfo =Tbl.LogOnInfo
CRTableLogOnInfo.ConnectionInfo = connection
Tbl.ApplyLogOnInfo(CRTableLogOnInfo)
Tbl.Location = Our Schema Here & "." & Tbl.Location
Next
Note that this is different than MS SQL... Also, note that Oracle is case sensitive.
Ludek
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I have done all you tell me above, but I have the same problem. If the report
data source location at design time have the same data base provider that the
data source location at run time everything works. But if the data source
location at design time is different than at runtime, the code you supplied to
me doesn't work.
I'm sure that if you try to program the same sample you have supplied to me you
will have the same unsuccessful result.
I have found too many questions about that problem at Crystal Reports forums
with no real solution.
Please could you tell me whether or not is it possible to change an OleDb
connection at run time from Oracle to SqlServer and reverse? And how to do it...
Here is my C# code that doesn't work at all:
protected void Page_Load(object sender, EventArgs e)
{
//the report data source location at design time is OleDb SQL Server.
ReportDocument doc = new ReportDocument();
string reportFileName = Server.MapPath("CrystalReport1.rpt");
doc.Load(reportFileName);
//I'm trying to change my connction from OleDb SqlServer to OleDb Oracle.
//Oracle Connection info.
ConnectionInfo connection = new ConnectionInfo();
connection.ServerName = "myServerName";
connection.UserID = "myUser";
connection.Password = "myPassword";
connection.DatabaseName = "";
connection.Type = ConnectionInfoType.SQL;
TableLogOnInfo CRTableLogOnInfo = new TableLogOnInfo();
foreach (CrystalDecisions.CrystalReports.Engine.Table crTable in doc.Database.Tables)
{
CRTableLogOnInfo = crTable.LogOnInfo;
CRTableLogOnInfo.ConnectionInfo = connection;
crTable.ApplyLogOnInfo(CRTableLogOnInfo);
//this line throws an exception
crTable.Location = "mySchema." + crTable.Location;
}
CrystalReportViewer1.ReportSource = doc;
CrystalReportViewer1.RefreshReport();
}
Here is my web.config
assembly="CrystalDecisions.CrystalReports.Engine, Version=12.0.2000.0, Culture=neutral, PublicKeyToken=692fbea5521e1304"
assembly="CrystalDecisions.ReportSource, Version=12.0.2000.0, Culture=neutral, PublicKeyToken=692fbea5521e1304"
assembly="CrystalDecisions.Shared, Version=12.0.2000.0, Culture=neutral, PublicKeyToken=692fbea5521e1304"
assembly="CrystalDecisions.Web, Version=12.0.2000.0, Culture=neutral, PublicKeyToken=692fbea5521e1304"
assembly="CrystalDecisions.ReportAppServer.ClientDoc, Version=12.0.1100.0, Culture=neutral, PublicKeyToken=692fbea5521e1304"
assembly="CrystalDecisions.Enterprise.Framework, Version=12.0.1100.0, Culture=neutral, PublicKeyToken=692fbea5521e1304"
assembly="CrystalDecisions.Enterprise.InfoStore, Version=12.0.1100.0, Culture=neutral, PublicKeyToken=692fbea5521e1304"
Here is the exception.
Detalles: [Código del proveedor de base de datos: 17 ]No se pudo abrir la
conexión.
CrystalReport1 {9F75D9DA-C524-48AF-9183-50F1E8989DD3}.rpt
Detalles: [Código del proveedor de base de datos: 17 ]+
Description:
|
Stack Trace:
|
[COMException (0x800002f4): No se pudo abrir la conexión.
No se pudo abrir la conexión.
CrystalReport1 {9F75D9DA-C524-48AF-9183-50F1E8989DD3}.rpt
CrystalDecisions.ReportAppServer.Controllers.DatabaseControllerClass.SetTableLocation(ISCRTable CurTable, ISCRTable NewTable) +0
CrystalDecisions.CrystalReports.Engine.Table.set_Location(String value) +842
Default.PageLoad(Object sender, EventArgs e) in d:Usersjosep.porcarDocumentsVisual Studio 2008CrystalReportsWebSite3Default.aspx.cs:48
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
System.Web.UI.Control.OnLoad(EventArgs e) +99
System.Web.UI.Control.LoadRecursive() +50
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627
Version Information:
Microsoft: No se pudo abrir la conexión.
No se pudo abrir la conexión.
CrystalReport1 {9F75D9DA-C524-48AF-9183-50F1E8989DD3}.rpt
at CrystalDecisions.ReportAppServer.Controllers.DatabaseControllerClass.SetTableLocation(ISCRTable CurTable, ISCRTable NewTable)
at CrystalDecisions.CrystalReports.Engine.Table.set_Location(String value)
at Default.PageLoad(Object sender, EventArgs e) in d:Usersjosep.porcarDocumentsVisual Studio 2008CrystalReportsWebSite3Default.aspx.cs:line 48
at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
at System.Web.UI.Control.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
: Exception of type 'System.Web.HttpUnhandledException' was thrown.
at System.Web.UI.Page.HandleError(Exception e)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest()
at System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context)
at System.Web.UI.Page.ProcessRequest(HttpContext context)
at ASP.default_aspx.ProcessRequest(HttpContext context) in c:WindowsMicrosoft.NETFrameworkv2.0.50727Temporary ASP.NET Filescrystalreportswebsite318edbb7f2522fba9App_Web_6lji7ebm.0.cs:line 0
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
-->
Thank you very much.
I'm going to upload a little utility on our ftp server for you. What you will need to do is open the report in that utility. It will present the code needed - VB and C#. The code uses inProc RAS, but that should not be an issue.
You probably want to read up a bit on inProc RAS. See [this|http://www.sdn.sap.com/irj/boc/index?rid=/library/uuid/10b840c0-623f-2b10-03b5-9d1913866b32] article.
Once the file is on the ftp, you'll get an automatic notification.
Ludek
| User | Count |
|---|---|
| 8 | |
| 5 | |
| 4 | |
| 4 | |
| 3 | |
| 3 | |
| 2 | |
| 2 | |
| 2 | |
| 2 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.