Having a problem with file server when using a different db
If the file server is using the same database the report where designed
with, all works well. But, if I create a file server using a different
database name, get an error:
Server Error: processing request for Report Files\Members\test report
EDataError, TdaSession.GetDatgabaseForName: No TDatabase object found
for specified name, demo.
A Separate database connection is required for each thread.
I thought the rbReportTemplateVolume unit owned the reports and the
reports used the db connection in the rbReportTemplateVolume unit. The
database object connects correctly and I can design a report in the ide
with the connections. Just can't run a report from a client app.
Is there something more that needs to be done before a report is run
when using a different database?
Thanks,
Dave
with, all works well. But, if I create a file server using a different
database name, get an error:
Server Error: processing request for Report Files\Members\test report
EDataError, TdaSession.GetDatgabaseForName: No TDatabase object found
for specified name, demo.
A Separate database connection is required for each thread.
I thought the rbReportTemplateVolume unit owned the reports and the
reports used the db connection in the rbReportTemplateVolume unit. The
database object connects correctly and I can design a report in the ide
with the connections. Just can't run a report from a client app.
Is there something more that needs to be done before a report is run
when using a different database?
Thanks,
Dave
This discussion has been closed.
Comments
When you create a report using the Data workspace, the DatabaseName is
saved as part of the report definition. When the report loads, there
needs to be a connection component (i.e. TDatabase when using the BDE)
with the same name.
The article below is not specific to server applications, but is
applicable here....
-------------------------------------------------
Tech Tip: How to modify the DatabaseName stored
with a DADE Query
-------------------------------------------------
Currently when DADE is used to create dataviews,
the DatabaseName is stored as part of the query
definition. (This is consistent with Delphi's
approach to specifying a database connection for
a Query object).
In some cases, you may decide that the
DatabaseName needs to be modified at a later date.
We recommend that the DatabaseName
refer to a TDatabase connection component or to
an Alias to provide flexibility for changing
the connection parameters.
A second way to handle this issue is to implement
some code that specifies a DatabaseName
whenever a template is loaded. This can be accomplished
by using the Report.Template.OnLoadEnd event.
1. Declare an event-handler procedure in the private
section of your form declaration.
type
myForm = class(TForm)
private
procedure ReportTemplateLoadEndEvent(Sender: TObject);
public
end;
2. Use the FormCreate event to assign the event-handler to
the event property.
procedure myForm.FormCreate(Sender: TObject)
begin
Report1.Template.OnLoadEnd := ReportTemplateLoadEndEvent;
end;
3. Add code to the event-handler to specify the database name.
procedure myForm.ReportTemplateLoadEndEvent(Sender: TObject)
var
lSQL: TdaSQL;
begin
if GetSQLObject(Report1, lSQL) then
begin
lSQL.DatabaseName := Designer.DataSettings.DatabaseName;
SetSQLObject(Report, lSQL);
lSQL.Free;
end;
end;
4. Below is a tech tip for extracting the SQL object
from a report. TdaSQL is a class defined in daQClass.pas.
-------------------------------------------------
Tech Tip: How to access the SQL object associated
with a Report created using DADE
-------------------------------------------------
uses
daDatMod;
function GetSQLObject(aReport: TppReport; var aSQL: TdaSQL): Boolean;
var
lDataModule: TdaDataModule;
lDataView: TdaDataView;
begin
aSQL := TdaSQL.Create(nil);
{get the datamodule}
lDataModule := daGetDataModule(aReport);
if (lDataModule <> nil) then
begin
lDataView := lDataModule.DataViews[0];
if (lDataView <> nil) and (lDataView is TdaQueryDataView) then
aSQL.Assign(TdaQueryDataView(lDataView).SQL);
end;
Result := (aSQL <> nil);
end;
procedure SetSQLObject(aReport: TppReport; aSQL: TdaSQL);
var
lDataModule: TdaDataModule;
lDataView: TdaDataView;
begin
{get the datamodule}
lDataModule := daGetDataModule(aReport);
if (lDataModule <> nil) then
begin
lDataView := lDataModule.DataViews[0];
if (lDataView <> nil) and (lDataView is TdaQueryDataView) then
TdaQueryDataView(lDataView).SQL := aSQL;
end;
end;
--
Tech Support mailto:support@digital-metaphors.com
Digital Metaphors http://www.digital-metaphors.com
Best regards,
Nard Moseley
Digital Metaphors
www.digital-metaphors.com
trigger to get the report to set the database name, I can not find the
Report.Template.OnLoadEnd event. This is where I get thoughly
confussed. I've used the below procedure to change the database name
for EUR reports, but I can not figure how to add the same event to the
server modules.
I'v used:
procedure
TdmReportTemplateVolume.rsReportTemplateVolume1ValidateReportParameters(
Sender: TObject; aEventParams: TrsValidateReportParametersEventParams);
begin
TppReport(aEventParams.Report).Template.OnLoadEnd :=
ReportTemplateLoadEndEvent;
end;
This gets set, but the report event does not fire and I get the same error.
Also, is the Sender in ReportTemplateLoadEndEvent(Sender: TObject)
the report object so I can use TppReport(Sender).Template instead of
Report1?
I'm really struggeling with the server objects as to when they are
actually loaded to send to the client and I can add my events to do my
special processing. I've also tried to add the report event in the
BeforePublishReport event. I guess I need some help.
Thanks,
Dave
TrsReportTemplateVolume OnLoadReportEnd as:
procedure TdmReportTemplateVolume.rsReportTemplateVolume1LoadReportEnd(
Sender: TObject);
var
lSQL: TdaSQL;
begin
if GetSQLObject(TppReport(Sender), lSQL) then
begin
lSQL.DatabaseName := Sessions.CurrentSession.Databases[0].databaseName;
SetSQLObject(TppReport(Sender), lSQL);
end;
end;
But I had to change the SetSqlObject to:
procedure TdmReportTemplateVolume.SetSQLObject(aReport: TppReport; aSQL:
TdaSQL);
var
lDataModule: TdaDataModule;
lDataView: TdaDataView;
begin
{get the datamodule}
lDataModule := daGetDataModule(aReport);
if (lDataModule <> nil) then
begin
lDataView := lDataModule.DataViews[0];
if (lDataView <> nil) and (lDataView is TdaQueryDataView) then
TdaQueryDataView(lDataView).SQL.DatabaseName := aSQL.DatabaseName;
// TdaQueryDataView(lDataView).SQL := aSQL;
end;
end;
If I used the aSql to set the ~.SQL there is an error that there is no
sql. Changing just the database name works for now. But I still would
like more info on the what objects are load when.
Thanks,
Dave
This is the appropriate event to use. For ReportVolumes you want to use
ReportVolume.OnLoadReportEnd event rather than
Report.Template.OnLoadEnd.
Best regards,
Nard Moseley
Digital Metaphors
www.digital-metaphors.com