我正在使用水晶报告根据DB中的唯一ID生成一些故障单。但是,我现在面临的挑战是在要打印的水晶报告中每英亩产生2张票。
下面我有代码应该发送查询并填充水晶报表查看器。超过9000个独特的记录和超过74000英亩的土地,这是行不通的。任何人都可以帮助或帮助更好的方法来做到这一点。
此代码运行sql server 2008 r2内存不足:
private void button1_Click(object sender, EventArgs e)
{
try{
SqlConnection con = new SqlConnection("Data Source=localhost\\DEV;Initial Catalog=db;Integrated Security=True");
var f_id = textBox2.Text; //Unique ID Not used to generate all tickets
var n_copies = textBox1.Text; //Number of copies default 1
var t_per_acre = textBox3.Text; //Set default at 2 Tickets per acre
string sql = "Select * From dbo.CParcel";
SqlDataAdapter sda = new SqlDataAdapter(sql, con);
DataSet ds = new DataSet();
sda.Fill(ds, "CParcel");
foreach (DataRow theRow in ds.Tables["CParcel"].Rows)
{
decimal get_acreage = System.Convert.ToDecimal(theRow["ACREAGE"]);
int acr = (int)(get_acreage + 0.5m);
int t_t_per_acr = acr * System.Convert.ToInt32(t_per_acre);
int t_t_per_acr_per_copy = t_t_per_acr * System.Convert.ToInt32(n_copies);
for (int i = 1; i < t_t_per_acr_per_copy; i++)
{
sql = sql + " Union All SELECT * FROM dbo.CParcel";
}
}
SqlDataAdapter tsda = new SqlDataAdapter(sql, con);
DataSet ds2 = new DataSet();
tsda.Fill(ds2, "CParcel");
crystal.SetDataSource(ds2);
crystal.SetDatabaseLogon("sa", "password");
crystalReportViewer1.ReportSource = crystal;
}
catch (Exception ex)
{
// Print error message
MessageBox.Show(ex.Message);
}
}
答案 0 :(得分:1)
考虑以下修改,这是非常小的,只是尝试收集一些计数器。
private void button1_Click(object sender, EventArgs e)
{
int i_xyz = 0, j_xyz = 0; // Drew added
try
{
SqlConnection con = new SqlConnection("Data Source=localhost\\DEV;Initial Catalog=db;Integrated Security=True");
var f_id = textBox2.Text; //Unique ID Not used to generate all tickets
var n_copies = textBox1.Text; //Number of copies default 1
var t_per_acre = textBox3.Text; //Set default at 2 Tickets per acre
string sql = "Select * From dbo.CParcel"; // STARTING POINT A
SqlDataAdapter sda = new SqlDataAdapter(sql, con);
DataSet ds = new DataSet();
sda.Fill(ds, "CParcel");
foreach (DataRow theRow in ds.Tables["CParcel"].Rows)
{
i_xyz++; // Drew added
decimal get_acreage = System.Convert.ToDecimal(theRow["ACREAGE"]);
int acr = (int)(get_acreage + 0.5m);
int t_t_per_acr = acr * System.Convert.ToInt32(t_per_acre);
int t_t_per_acr_per_copy = t_t_per_acr * System.Convert.ToInt32(n_copies);
for (int i = 1; i < t_t_per_acr_per_copy; i++)
{
j_xyz++; // Drew added
sql = sql + " Union All SELECT * FROM dbo.CParcel";
}
}
// POINT B <------------------
// STOP !!
// RIGHT HERE what is the value of i_xyz and j_xyz ?? In particular j_xyz
// also flush sql out to a text file and get a good look at it
//SqlDataAdapter tsda = new SqlDataAdapter(sql, con);
//DataSet ds2 = new DataSet();
//tsda.Fill(ds2, "CParcel");
//crystal.SetDataSource(ds2);
//crystal.SetDatabaseLogon("sa", "password");
//crystalReportViewer1.ReportSource = crystal;
}
catch (Exception ex)
{
// Print error message
MessageBox.Show(ex.Message);
}
}
在POINT B
之后,你会j_xyz
知道你在sql字符串上添加UNION ALL
的次数。我能理解你的联盟是否添加了一些其他有意义(和不同)数据子集的粒度,比如here(尽管是一个不同的数据库引擎)。但是想想一个联盟在不同数据这样的事情上很有用,而且如果没有联合就很难实现它。
但是在你的情况下,你每次只使用相同的数据进行union all select *
。并且可能在此过程中创建一个巨大的sql语句来执行此操作。那个j_xyz
变量会告诉你你加上它的次数。
其他想法包括不要指定select *
,而只是指定报告所需的列。并且还遵循内存管理的最佳实践,使用Dispose
,设置为null,或者当Adam使用&#34;使用资源时显示here时将执行的操作。&#34; Using
因此,总而言之,使用串联的sql字符串,毫无疑问例程会失败。