用于 Crystal 报表的存储过程会覆盖以前的记录
Stored procedure used for Crystal Reports overwrites previous records
我有以下代码调用存储过程来填充 Crystal 报告。问题是最后一条记录是唯一返回的记录,并且在整个报告中重复出现。它似乎正在覆盖以前的记录,而不是返回与 ID 参数关联的每条记录。我错过了什么吗?
Dim idSQL As String = "SELECT DISTINCT ID FROM table"
drID = objdata.getOLEDBDR(MSCON1, idSQL)
While drID.Read
IDall = drID(0)
'GET DATA******************************
sqlstr = "SELECT columnname FROM tablename WHERE Id = '" & IDall & "'"
Dim DAscp As New OleDbDataAdapter(sqlstr, MSCON1)
dsQRpt.EnforceConstraints = False
DAscp.Fill(dsQRpt, "tablename")
'GET DATA FROM SP***********************
Dim cmd As OleDbCommand = New OleDbCommand()
cmd.Connection = MSCON
cmd.CommandType = CommandType.StoredProcedure
cmd.CommandText = "NAME_OF_SP"
cmd.Parameters.Add("@month", OleDbType.VarChar, 10, ParameterDirection.Output).Value = QtrMonth
cmd.Parameters.Add("@year", OleDbType.VarChar, 10, ParameterDirection.Output).Value = cboYear.SelectedValue
cmd.Parameters.Add("@id", OleDbType.VarChar, 10, ParameterDirection.Output).Value = IDall
Dim DAms As New OleDbDataAdapter()
DAms.SelectCommand = cmd
'DAms.Fill(dsQRpt)
DAms.Fill(dsQRpt, "SP_NAME")
'Populate Report*********************************************************************
QPrpt.Load(Server.MapPath("rptQuarterly.rpt"))
QPrpt.SetDataSource(dsQRpt)
crQtrProgress.ReportSource = QPrpt
QPrpt.SetParameterValue("vPTSID", PTSall)
crQtrProgress.DataBind()
End While
存储过程如下:
USE [DB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SP_NAME]
(
@month varchar(20),
@year varchar (4),
@id varchar (15)
)
AS
DECLARE @tmp table
(
ID nvarchar(10),
CategoryId nvarchar(5),
CategoryName nvarchar(50),
MDate datetime
)
DECLARE @i varchar(10)
DECLARE @sql varchar(1000)
SET @i = 1
DECLARE @j varchar(10)
SET @j = 1
WHILE (@i <=28)
BEGIN
DECLARE @MIDDATE nvarchar(25)
DECLARE @MIDID nvarchar(15)
SET @MIDDATE = 'mh.MID_'+@i+'_DATE'
SET @MIDID = 'mh.MID_'+@i
IF (((@i= 9) OR (@i =12)) AND (@j = 1))
BEGIN
--SET @j = 2
SET @MIDDATE = 'mh.MID_'+@i+'a_DATE'
SET @MIDID = 'mh.MID_'+@i+'a'
END
IF (((@i= 9) OR (@i = 12)) AND (@j = 2))
BEGIN
SET @MIDDATE = 'mh.MID_'+@i+'b_DATE'
SET @MIDID = 'mh.MID_'+@i+'b'
END
SET @sql ='SELECT mh.ID, mc.CategoryId, mc.CategoryName, '+ @MIDDATE +'
FROM MHistory As mh, MCategories As mc WHERE mc.CategoryId = SUBSTRING('''+
@MIDID +''',8,10) AND mh.ID = ''' + @id + ''' AND mh.Hist_Yr = ' + @year + '
AND mh.Hist_Month = ''' + @month + ''' ORDER BY mh.ID'
INSERT INTO @tmp
EXEC (@sql)
IF (((@i= 9) OR (@i=12)) AND (@j = 1))
BEGIN
IF @i= 9 SET @i = 9
IF @i =12 SET @i = 12
SET @j = 2
END
ELSE
BEGIN
SET @i = @i + 1
SET @j = 1
END
END
----SET @i = @i + 1
SELECT
ID AS ID,
CategoryId AS CategoryId,
CategoryName AS CategoryName,
MDate AS MDate
from @tmp
似乎对报表数据源的查询总是返回一条记录,因为您的数据源查询正在过滤 Id
,我认为这是 tablename
.[=18= 的主键]
'GET DATA******************************
sqlstr = "SELECT columnname FROM tablename WHERE Id = '" & IDall & "'"
Dim DAscp As New OleDbDataAdapter(sqlstr, MSCON1)
dsQRpt.EnforceConstraints = False
DAscp.Fill(dsQRpt, "tablename")
此外,我建议您验证报表是否使用正确的参数调用了存储过程。您可以通过在存储过程中的最后一个 SELECT
之前填充自定义 table 来完成此操作。在此自定义 table 中,您可以记录参数值以及您认为与情况相关的任何其他内容。
您可以使用以下查询来执行此日志记录。
为日志记录创建自定义 tables
CREATE TABLE CustomLoggingTable (Parameters varchar(max), RunDate DateTime);
CREATE TABLE CustomResultsTable (ID int, CategoryId int, CategoryName varchar(500),
MDate DateTime);
将下面的查询添加为程序的最后一部分(此代码中的最后 SELECT 是您原来的 SELECT,您不应更改它,而只需将另一部分在它之前)
记录您的存储过程
--log procedure parameters
INSERT INTO CustomLoggingTable ( Parameters, RunDate)
select '@month = ' + isnull(@month,'') + ', @year = ' + isnull(@year,'')
+ ', @id = ' + isnull( @id,''), getdate() ;
--log result set being returned into a custom table
DELETE from CustomResultsTable;
INSERT into CustomResultsTable (ID, CategoryId, CategoryName, MDate)
SELECT
ID AS ID,
CategoryId AS CategoryId,
CategoryName AS CategoryName,
MDate AS MDate
from @tmp
--this is your last statement in procedure for returning final result set
SELECT
ID AS ID,
CategoryId AS CategoryId,
CategoryName AS CategoryName,
MDate AS MDate
from @tmp
完成上述设置后,您可以准确查看调用存储过程时发生的情况。 CustomResultsTable
每次都会刷新返回最新的结果集,而 CustomLoggingTable
会为每个 运行 过程添加一条新记录。
我有以下代码调用存储过程来填充 Crystal 报告。问题是最后一条记录是唯一返回的记录,并且在整个报告中重复出现。它似乎正在覆盖以前的记录,而不是返回与 ID 参数关联的每条记录。我错过了什么吗?
Dim idSQL As String = "SELECT DISTINCT ID FROM table"
drID = objdata.getOLEDBDR(MSCON1, idSQL)
While drID.Read
IDall = drID(0)
'GET DATA******************************
sqlstr = "SELECT columnname FROM tablename WHERE Id = '" & IDall & "'"
Dim DAscp As New OleDbDataAdapter(sqlstr, MSCON1)
dsQRpt.EnforceConstraints = False
DAscp.Fill(dsQRpt, "tablename")
'GET DATA FROM SP***********************
Dim cmd As OleDbCommand = New OleDbCommand()
cmd.Connection = MSCON
cmd.CommandType = CommandType.StoredProcedure
cmd.CommandText = "NAME_OF_SP"
cmd.Parameters.Add("@month", OleDbType.VarChar, 10, ParameterDirection.Output).Value = QtrMonth
cmd.Parameters.Add("@year", OleDbType.VarChar, 10, ParameterDirection.Output).Value = cboYear.SelectedValue
cmd.Parameters.Add("@id", OleDbType.VarChar, 10, ParameterDirection.Output).Value = IDall
Dim DAms As New OleDbDataAdapter()
DAms.SelectCommand = cmd
'DAms.Fill(dsQRpt)
DAms.Fill(dsQRpt, "SP_NAME")
'Populate Report*********************************************************************
QPrpt.Load(Server.MapPath("rptQuarterly.rpt"))
QPrpt.SetDataSource(dsQRpt)
crQtrProgress.ReportSource = QPrpt
QPrpt.SetParameterValue("vPTSID", PTSall)
crQtrProgress.DataBind()
End While
存储过程如下:
USE [DB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SP_NAME]
(
@month varchar(20),
@year varchar (4),
@id varchar (15)
)
AS
DECLARE @tmp table
(
ID nvarchar(10),
CategoryId nvarchar(5),
CategoryName nvarchar(50),
MDate datetime
)
DECLARE @i varchar(10)
DECLARE @sql varchar(1000)
SET @i = 1
DECLARE @j varchar(10)
SET @j = 1
WHILE (@i <=28)
BEGIN
DECLARE @MIDDATE nvarchar(25)
DECLARE @MIDID nvarchar(15)
SET @MIDDATE = 'mh.MID_'+@i+'_DATE'
SET @MIDID = 'mh.MID_'+@i
IF (((@i= 9) OR (@i =12)) AND (@j = 1))
BEGIN
--SET @j = 2
SET @MIDDATE = 'mh.MID_'+@i+'a_DATE'
SET @MIDID = 'mh.MID_'+@i+'a'
END
IF (((@i= 9) OR (@i = 12)) AND (@j = 2))
BEGIN
SET @MIDDATE = 'mh.MID_'+@i+'b_DATE'
SET @MIDID = 'mh.MID_'+@i+'b'
END
SET @sql ='SELECT mh.ID, mc.CategoryId, mc.CategoryName, '+ @MIDDATE +'
FROM MHistory As mh, MCategories As mc WHERE mc.CategoryId = SUBSTRING('''+
@MIDID +''',8,10) AND mh.ID = ''' + @id + ''' AND mh.Hist_Yr = ' + @year + '
AND mh.Hist_Month = ''' + @month + ''' ORDER BY mh.ID'
INSERT INTO @tmp
EXEC (@sql)
IF (((@i= 9) OR (@i=12)) AND (@j = 1))
BEGIN
IF @i= 9 SET @i = 9
IF @i =12 SET @i = 12
SET @j = 2
END
ELSE
BEGIN
SET @i = @i + 1
SET @j = 1
END
END
----SET @i = @i + 1
SELECT
ID AS ID,
CategoryId AS CategoryId,
CategoryName AS CategoryName,
MDate AS MDate
from @tmp
似乎对报表数据源的查询总是返回一条记录,因为您的数据源查询正在过滤 Id
,我认为这是 tablename
.[=18= 的主键]
'GET DATA******************************
sqlstr = "SELECT columnname FROM tablename WHERE Id = '" & IDall & "'"
Dim DAscp As New OleDbDataAdapter(sqlstr, MSCON1)
dsQRpt.EnforceConstraints = False
DAscp.Fill(dsQRpt, "tablename")
此外,我建议您验证报表是否使用正确的参数调用了存储过程。您可以通过在存储过程中的最后一个 SELECT
之前填充自定义 table 来完成此操作。在此自定义 table 中,您可以记录参数值以及您认为与情况相关的任何其他内容。
您可以使用以下查询来执行此日志记录。
为日志记录创建自定义 tables
CREATE TABLE CustomLoggingTable (Parameters varchar(max), RunDate DateTime);
CREATE TABLE CustomResultsTable (ID int, CategoryId int, CategoryName varchar(500),
MDate DateTime);
将下面的查询添加为程序的最后一部分(此代码中的最后 SELECT 是您原来的 SELECT,您不应更改它,而只需将另一部分在它之前)
记录您的存储过程
--log procedure parameters
INSERT INTO CustomLoggingTable ( Parameters, RunDate)
select '@month = ' + isnull(@month,'') + ', @year = ' + isnull(@year,'')
+ ', @id = ' + isnull( @id,''), getdate() ;
--log result set being returned into a custom table
DELETE from CustomResultsTable;
INSERT into CustomResultsTable (ID, CategoryId, CategoryName, MDate)
SELECT
ID AS ID,
CategoryId AS CategoryId,
CategoryName AS CategoryName,
MDate AS MDate
from @tmp
--this is your last statement in procedure for returning final result set
SELECT
ID AS ID,
CategoryId AS CategoryId,
CategoryName AS CategoryName,
MDate AS MDate
from @tmp
完成上述设置后,您可以准确查看调用存储过程时发生的情况。 CustomResultsTable
每次都会刷新返回最新的结果集,而 CustomLoggingTable
会为每个 运行 过程添加一条新记录。