C# ASP.NET及;Crystal Report:使用临时表从存储过程加载数据源

C# ASP.NET及;Crystal Report:使用临时表从存储过程加载数据源,c#,asp.net,stored-procedures,sql-server-2008-r2,crystal-reports,C#,Asp.net,Stored Procedures,Sql Server 2008 R2,Crystal Reports,我使用存储过程在一个商场/地点上显示租户的monhtly sales report时实现了所需的输出。存储过程包含多个临时表(由于现有数据库结构/模式的限制),以完成我需要完成的任务。该程序在gridview中确实成功 这是存储过程 USE [DATABASENAME] GO ALTER PROCEDURE [dbo].[spName] // parameters @Location int, // the location number @CurrentMonthStart date ,

我使用存储过程在一个商场/地点上显示租户的monhtly sales report时实现了所需的输出。存储过程包含多个临时表(由于现有数据库结构/模式的限制),以完成我需要完成的任务。该程序在gridview中确实成功

这是存储过程

USE [DATABASENAME]
GO

ALTER PROCEDURE [dbo].[spName]
// parameters

@Location int, // the location number
@CurrentMonthStart date ,
@MonthCurrent varchar(20),
@MonthPrevious varchar(20)



AS
BEGIN
 //Using the CurrentMonthStart data, I formulated the other essential variable needed for the query to run
declare @PreviousMonthStart date
declare @PreviousMonthEnd date
declare @CurrentMonthEnd date
declare @query varchar (8000)

set @PreviousMonthStart  =   convert(varchar(10), DATEADD(m,-1, @CurrentMonthStart) , 101)
set @PreviousMonthEnd   =   convert(varchar(10), DATEADD(d,-1, @CurrentMonthStart) , 101)
set @CurrentMonthEnd    =   convert(varchar(10), DATEADD(d, -1, DATEADD(m,1, @CurrentMonthStart)) , 101)



// i used temp table several times
select b.tenantcode, b.date , SUM(a.other)as discount
        INTO #NewDiscountTable
        from DAILY a INNER JOIN DISCOUNT b on a.date = b.date and a.tenantcode = b.tenantcode 
        WHERE b.date between @PreviousMonthStart  AND @CurrentMonthEnd  and A.location = @Location 
        group by b.date, b.tenantcode 
        order by b.tenantcode 


        select tenantcode , SUM(discount) as Approved_Disc
        into #NewDiscountTableFinal
        from #NewDiscountTable 
        where  date between @PreviousMonthStart  AND @PreviousMonthEnd
        group by tenantcode

        select tenantcode , SUM(discount) as Approved_Disc2
        into #NewDiscountTableFinal2
        from #NewDiscountTable 
        where  date between @CurrentMonthStart AND @CurrentMonthEnd  
        group by tenantcode




select  b.sqm  as 'FLOOR AREA/SQM',  b.name as 'RETAIL PARTNERS' , 
        convert(varchar(10), a.date, 101) as Date, datename(weekday, a.date) as Day,
        ((sum(a.cash) + SUM(a.charge) + SUM(a.gift)+ SUM(a.other)) - (SUM(a.surcharge))) as GSC,
        a.location , a.tenantcode 
        into #NewDailySalesTenderTable
        from  TENANT b inner join LOCATION c on b.location=c.location inner join DAILY a on a.tenantcode=b.tenantcode

        where a.location = @Location and b.status  > 1 and
            a.date  BETWEEN  @PreviousMonthStart and @CurrentMonthEnd 

        GROUP BY  b.name, a.date , a.location , a.tenantcode , b.sqm
        order by b.name, A.DATE



        select  [FLOOR AREA/SQM], [RETAIL PARTNERS] , Tenantcode,  SUM(GSC) as GSCwithOtherDisc
        into #NewDailySalesTenderTableFinal 
        from #NewDailySalesTenderTable 
        where date  BETWEEN  @PreviousMonthStart and @PreviousMonthEnd
        GROUP BY [Retail Partners], tenantcode, [FLOOR AREA/SQM]
        ORDER BY [Retail Partners]



        select  [FLOOR AREA/SQM], [RETAIL PARTNERS] ,  Tenantcode,  SUM(GSC) as GSCwithOtherDisc2
        into #NewDailySalesTenderTableFinal2 
        from #NewDailySalesTenderTable 
        where  date between @CurrentMonthStart  AND @CurrentMonthEnd  
        GROUP BY [Retail Partners], tenantcode, [FLOOR AREA/SQM]
        ORDER BY [Retail Partners]



select A.[FLOOR AREA/SQM] , a.[Retail Partners], 

          case when a.tenantcode  in (select d.tenantcode from #NewDiscountTableFinal2 d ) -- case within case kasi pag 0 yung divisor may error
            then Round(((c.GSCwithOtherDisc2   - d.Approved_Disc2  )/(case when a.[FLOOR AREA/SQM] = 0 then null else (a.[FLOOR AREA/SQM]) end)   ),0)
            else Round(((c.GSCwithOtherDisc2  - 0)/ (case when a.[FLOOR AREA/SQM] = 0 then null else (a.[FLOOR AREA/SQM]) end) ),0)
            end as 'SALES/SQM',



            case when a.tenantcode  in (select d.tenantcode from #NewDiscountTableFinal2 d )
            then Round((c.GSCwithOtherDisc2   - d.Approved_Disc2  ),0)
            else Round((c.GSCwithOtherDisc2  - 0),0)
            end as CurrentMonth,

            case when a.tenantcode  in (select b.tenantcode from #NewDiscountTableFinal b )
            then Round((a.GSCwithOtherDisc  - b.Approved_Disc ),0)
            else Round((a.GSCwithOtherDisc  - 0),0)
            end as PreviousMonth


            --case when a.tenantcode  in (select b.tenantcode from #NewDiscountTableFinal b )
            --then Round((((((c.GSCwithOtherDisc2   - d.Approved_Disc2  )- (a.GSCwithOtherDisc  - b.Approved_Disc )) / (a.GSCwithOtherDisc  - b.Approved_Disc )) * 100)),0)
            --else Round((C.GSCwithOtherDisc2  - 0),0)
            --end as '%INC/DEC'

        into #FinalResult
        FROM #NewDailySalesTenderTableFinal  a left join  #NewDiscountTableFinal b on a.tenantcode = b.tenantcode join
        #NewDailySalesTenderTableFinal2 c on a.tenantcode = c.tenantcode left join #NewDiscountTableFinal2 d on c.tenantcode = d.tenantcode


 set @query = 'select [Retail Partners],[FLOOR AREA/SQM], ' +
'replace(convert(varchar,cast(([SALES/SQM])  as money),1), ''.00'','''') as ''SALES/SQM'',' +
'replace(convert(varchar,cast((CurrentMonth)  as money),1), ''.00'','''') as ' + @MonthCurrent  +
',replace(convert(varchar,cast((PreviousMonth)  as money),1), ''.00'','''') as ' + @MonthPrevious   +

',case when PreviousMonth = 0 
then ''N/A''' +
'else  replace(convert(varchar,cast(Round((((CurrentMonth-PreviousMonth)/ PreviousMonth    ) *100),0) as money),1), ''.00'','''') 
end as ''%INC/DEC'' ' +
'from #FinalResult '
 execute(@query)


END
我已经找到了问题的根源 存储过程的最后一部分是冲突的根源。我在其中设置参数-@MonthCurrent和@MonthPrevious作为查询的生成列,这些列基于用户选择的内容。我通过注释这些部分来隔离问题,看看它是否会在Crystal Report中运行,它确实做到了

问题是:如何在Crystal REPORT中加入这些列?

set @query = 'select [Retail Partners],[FLOOR AREA/SQM], ' +
    'replace(convert(varchar,cast(([SALES/SQM])  as money),1), ''.00'','''') as ''SALES/SQM'',' +
    'replace(convert(varchar,cast((CurrentMonth)  as money),1), ''.00'','''') as ' + @MonthCurrent  +
    ',replace(convert(varchar,cast((PreviousMonth)  as money),1), ''.00'','''') as ' + @MonthPrevious   +

    ',case when PreviousMonth = 0 
    then ''N/A''' +
    'else  replace(convert(varchar,cast(Round((((CurrentMonth-PreviousMonth)/ PreviousMonth    ) *100),0) as money),1), ''.00'','''') 
    end as ''%INC/DEC'' ' +
    'from #FinalResult '
示例屏幕截图,在gridview中成功运行SP

现在,我还想合并相同的存储过程,这次将数据填充到Crystal Report中,使用所述SP作为我的数据源。以下是我开始的内容

 protected void Page_Load(object sender, EventArgs e)
    {
        con.Open();

//I pass the values of parameter from the page to the print page using Session
        Label1.Text = Session["Location"].ToString();
        int Loc = Convert.ToInt32(Label1.Text);

        Label2.Text = Session["CurrentMonthStart"].ToString();
        DateTime dt = Convert.ToDateTime(Label2.Text);

        Label3.Text = Session["MonthCurrent"].ToString();
        Label4.Text = Session["MonthPrevious"].ToString();


      report.Load(Server.MapPath("MonthlySalesReport.rpt"));

        CrystalReportViewer1.ReportSource = report;
        CrystalReportViewer1.ReuseParameterValuesOnRefresh = true;
        CrystalReportViewer1.DataBind();

        report.SetParameterValue(0, Loc);
        report.SetParameterValue(1, dt);
        report.SetParameterValue(2, Label3.Text);
        report.SetParameterValue(3, Label4.Text);

        con.Close();

    }
这是存储的pro中所述问题导致的错误


在结果集中找不到一个或多个字段。使用验证数据库更新报告。文件MonthlySalesReport{0E90B4CE-8D1A-4712-BE05-9C1DC8CC9ADB}中出错。rpt:找不到行集列。

CR只能读取查询返回的内容。您可以看到类似的问题和解决方案。所有这些人都有和你一样的问题,瑞奇。阅读并看看它是否有帮助。如果没有,不要浪费你的时间找一份工作。如果我是你。我已经创建了一个新表
dbo.mytentable
,并在调用过程时刷新它

DELETE FROM dbo.MyTempTable
INSERT INTO dbo.myTempTable(Col1, Col 2, Col3, Col4 , Col5, Col6 ..)

    select [Retail Partners],[FLOOR AREA/SQM], ' +
    'replace(convert(varchar,cast(([SALES/SQM])  as money),1), ''.00'','''') as ''SALES/SQM'',' +
    'replace(convert(varchar,cast((CurrentMonth)  as money),1), ''.00'','''') as ' + @MonthCurrent  +
    ',replace(convert(varchar,cast((PreviousMonth)  as money),1), ''.00'','''') as ' + @MonthPrevious   +

    ',case when PreviousMonth = 0 
    then ''N/A''' +
    'else  replace(convert(varchar,cast(Round((((CurrentMonth-PreviousMonth)/ PreviousMonth    ) *100),0) as money),1), ''.00'','''') 
    end as ''%INC/DEC'' ' +
    'from #FinalResult '
在上面你总是空的诱惑。然后用查询返回的内容填充临时表

然后继续并创建另一个过程或仅创建视图。像

CREATE PROCEDURE dbo.MyTempTableProcedure

AS 
  BEGIN 
     SELECT * FROM myTempTable
  END  
转到报告并将数据源更新为MyTestableProcedure。这是绕着走。在后端c#中。在打印结果之前,先执行该过程。您不会对此有问题,因为您已经使用gridview了

        Label1.Text = Session["Location"].ToString();
        int Loc = Convert.ToInt32(Label1.Text);

        Label2.Text = Session["CurrentMonthStart"].ToString();
        DateTime dt = Convert.ToDateTime(Label2.Text);

        Label3.Text = Session["MonthCurrent"].ToString();
        Label4.Text = Session["MonthPrevious"].ToString();

       //EXECCUTE the procedure here
        using(SqlCommand cmd = new SqlCommand("spName",con)
        {
           cmd.CommandType = CommandType .StoredProcedure;
           cmd.Parameters.AddwithValue("@Location", LOC);
           cmd.Parameters.AddwithValue("@CurrentMonthStart ",   Label3.Text);
           cmd.Parameters.AddwithValue("@date ",   dt);
           cmd.Parameters.AddwithValue("@CurrentMonthStart ",   Label4.Text);

          cmd.ExecuteNonQuery();
        } 
        report.Load(Server.MapPath("MonthlySalesReport.rpt"));

        CrystalReportViewer1.ReportSource = report;
        CrystalReportViewer1.ReuseParameterValuesOnRefresh = true;

        con.Close();

这应该是一次散步。这就是我的想法。希望有帮助。

您是否尝试逐一运行每个查询。。似乎您正在尝试绑定查询中不存在的列字段名。。请确保报告和查询中的拼写正确。您是否也仔细阅读了代码?您好@DJKRAZE是的,我在后端部分-SQL中逐个运行了每个查询,它实际上运行成功,这就是为什么我能够在gridview中加载完美的数据。dt实际上是Label2.text中的@CurrentMonthStart参数,我需要将其转换为datetime数据类型,因为在存储的pro中,它被标记为datetime;在sp中,然后尝试删除此行计数。然后重新生成解决方案并尝试重新运行报告。那么,报告中说找不到哪一列。。?您是否查看了CrystalReport designer,以确保当它尝试绑定到实际列名时,它会绑定到实际列名谢谢,我现在正在尝试,一个问题是,是否能够保留当前月份和上一个月份的动态列名?因为它从temp表中创建了一个新列?@rickyProgrammer。您可以使用您喜欢的确切列名创建新表。然后将选择返回的记录插入表中。相信我,这是直截了当的。如果查询返回列,请使用从临时表返回的列名称创建新表。然后将所有内容插入新表。然后,您的新存储过程从新表中选择*并发送到您的报告。这很简单,不是吗?是的,听起来很酷,它实际上与我在整个存储过程中所做的非常相似,我使用临时表在gridview中实现了我想要的最终输出。我真正想要的是在Crystal Report中也实现这一点。在您的想法或概念的启发下,我也想到了为Crystal report创建一个存储过程副本,并用静态名称更改列名,而不是参数化的列名。您好,这个方法奏效了!谢谢,我也想到了其他方法来实现我想要的基于你的想法,使用代码,我已经开始基于你的想法。