2013-09-25 61 views
0

我正在编写一个应用程序,它将更改Crystal Reports报告文件中的数据库访问参数。我使用.NET窗体应用程序打开报告并应用SDK功能来更改驱动程序类型(ODBC/OLEDB),服务器名称,数据库名称,用户,密码,身份验证类型等。我遇到问题数据库名称。我的代码会更改表ConnectionInfo的具体属性(在子报表中),但无法更新报表中的一般SQL查询。这导致报告仍然访问旧数据库。Crystal Reports中的SQL查询不更新

因此,如果原始报告配置为访问database_1,并将其更改为database_2,则它将将所有表属性正确更改为database_2(可在Designer中验证)。它仍然会在查询中拥有database_1。数据库名称在SDK RowsetController.GetSQLStatement()结果和Crystal Reports Developer查询视图(数据库 - >显示SQL查询...)中保持不变。

而且我必须有两个数据库(database_1和了Database_2)在线而发生转换,否则我得到任何GetSQLStatement异常(当database_1处于脱机状态,原因是其仍然是指它)或SetTableLocation(当了Database_2处于离线状态 - 尽管这是预期的和可接受的行为)。如果两个数据库都在线,则没有错误。

这正是我使用的是什么:

1)CrystalDecisions.CrystalReports.Engine.ReportDocument.Load(文件路径,OpenReportMethod.OpenReportByTempCopy) (...)

2)请并填充CrystalDecisions.ReportAppServer.DataDefModel.PropertyBag

3)遍历CrystalDecisions.ReportAppServer.DataDefModel.Tables并使用SetTableLocaiton()为每个属性应用所有属性。

4)与每个子报表

5)RowsetController.GetSQLStatement()重复,以查看该报告的SQL查询。

是否有一些方法来更新基于新表ConnectionInfos(似乎设置正确)的查询?我甚至没有看到任何手动更新查询的可能性(GET,搜索&替换,SET)。

我使用:

.NET 4.5, 的Visual Studio 2012, CR为VS 13.0.5, Crystal Reports开发9.2.2.693的结果验证(来源报告也用它创建)

+1

当你说查询时,你的意思是由Crystal报表创建的SQL,或者你正在使用一个命令,你的问题是如何更新命令?你可以检查这个产品:http://www.r-tag.com/Pages/CRDataSource.aspx如果它能够改变连接,你也应该能够做到这一点。否则,查询有一些特定的内容。 – Lan

+0

我的意思是由CR创建的主报告的整体SQL查询。命令很容易更新,同时迭代所有表,应用属性包并使用SetTableLocation。我已经找到了答案,但仍然感谢产品的链接! –

回答

1

答案:设置propper 限定名称为每个表。 QualifiedName是包含DbName的表的全名。这稍后出现在报表的SQL查询中。通过我们了解的合格名称:

myDatabase.mySchema。myTableName

代码示例:

CrystalDecisions.ReportAppServer.DataDefModel.Table boTable = new CrystalDecisions.ReportAppServer.DataDefModel.Table(); 
CrystalDecisions.ReportAppServer.DataDefModel.PropertyBag boMainPropertyBag = new CrystalDecisions.ReportAppServer.DataDefModel.PropertyBag(); 
CrystalDecisions.ReportAppServer.DataDefModel.PropertyBag boInnerPropertyBag = new CrystalDecisions.ReportAppServer.DataDefModel.PropertyBag(); 

// Custom function to fill property bags with values which influence the table properties as seen in CR Developer 
FillPropertyBags(boMainPropertyBag, boInnerPropertyBag); 

CrystalDecisions.ReportAppServer.DataDefModel.ConnectionInfo boConnectionInfo = new CrystalDecisions.ReportAppServer.DataDefModel.ConnectionInfo(); 
boConnectionInfo.Attributes = boMainPropertyBag; 
boConnectionInfo.Kind = CrystalDecisions.ReportAppServer.DataDefModel.CrConnectionInfoKindEnum.crConnectionInfoKindCRQE; 

boTable.ConnectionInfo = boConnectionInfo; 

CrystalDecisions.ReportAppServer.DataDefModel.Tables boTables = boReportDocument.ReportClientDocument.DatabaseController.Database.Tables; 

for (int i = 0; i < boTables.Count; i++) 
{ 
    boTable.Name = boTables[i].Name; 
    // the QualifiedName is directly taken into the CR general query so this is a quick fix to change it 
    boTable.QualifiedName = boTables[i].QualifiedName.Replace("oldDbName", "newDbName"); 
    boTable.Alias = boTables[i].Alias; 
    boReportDocument.ReportClientDocument.DatabaseController.SetTableLocation(boTables[i], boTable); 
} 

呃...研究一整天和SO发布问题后找到答案。