65.9K
CodeProject 正在变化。 阅读更多。
Home

将 Crystal Report 与 Oracle 和参数化查询结合使用(将 SQL 查询参数传递给 Crystal Reports)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.38/5 (13投票s)

2008年8月3日

CPOL

3分钟阅读

viewsIcon

137499

downloadIcon

2856

在 .NET Windows 应用程序中使用 Crystal Report 和参数化查询(C#.NET Windows 应用程序)。将 SQL 查询参数传递给 Crystal Reports

Crystal_Reportwith_net/main.JPG

引言

本文介绍如何在 .NET Windows 应用程序中使用 Crystal Report,并结合参数化查询以及使用 `dataset` 作为 Oracle 数据库。我在网上搜索了关于 Crystal Report 与 Oracle 参数化查询的文章,但没有找到一篇好文章,所以我在这里分享我的文章。

本文主要有三个要点:

  1. 带参数化查询的 Crystal Report
  2. 使用 Oracle 视图,因为在这种情况下存储过程无法胜任,原因在于 Oracle 存储过程不像 SQL Server 存储过程那样返回多行(记录集)。
  3. 使用 `DataSet`

因此,我在此项目中使用 Oracle 视图来绑定 Crystal Report 和 Dataset。然后,我像往常一样在视图上编写参数化查询,就像在数据库表上一样。所以这个项目将很好地说明如何将 Crystal Report 与 Oracle 结合使用。有很多方法可以做到这一点,我们甚至可以创建 Oracle 包,它们可以像 SQL Server 存储过程一样返回多条记录。但我发现这种方式简单快捷。

背景

本文不需要任何特殊的背景知识。任何初学者或中级开发者都能理解这段代码。如果你对数据库视图有基本了解会更好。

Using the Code

我为此项目创建了 2 个示例表和一个视图。表和视图的脚本如下,并附带了一些示例 `insert` 语句以提供示例数据。

create table tbl_project
(
PROJECT_ID NUMBER(4),
PROJECT_NAME  VARCHAR2(150),
GROUP_CODE  NUMBER(2)
)

create table tbl_project_group
(
GROUP_CODE  NUMBER(2),
GROUP_NAME  VARCHAR2(100)
);

create view view_project as
select a.PROJECT_NAME "PROJECT_NAME",b.GROUP_NAME "GROUP_NAME",
a.GROUP_CODE "GROUP_CODE"
from tbl_project a,tbl_project_group b where
a.GROUP_CODE=b.GROUP_CODE;

insert into tbl_project values(1,'CrystalReportWithOracle',1);

insert into tbl_project values(2,'Ajax Application',2);

insert into tbl_project_group values(1,'windows application');

insert into tbl_project_group values(2,'Web application');

步骤 1

首先,在 Microsoft Visual Studio 2005 中创建一个名为 `CrystalReportWithOracle` 的项目。然后,像下面一样添加一个 Crystal Report。

Crystal_Reportwith_net/2-1.JPG

第二步

然后,从可用数据源中选择 OLEDB(ADO),如下所示:

然后,选择 Oracle Provider for OLEDB 作为提供程序,如下图所示:

然后,根据你的 Oracle 配置提供必要的数据库登录信息。

步骤 3

然后,从可用数据源中,将之前创建的视图添加到选定的表 `Container` 中,并添加你将在报表中显示的字段,如下所示:

步骤 4

现在,向你的项目中添加一个空的 `DataSet`。

然后,从工具箱向你的窗体添加一个 Crystal Report Viewer 控件。

为了实现数据库连接,这里有一个类文件 `DLApplication.cs`。在这里,你可以根据你的 Oracle 配置更改连接字符串。如果你自己在窗体中创建连接,可以忽略此文件。

有一个组合框 (Combo Box),用户可以在其中选择他们想要的项目类型,以便应用程序根据用户的选择生成动态报表。填充组合框的代码如下:

String Query = "Select GROUP_CODE,GROUP_NAME from  tbl_project_group order by GROUP_CODE ASC";
DLApplication oDl = new DLApplication();
OracleConnection Conn = oDl.GetCon();
DataView dv = oDl.getDataView(Query, Conn);

cmb_type.DataSource = dv;
cmb_type.ValueMember = "GROUP_CODE";
cmb_type.DisplayMember = "GROUP_NAME";
cmb_type.SelectedIndex = -1;

在上面的代码中,调用了带有所需参数的 `getDataView()` 函数。该函数位于 `DLApplication` 类中。

绑定 Crystal Report 的主函数如下,每当用户在组合框中更改选择时,就会为选定的组合框值生成新报表。

//         

   private void cmb_type_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (Convert.ToInt32(cmb_type.SelectedIndex) == -1 || 
(Convert.ToString(cmb_type.SelectedValue) == "System.Data.DataRowView"))
            {
                return;
            }
            CrystalReport1 objRpt;
            objRpt = new CrystalReport1();

            String ConnStr = "SERVER=newsdb;USER ID=ppms;PWD=ppms";

            OracleConnection myConnection = new OracleConnection(ConnStr);
// Here I am writing my query over the view
// we cannot write query directly over the tables because it will be a 
// join query and we will not be able to fill our adapter easily.
            string Query1 = "select PROJECT_NAME,GROUP_NAME from view_project
 where GROUP_CODE=" + cmb_type.SelectedValue;

            OracleDataAdapter adapter = new OracleDataAdapter(Query1, ConnStr);
            DataSet1 Ds = new DataSet1();

            adapter.Fill(Ds, "view_project");

            if (Ds.Tables[0].Rows.Count == 0)
            {
                MessageBox.Show("No data Found", "Project Tracker Suite");
                return;
            }

            objRpt.SetDataSource(Ds);

            CrystalDecisions.CrystalReports.Engine.TextObject root;
            root = (CrystalDecisions.CrystalReports.Engine.TextObject)
                    objRpt.ReportDefinition.ReportObjects["txtHeader"];
            root.Text = "Sample Report With Parameter!!";

            crystalReportViewer1.ReportSource = objRpt;
        }
    }
//

`DLApplication.cs` 文件包含返回 Oracle Data View、Oracle Data Reader 等的函数。你可以查看该类文件。

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.OracleClient;

namespace CrystalReportWithOracle
{
    public class DLApplication 
    {
        private const String My_name = "  DLApplication : ";
        private static String m_sConStr = "SERVER=yourdB;USER ID=user1;PWD=pass";
        private int userId;

        public int propertyUserId
        {
            get
            {
                return userId;
            }
            set
            {
                userId = value;
            }
        }

        public OracleConnection GetCon()
        {
            try
            {
                OracleConnection sqlcon = new OracleConnection(m_sConStr);
                return sqlcon;
            }
            catch (Exception ex)
            {
                throw new System.ApplicationException(My_name + " GetCon: " + ex.Message);
            }
        }

        public OracleDataReader GetSqlReader(String Sql, ref OracleConnection con)
        {
            try
            {
                OracleCommand objOraCmd = new OracleCommand();
                OracleDataReader objOraDrRead;
                objOraCmd.Connection = con;
                objOraCmd.CommandType = CommandType.Text;
                objOraCmd.CommandText = Sql;
                if (con.State != ConnectionState.Open) con.Open();
                objOraDrRead = objOraCmd.ExecuteReader(CommandBehavior.CloseConnection);
                return objOraDrRead;
            }
            catch (Exception ex)
            {
                throw new System.ApplicationException(My_name + " GetSqlReader: " + ex.Message);
            }
        }

        public void CloseCon(ref  OracleConnection thisCon)
        {
            try
            {
                if (thisCon.State != ConnectionState.Closed)
                    thisCon.Close();
            }
            catch (Exception ex)
            {
                throw new System.ApplicationException(My_name + " CloseCon: " + ex.Message);
            }
        }

        public void ExecNonQuery(String sQuery)
        {
            OracleConnection objCon = new OracleConnection(m_sConStr);
            OracleCommand objCmd;
            try
            {
                objCon.Open();
                objCmd = objCon.CreateCommand();
                objCmd.CommandText = sQuery;
                objCmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                throw new System.ApplicationException(My_name + " ExecNonQuery : " + ex.Message);
            }
            finally
            {
                if (objCon.State == ConnectionState.Open)
                    objCon.Close();
            }
        }

        public DataView getDataView(String Query, OracleConnection Conn)
        {
            try
            {
                OracleDataAdapter oDa;
                DataSet ds;

                oDa = new OracleDataAdapter(Query, Conn);
                ds = new DataSet();
                oDa.Fill(ds);
                if (Conn.State != ConnectionState.Closed)
                    Conn.Close();
                return (ds.Tables[0].DefaultView);
            }
            catch (Exception ex)
            {
                throw new System.ApplicationException(My_name + " getDataView : " + ex.Message);
            }
            finally
            {
                if (Conn.State != ConnectionState.Closed)
                    Conn.Close();
            }
        }

    }
}

关注点

Oracle 存储过程不返回多个记录,我们可以使用包代替,但在这里,我使用了视图,它更容易理解。

很快,我将发布关于以下主题的文章:

  1. 通过附加数字证书,将数据从 Windows 应用程序 (.NET) 发布到 HTTPS (https,即安全连接) URL,并接收响应。
  2. Ajax 技术

历史

  • 我将更新这篇文章,以更清晰地阐述这个主题。
© . All rights reserved.