Как изменить подключение базы данных ODBC Crystal Report во время выполнения?
У меня есть отчет с Crystal Reports 2008, в котором мне нужно развернуть производственную систему, что означает, что мне нужно изменить соединение с базой данных во время выполнения. База данных - PostgreSQL 8.3.0, а соединение, которое я использую для создания исходного отчета, - это соединение ODBC.
Я нашел различные способы изменения соединения с базой данных, включая следующее:
reportDoc.Load(report);
reportDoc.DataSourceConnections[0].SetConnection("server", "database", "user", "pwd");
reportDoc.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, path);
Однако это всегда не выполняется со следующим сообщением об ошибке.
Не удалось открыть соединение.
Я проверил параметры соединения, успешно подключившись к базе данных с помощью pgAdmin III, поэтому я знаю, что параметры подключения верны. Кроме того, если я удалю строку SetConnection (...), чтобы код выглядел следующим образом:
reportDoc.Load(report);
reportDoc.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, path);
тогда отчет работает нормально, используя параметры соединения, которые хранятся в отчете. Возможно ли, что этот метод не работает для соединений ODBC?
Как изменить соединение базы данных ODBC Crystal Report во время выполнения?
Ответы
Ответ 1
После еще большего исследования я обнаружил, что был ответ на две части.
ЧАСТЬ 1
Если вы подключаетесь к PostgreSQL через ODBC (единственный способ, с помощью которого Crystal Reports может извлекать данные из PostgreSQL на момент написания этой статьи), используя владельца данных, вы можете использовать следующий код:
reportDoc.Load(report);
reportDoc.DataSourceConnections[0].SetConnection("Driver={PostgreSQL ANSI};Server=myServer;Port=5432;", "myDatabase", "myUser", "myPassword");
reportDoc.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, path);
// Depending on your application you may have more than one data source connection that needs to be changed.
Этот метод работает только в том случае, если вы подключаетесь как пользователь, которому принадлежат данные, о которых вы сообщаете, поскольку имя схемы не требуется.
ЧАСТЬ 2
Если вы подключаетесь к PostgreSQL через ODBC с пользователем, отличным от владельца данных, вам необходимо вручную указать имя схемы. Это выполняется с помощью следующего кода.
reportDoc.Load(report);
ConnectionInfo connInfo = new ConnectionInfo();
connInfo.ServerName = "Driver={PostgreSQL ANSI};Server=myServer;Port=5432;";
connInfo.DatabaseName = "myDatabase";
connInfo.UserID = "myUser";
connInfo.Password = "myPassword";
TableLogOnInfo tableLogOnInfo = new TableLogOnInfo();
tableLogOnInfo.ConnectionInfo = connInfo;
foreach (Table table in reportDoc.Database.Tables)
{
table.ApplyLogOnInfo(tableLogOnInfo);
table.LogOnInfo.ConnectionInfo.ServerName = connInfo.ServerName;
table.LogOnInfo.ConnectionInfo.DatabaseName = connInfo.DatabaseName;
table.LogOnInfo.ConnectionInfo.UserID = connInfo.UserID;
table.LogOnInfo.ConnectionInfo.Password = connInfo.Password;
// Apply the schema name to the table location
table.Location = "mySchema." + table.Location;
}
reportDoc.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, path);
Резюме
Здесь есть две критические части информации при попытке подключиться к базе данных PostgreSQL из Crystal Reports.
- Номер драйвера, сервера и порта должен быть указан в свойстве имени сервера.
- Если вы подключаетесь как пользователь, отличный от владельца данных, вы должны указать имя схемы для каждой таблицы, из которой вы извлекаете данные.
Источники
Было использовано несколько источников, у которых не было ответа, который работал в моем конкретном сценарии, но это привело меня в правильном направлении. Эти источники перечислены ниже.
Ответ 2
Я просто пережил это испытание.
Я установил свои подключения, подобные этому (где sDataSource и т.д. - строка с информацией)
Dim myConnectionInfo As ConnectionInfo = New ConnectionInfo()
myConnectionInfo.ServerName = sDataSource
myConnectionInfo.DatabaseName = sInitialCatalog
myConnectionInfo.UserID = sUserID
myConnectionInfo.Password = sPassword
Dim myTables As Tables = report.Database.Tables
Dim myTableLogonInfo As TableLogOnInfo = New TableLogOnInfo()
myTableLogonInfo.ConnectionInfo = myConnectionInfo
For Each myTable As CrystalDecisions.CrystalReports.Engine.Table In myTables
myTable.ApplyLogOnInfo(myTableLogonInfo)
myTable.LogOnInfo.ConnectionInfo.DatabaseName = myTableLogonInfo.ConnectionInfo.DatabaseName
myTable.LogOnInfo.ConnectionInfo.ServerName = myTableLogonInfo.ConnectionInfo.ServerName
myTable.LogOnInfo.ConnectionInfo.UserID = myTableLogonInfo.ConnectionInfo.UserID
myTable.LogOnInfo.ConnectionInfo.Password = myTableLogonInfo.ConnectionInfo.Password
Next
Ответ 3
Прежде всего, спасибо за эту информацию!!!
Я использую MySQL/С#/Crystal Reports. После настройки ODBC/DSN что-то просто, как это сработало для меня.
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
using MySql.Data.MySqlClient;
.
.
.
ConnectionInfo connInfo = new ConnectionInfo();
connInfo.ServerName = "Driver={MySQL ODBC 3.51 Driver};DSN=MyODBCDatasourceName";
TableLogOnInfo tableLogOnInfo = new TableLogOnInfo();
tableLogOnInfo.ConnectionInfo = connInfo;
// rpt is my Crystal Reports ReportDocument
// Apply the schema name to the table location
foreach (Table table in rpt.Database.Tables)
{
table.ApplyLogOnInfo(tableLogOnInfo);
table.Location = table.Location;
}
Ответ 4
Обновление ODBC в файле отчета о кристалле.
Мы используем ODBC с MSSQL, мы не смогли найти, как обновить ODBC в кристаллических файлах в рамках C-проекта.
В приведенном здесь примере нам удалось найти способ обновления ODBC в MSSQL, и он прост как это:
Cursor.Current = Cursors.WaitCursor;
CrystalDecisions.Windows.Forms.CrystalReportViewer CR_Viewer;
CR_Viewer = new CrystalDecisions.Windows.Forms.CrystalReportViewer();
this.Controls.Add(CR_Viewer);
ConnectionInfo connInfo = new ConnectionInfo();
connInfo.ServerName = "YOUR ODBC NAME";
TableLogOnInfo tableLogOnInfo = new TableLogOnInfo();
tableLogOnInfo.ConnectionInfo = connInfo;
//THIS IS A CRYSTAL RPT FILE DIFINE AS A CLASS
Facturation_Nord_Ouest.Reports.Facture_Français CrystalReportFr;
CrystalReportFr = new Facturation_Nord_Ouest.Reports.Facture_Français();
for (int i = 0; i < CrystalReportFr.Database.Tables.Count; i++)
{
CrystalReportFr.Database.Tables[i].ApplyLogOnInfo(tableLogOnInfo);
}
CR_Viewer.ReportSource = CrystalReportFr;
CR_Viewer.ActiveViewIndex = 0;
CR_Viewer.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
CR_Viewer.Dock = System.Windows.Forms.DockStyle.Fill;
CR_Viewer.Location = new System.Drawing.Point(0, 0);
CR_Viewer.Size = new System.Drawing.Size(545, 379);
CR_Viewer.TabIndex = 0;
CR_Viewer.Name = "Invoice";
CR_Viewer.Zoom(100);
CR_Viewer.Show();
Cursor.Current = Cursors.Default;
С этим ODBC в кристаллическом файле автоматически обновляется.
Ответ 5
protected void Page_Load(object sender, EventArgs e)
{
try
{
ReportDocument cryRpt = new ReportDocument();
TableLogOnInfos crtableLogoninfos = new TableLogOnInfos();
TableLogOnInfo crtableLogoninfo = new TableLogOnInfo();
ConnectionInfo crConnectionInfo = new ConnectionInfo();
cryRpt.Load(@"D:\tem\WebAppReport\WebAppReport\CrystalReport1.rpt");
crConnectionInfo.ServerName = "misserver";
crConnectionInfo.DatabaseName = "testAccountability_data";
crConnectionInfo.UserID = "RW";
crConnectionInfo.Password = "RW";
foreach (CrystalDecisions.CrystalReports.Engine.Table CrTable in cryRpt.Database.Tables)
{
crtableLogoninfo = CrTable.LogOnInfo;
crtableLogoninfo.ConnectionInfo = crConnectionInfo;
CrTable.ApplyLogOnInfo(crtableLogoninfo);
}
CrystalReportViewer1.ReportSource = cryRpt;
CrystalReportViewer1.RefreshReport();
}
catch
{
}
}
Ответ 6
Эта работа для Sql Server 2008 R2 для подключения к DSN меньше.
Dim myConnectionInfo As CrystalDecisions.Shared.ConnectionInfo = New CrystalDecisions.Shared.ConnectionInfo()
myConnectionInfo.ServerName = "Driver={SQL Server Native Client 10.0};Server=P03\sqlrs1;"
myConnectionInfo.DatabaseName = "RS1DB"
myConnectionInfo.UserID = "user"
myConnectionInfo.Password = "pwd"
For Each myTable As CrystalDecisions.CrystalReports.Engine.Table In mboReportDocument.Database.Tables
Dim myTableLogonInfo As TableLogOnInfo = myTable.LogOnInfo
myTableLogonInfo.ConnectionInfo = myConnectionInfo
myTable.ApplyLogOnInfo(myTableLogonInfo)
Next