I have developed a web application which uses a crystal report document to connect to the database, generate the report and export it to pdf. The application is written in .Net as a web application using c#. The report has several sub-reports (6).
This all works well. However, the report document does not release database resources, so after it is called several times Oracle eventually fails because it hits its maximum processes limit.
How do I get the ReportDocument to release its database connections?
Don't suggest increasing oracles max_processes - the limit will be exceeded eventually regardless of how high this is set.
The connection mechanism I use is one which I got from this forum. It seems to create a connection for each subreport in the report, which seems a bit excessive, but it works.
The connection code is as follows:
private bool CrSetDbLogin(ReportDocument CrDoc, string DbServer,
string DbName, string UserId, string Password)
{
bool Status = true;
ConnectionInfo DbConnInfo = new ConnectionInfo();
SubreportObject SubObj;
DbConnInfo.ServerName = DbServer;
DbConnInfo.DatabaseName = DbName;
DbConnInfo.UserID = UserId;
DbConnInfo.Password = Password;
if (CrApplyLogin(CrDoc, DbConnInfo))
{
foreach (ReportObject CrDocObj in CrDoc.ReportDefinition.ReportObjects)
{
if (CrDocObj.Kind == ReportObjectKind.SubreportObject)
{
SubObj = (SubreportObject)CrDocObj;
if (CrApplyLogin(CrDoc.OpenSubreport(SubObj.SubreportName),
DbConnInfo) == false)
{
Status = false;
}
}
}
}
else
{
Status = false;
}
return Status;
}
private bool CrApplyLogin(ReportDocument CrDoc, ConnectionInfo DbConnInfo)
{
bool Status = true;
TableLogOnInfo LoginInfo;
foreach (Table DbTable in CrDoc.Database.Tables)
{
LoginInfo = DbTable.LogOnInfo;
LoginInfo.ConnectionInfo = DbConnInfo;
DbTable.ApplyLogOnInfo(LoginInfo);
if (DbTable.TestConnectivity())
{
if (DbTable.Location.IndexOf(".") > 0)
{
int LastDot = DbTable.Location.LastIndexOf(".");
DbTable.Location = DbTable.Location.Substring(LastDot + 1);
}
else
{
DbTable.Location = DbTable.Location;
}
}
else
{
Status = false;
}
}
return Status;
}
This all works well. However, the report document does not release database resources, so after it is called several times Oracle eventually fails because it hits its maximum processes limit.
How do I get the ReportDocument to release its database connections?
Don't suggest increasing oracles max_processes - the limit will be exceeded eventually regardless of how high this is set.
The connection mechanism I use is one which I got from this forum. It seems to create a connection for each subreport in the report, which seems a bit excessive, but it works.
The connection code is as follows:
private bool CrSetDbLogin(ReportDocument CrDoc, string DbServer,
string DbName, string UserId, string Password)
{
bool Status = true;
ConnectionInfo DbConnInfo = new ConnectionInfo();
SubreportObject SubObj;
DbConnInfo.ServerName = DbServer;
DbConnInfo.DatabaseName = DbName;
DbConnInfo.UserID = UserId;
DbConnInfo.Password = Password;
if (CrApplyLogin(CrDoc, DbConnInfo))
{
foreach (ReportObject CrDocObj in CrDoc.ReportDefinition.ReportObjects)
{
if (CrDocObj.Kind == ReportObjectKind.SubreportObject)
{
SubObj = (SubreportObject)CrDocObj;
if (CrApplyLogin(CrDoc.OpenSubreport(SubObj.SubreportName),
DbConnInfo) == false)
{
Status = false;
}
}
}
}
else
{
Status = false;
}
return Status;
}
private bool CrApplyLogin(ReportDocument CrDoc, ConnectionInfo DbConnInfo)
{
bool Status = true;
TableLogOnInfo LoginInfo;
foreach (Table DbTable in CrDoc.Database.Tables)
{
LoginInfo = DbTable.LogOnInfo;
LoginInfo.ConnectionInfo = DbConnInfo;
DbTable.ApplyLogOnInfo(LoginInfo);
if (DbTable.TestConnectivity())
{
if (DbTable.Location.IndexOf(".") > 0)
{
int LastDot = DbTable.Location.LastIndexOf(".");
DbTable.Location = DbTable.Location.Substring(LastDot + 1);
}
else
{
DbTable.Location = DbTable.Location;
}
}
else
{
Status = false;
}
}
return Status;
}