【问题标题】:Crystal report with linked subreport only working on Report Preview带有链接子报表的水晶报表仅适用于报表预览
【发布时间】:2016-06-08 07:06:50
【问题描述】:

我在我的主报告中使用了带有 sql 参数的存储过程。

我的主报告的存储过程

然后我尝试使用以下存储过程在工作报告中添加子报告

然后将 Subreport 字段参数链接到我的 Main

如果子报告正常工作,我检查了主报告预览

然后我运行报告,但我看到的只是这个 它只是停留在此消息中并继续运行,我什至等待了几个小时并检查任务管理器是否挂起报告,但没有..它也没有任何错误消息。但为了关闭正在运行的报告,我必须在任务管理器中“结束进程”。

所以我尝试从子报告以及链接中删除字段参数并重新运行报告。

它可以工作,但是如果没有从主报告中传递值,则生成报告是没有用的。因为我有日期范围。似乎是什么问题?为什么我链接参数时它只是停留在加载报告?

有关更多信息,我正在使用 SAP Crystal Report Service Pack 16,以及作为 Visual Studio 2015 的 IDE

这是我用于获取/设置主报告参数值的代码

 private void SalesByRangeReport_Load(object sender, EventArgs e)
    {

        FormBorderStyle = FormBorderStyle.Sizable;

        WindowState = FormWindowState.Maximized;

        TopMost = true;

        DataTable dtSalesByRangeReport = GetData();

        showReport(dtSalesByRangeReport);
    }

    private void showReport(DataTable dtSalesByRangeReport)
    {
        ReportDocument rdoc = new ReportDocument();

        //rdoc.Load(@"Report\SalesByRangeReport.rpt");

        rdoc.Load(AppDomain.CurrentDomain.BaseDirectory + @"Report\SalesByRangeReport.rpt");
        rdoc.SetDataSource(dtSalesByRangeReport);

        TextObject txt;
        if (rdoc.ReportDefinition.ReportObjects["test"] != null)
        {
            txt = (TextObject)rdoc.ReportDefinition.ReportObjects["test"];
            txt.Text = "From :" + StartDate.ToString(" MMMM  dd  yyyy  hh :mm") + " To :" + EndDate.ToString(" MMMM  dd  yyyy  hh :mm");
        }

        SalesByRangeCystalReport.ReportSource = rdoc;
    }


 private DataTable GetData()
    {
        DataTable dtData = new DataTable();

        using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["CSPOSWare.Reports.Properties.Settings.fpos_chaplinConnectionString"].ConnectionString))
        {

            //TODO Mark and Reni : Create a Stored Procedure, Saved in SalesByRangeReport.txt 

            using (SqlCommand cmd = new SqlCommand("usp_ReportShowSalesRangeDateTime", conn))
            {
                cmd.CommandType = CommandType.StoredProcedure;

                conn.Open();

                //cmd.Parameters.AddWithValue("@TopInt", this.TopInt);
                cmd.Parameters.AddWithValue("@SortType", this.SortType);
                cmd.Parameters.AddWithValue("@StartDate", this.StartDate);
                cmd.Parameters.AddWithValue("@EndDate", this.EndDate);
                cmd.Parameters.AddWithValue("@DeptGroup", this.DeptGroup);
                cmd.Parameters.AddWithValue("@DateType", this.DateType);

                //Console.WriteLine("Start Date" + StartDate);

                SqlDataReader rdr = cmd.ExecuteReader();

                dtData.Load(rdr);
            }

        }


        return dtData;
    }

我的两个报告都具有以下属性:

Build Action: Compile
Copy to Output Directory: Copy Always
Custom Tool: 
Custom Tool Name: 

所以我尝试在我的主 SP 和子 SP 上为未知数添加优化 主要:

  ALTER PROCEDURE[dbo].[usp_ReportShowSalesRangeDateTime]
        (                           
            @SortType     Varchar(50),
            @StartDate    DATETIME,
            @EndDate      DATETIME,
            @DeptGroup    Varchar(50),
            @DateType     Varchar(50)
        )
        AS
    BEGIN
        Declare @SQLQuery NVARCHAR(max)
         Declare @ReportCriteria NVARCHAR(max)
         If (LEN(@DeptGroup) > 0) 
            Set @ReportCriteria = ' AND B.Department =  ''' + @DeptGroup + '''';
         If (LEN(@DeptGroup) = 0)
         Set @ReportCriteria = ' ';

            WITH SalesRange AS(
                        Select A.EndDate as [Log Date], A.StoreDate as [Store Date], B.Department as [Department], B.Quantity as [Quantity], 
                        isnull(C.Amount,0) as [Discount], B.AmountDue as [AmountDue],round(B.BasePrice*1.12,4) as [Gross Sales],
                         B.BasePrice + isnull(vsa.Tax,0) as [BasePrice], 
                        case when vsa.type = 0 then isnull(vsa.Amount,0) else 0.0000 end As [VAT Sales Amount],
                        case when vsa.type = 1 then isnull(vsa.Amount,0) else 0.0000 end As [VAT Exempt Sales Amount],
                        B.ServiceCharge as [ServiceCharge], isnull(vsa.Tax,0) As [VAT Sales Tax],
                        case when D.[Type] = 0 Then D.Tax Else 0 End As [Tax],
                        case when T.MediaIndex = 4 then T.Amount else 0 End As [GiftCert],
                        case when T.MediaIndex = 4 then 1 else 0 End As [GCCount]
                        FROM  CSSaleItem B WITH(NOLOCK)
                        LEFT JOIN CSSaleItemDiscount C WITH(NOLOCK) ON B.CSSaleItemID = C.CSSaleItemID
                        LEFT JOIN CSSale A WITH(NOLOCK) ON A.CSSaleID = B.CSSaleID
                        LEFT JOIN CSSaleItemTax D WITH(NOLOCK) ON B.CSSaleItemID = D.CSSaleItemID
                        LEFT JOIN (Select CSSaleItemID, Amount, Tax, [Type] From CSSaleItemTax WITH(NOLOCK) Where [Type] = 0)  As vsa  ON vsa.CSSaleItemID = B.CSSaleItemID
                        LEFT JOIN CSSaleTender T WITH(NOLOCK) ON T.CSSaleID = A.CSSaleID
                        Where   StoreDate   BETWEEN  convert(VARCHAR,@StartDate)   AND  convert(VARCHAR,@EndDate)  and a.RefundStoreDate IS NULL 
                        )
                        SELECT [Department], sum([Quantity]) as [Quantity], SUM([Tax]) as [Tax] , sum([Discount]) as [Discount], 
                        sum(([Gross Sales]+[ServiceCharge])) as [Gross Sales], sum(([BasePrice]+[ServiceCharge]-[Discount])) As [Net Sales],
                        sum(([BasePrice]+[ServiceCharge]-[Discount]))/
                        (Select  sum(NetSales) FROM  CSSale B LEFT JOIN (select csSaleID, Department from CSSaleItem WITH(NOLOCK) group by Department, CSSALEID ) AS A On A.CSSaleID = B. CSSaleID
                          Where   StoreDate   BETWEEN  convert(VARCHAR,@StartDate)   AND  convert(VARCHAR,@EndDate)  and RefundStoreDate IS NULL )*100 as [% Total],
                        sum([GiftCert]) as [Gift Cert Total], sum([ServiceCharge]) as [Service Charge], sum([GCCount]) as [GCCountTotal]
                        From SalesRange
                        Group By [Department] 
                        Order By [Department]  desc 
                    OPTION (OPTIMIZE FOR (@StartDate UNKNOWN, @EndDate UNKNOWN))
                END

子报告:

    ALTER PROCEDURE[dbo].[usp_ReportShowMedia](
       @StartDate2    DATETIME,
                @EndDate2      DATETIME
                )
 As
        BEGIN


      Select isnull(M.MediaName,'Other') As [Media], 
      COUNT(T.MediaIndex) As [Count], 
      isnull(sum(T.Amount),0) As [Sales Amount], 
      isnull(sum(case when S.EndDate IS NOT NULL and DateRefunded IS NULL Then       S.NetSales Else 0 End),0) As [Total Sales], 
      isnull(sum(case when S.EndDate IS NULL then S.NetSales else 0 end),0) as [Cancelled Sales],
      isnull(sum(case when S.DateRefunded IS NOT NULL then S.NetSales else 0 end),0) as [Refunded Sales]
      FROM  CSSale S WITH(NOLOCK)
      LEFT JOIN (Select CSSaleID, Department from CSSaleItem WITH(NOLOCK) group by CSSaleID,Department) As I ON I.CSSaleID = S.CSSaleID
      LEFT JOIN CSSaleTender T WITH(NOLOCK) On S.CSSaleID = T.CSSaleID
      LEFT JOIN Media M WITH(NOLOCK) ON M.MediaIndex = T.MediaIndex
      Where   StoreDate   BETWEEN  convert(VARCHAR,@StartDate2)   AND        convert(VARCHAR,@EndDate2) 
      group by M.MediaName
      order by M.MediaName
      OPTION (OPTIMIZE FOR (@StartDate2 UNKNOWN, @EndDate2 UNKNOWN))
        END

同样的结果,我认为主报告中的结果并没有通过子报告,因为它总是只在预览中工作,但在运行时只是卡在加载中。

我试过 sp_who2 Active 检查是否被阻止。

顺便说一句,如果这有帮助,我正在我的 App.config 上使用此连接..

 <?xml version="1.0" encoding="utf-8" ?>
 <configuration>
<startup useLegacyV2RuntimeActivationPolicy="true"> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <probing privatePath="lib" />
  </assemblyBinding>
</runtime>
<connectionStrings>
  <add name="CSPOS.Reports.Properties.Settings.chaplinConnectionString" connectionString="Data Source=RENZ\SQLEXPRESS;Initial Catalog=erika;Integrated Security=True" providerName="System.Data.SqlClient"/>
 </connectionStrings>
 </configuration>

我检查了 master 上的数据库权限

【问题讨论】:

  • 您将子报表放在主报表的哪个部分?可能是导致问题的原因
  • 我把它放在报告的 Repoot Footer 部分
  • 为什么要将日期转换为 VARCHAR? “在转换(VARCHAR,@StartDate2)和转换(VARCHAR,@EndDate2)之间”
  • 我可以删除它,但这里不是这样。
  • RE VARCHAR:我已经对此进行了测试,认为这不会有问题。其他问题:主报告返回多少条记录(在您的示例中为 4 条)?如果您从 usp_ReportShowMedia 中删除所有查询以使其为空白,或者有一个虚拟 SELECT,例如“SELECT 1 as [Media], 2 as [Count], ..”,您的报告是否有效?尝试对主报告进行相同操作。总结一下:只测试配置子报表时是否可以执行空白程序。

标签: c# sql-server stored-procedures crystal-reports


【解决方案1】:

有一天我遇到了这样的情况。主要问题是存储过程中不同参数的执行计划不正确。

它可以通过 OPTION (OPTIMIZE FOR (@param UNKNOWN) 修复。您可以在here 中阅读所有相关信息。

第二个:查询中可能存在一些读锁。如果报告数据不那么敏感,您可以使用标准 WITH(NOLOCK) 提示(READ UNCOMMITTED 隔离级别)。

尝试将您的查询修改为如下所示并检查结果。

SELECT 
...
FROM CSSale S WITH(NOLOCK)
LEFT JOIN (... FROM CSSaleItem WITH(NOLOCK) ...)
LEFT JOIN CSSaleTender T WITH(NOLOCK) ...
LEFT JOIN Media M WITH(NOLOCK)
ORDER BY M.MediaName
OPTION (OPTIMIZE FOR (@StartDate2 UNKNOWN, @EndDate2 UNKNOWN))

您还需要检查用于主查询的存储过程是否存在相同问题。

附:无论如何检查 SQL Profiler 是否有传出查询。

【讨论】:

  • 嗨@andrey-nadezhdin 我尝试了选项和WithNoLock 请检查是否正确(我编辑了我的问题并将m张图片添加到我的存储过程中)
  • 我也想知道这一切是否可以在未注册版本的 SAP CR 上完成? (免费)
  • 查询似乎没问题。但是让我们尝试分几个步骤来完成。首先,去掉 WITH(NOLOCK) 提示,只留下 OPTIMIZE FOR 语句。
  • 能不能也写SQL Server版本?我在 CR 上开发更早的版本。
  • 是的,我已经尝试过了。首先只在主报表上进行优化,然后在子报表中进行优化,然后只在主报表上不加锁,然后在子报表上也不加锁。我使用的 Sql 版本是 Sql Sever 2008 R2
【解决方案2】:

让我们尝试找出问题是否与存储过程有关。

尝试通过将参数插入到某个虚拟表 (dbo.subReportParamsTb) 作为 SP 的第一条语句来捕获传递给子报表的存储过程 (dbo.usp_ReportShowMedia) 的参数。

INSERT INTO dbo.subReportParamsTb(
StartDate2,
EndDate2
) 
VALUES (
@StartDate2,
@EndDate2
);

在运行主报告后,当您看到卡住的消息时,请检查 dbo.subReportParamsTb 的包含情况,并且没有锁定。

SELECT *
FROM dbo.subReportParamsTb WITH(NOLOCK);

如果您看到参数已成功传递给 SP,请尝试使用这些参数独立运行 SP。

如果 SP 没有在有限的时间内产生输出,您可以尝试通过查看执行计划来进一步排除故障。

如果 SP 运行正常,您可以确定问题不在于 SP。

【讨论】:

  • 有这个/的SQL Profiler:
  • 嗨,@Swapnil 我试过你的测试查询ALTER PROCEDURE[dbo].[usp_ReportShowMedia]( @StartDate2 DATETIME, @EndDate2 DATETIME ) As BEGIN INSERT INTO dbo.Test( StartDate2, EndDate2 ) VALUES ( @StartDate2, @EndDate2 ); END 它仍然停留在加载中。并且没有插入任何参数,
  • 您好@FatalError,当报告卡住时,在数据库服务器上执行“sp_who2 active”以获取与报告对应的SPID。使用 sp_who2 获取 SPID 后,使用 dbcc inputbuffer(spid) 获取正在执行的 sql。我不了解水晶报表,但是这个练习将帮助您了解哪个 sql 语句被卡住了。
  • @Swapnil 嗨,当 CR 卡在加载时,我尝试运行 sp_who2 active,但我没有看到任何 BlkBy,也许这就是为什么在任务管理器上它仍在运行?我将编辑我的问题以发布屏幕截图。谢谢
  • @FatalError..如果它实际上是一个长时间运行的查询,您可能看不到阻塞。你试过dbcc inputbuffer(spid)吗?请分享截图。
【解决方案3】:

我认为这可能是两个报告之间的数据链接问题。请确保主报告和子报告具有唯一的 ID 并正确链接。

【讨论】:

    【解决方案4】:

    我通过使用两个 sqlcommand 解决了这个问题,并消除了存储过程的使用。谢谢顺便说一句。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-01
      • 1970-01-01
      • 2013-04-16
      • 1970-01-01
      • 2013-03-09
      • 1970-01-01
      相关资源
      最近更新 更多