C# 单击一个按钮调用多个存储过程和GridView
背景:我正在转换一个access运行时,它按邮政编码、计划类型和年龄搜索计划 到目前为止,,我在主搜索中正确显示了存储过程C# 单击一个按钮调用多个存储过程和GridView,c#,asp.net,sql-server-2008,stored-procedures,gridview,C#,Asp.net,Sql Server 2008,Stored Procedures,Gridview,背景:我正在转换一个access运行时,它按邮政编码、计划类型和年龄搜索计划 到目前为止,,我在主搜索中正确显示了存储过程get_zip_plan_age,但不确定我是否在C#code behind中正确调用了存储过程get_lost_femal_insurance_rate,以及如何为显示最低女性的get_lost_female_rate编写不同的代码每个年龄组的比率vsget\u zip\u plan\u age显示所有数据 问题: 如何在代码隐藏中正确调用get\u lower\u fe
get_zip_plan_age
,但不确定我是否在C#code behind中正确调用了存储过程get_lost_femal_insurance_rate
,以及如何为显示最低女性的get_lost_female_rate
编写不同的代码每个年龄组的比率vsget\u zip\u plan\u age
显示所有数据
问题:
- 如何在代码隐藏中正确调用
?我说的对吗get\u lower\u femal\u rate
- 如何为显示每个年龄组(65、70、75、80)的最低女性比率的
编写存储过程代码get_lower_femal_rate
protected void Search_Zip_Plan_Age_Button_Click(object sender, EventArgs e)
{
using (SqlConnection cn = new SqlConnection())
{
cn.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["PriceFinderConnectionString"].ToString();
cn.Open();
using (SqlCommand cmd = cn.CreateCommand())
{
cmd.CommandText = "get_zip_plan_age";
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "get_lowest_female_rate";
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "get_lowest_male_rate";
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "get_carrier_info";
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter parm = cmd.CreateParameter();
parm.ParameterName = "@insur_age";
parm.DbType = DbType.Int64;
parm.Value = Convert.ToInt64(this.insur_age.Text);
cmd.Parameters.Add(parm);
parm = cmd.CreateParameter();
parm.ParameterName = "@zip_code";
parm.DbType = DbType.String;
parm.Value = this.ZipCode.Text;
cmd.Parameters.Add(parm);
parm = cmd.CreateParameter();
parm.ParameterName = "@plan_code";
parm.DbType = DbType.String;
parm.Value = this.PlanCode.Text;
cmd.Parameters.Add(parm);
SqlDataReader reader = cmd.ExecuteReader();
Zip_Plan_Age_GridView.DataSource = reader;
Zip_Plan_Age_GridView.DataBind();
}
}
}
下面是显示所有数据的存储过程get\u zip\u plan\u age的代码:
ALTER PROCEDURE get_zip_plan_age
-- Add the parameters for the stored procedure here
@zip_code nvarchar(16),
@plan_code nvarchar(16),
@insur_age int = 0
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
IF @insur_age > 0
BEGIN
SELECT
[state_code],
[zip_code],
[female_value],
[male_value],
[carrier_name],
[update_date],
[insur_age],
[plan_code],
[spousal_discount]
FROM [state_zipcode_plans]
WHERE (([insur_age] = @insur_age)
AND ([zip_code] = @zip_code)
AND ([plan_code] = @plan_code))
ORDER BY [male_value], [plan_code]
END
ELSE BEGIN
SELECT
[state_code],
[zip_code],
[female_value],
[male_value],
[carrier_name],
[update_date],
[insur_age],
[plan_code],
[spousal_discount]
FROM [state_zipcode_plans]
WHERE (([zip_code] = @zip_code)
AND ([plan_code] = @plan_code))
ORDER BY [male_value], [plan_code]
END
END
GO
在方法搜索_Zip _计划_年龄_按钮_单击您已多次设置cmd.CommandText和cmd.CommandType。在这种情况下,只能设置一次-它们的值为cmd.CommandText=“get_carrier_info”;cmd.CommandType=CommandType.storedProcess <> >为了使代码更可维护,请考虑将命令创建到工厂,
就sp而言,我只能看到get\u zip\u plan\u age的sp。我的建议是:如果要将内容绑定到用户可以查看/编辑的表单,请不要使用
SqlDataReader
。这将使数据库连接保持打开状态—可能会持续很长时间
如果您使用表单来显示数据,我会使用ORM(对象关系映射器)从数据库中获取对象列表——或者,如果这不是您想要的,那么至少使用一个DataTable
,它获取数据,然后允许您断开与数据库的连接,直到您实际需要更新内容为止(或读取新数据)
至于调用存储的进程:
- BIG使用
块的
奖励
- 我会尽可能晚地打开连接-它不必在创建参数和内容时打开-只在需要读取数据之前打开它
- 我会尝试将UI代码(读取文本框,绑定到网格)从实际代码中分离出来以加载数据-您可能希望在某个时候将其放入数据访问层(单独的类库)-不要将加载数据与操作UI混为一谈
- 我会将对单个存储过程的各个调用分开——只有四个方法,您可以在需要时使用所需的参数调用它们
protected void Search_Zip_Plan_Age_Button_Click(object sender, EventArgs e)
{
string _connStr = ConfigurationManager.ConnectionStrings["PriceFinderConnectionString"].ConnectionString;
DataTable data = LoadZipPlanAge(_connStr, .......);
Zip_Plan_Age_GridView.DataSource = data;
Zip_Plan_Age_GridView.DataBind();
}
protected DataTable LoadZipPlanAge(string connString, Int64 insurAge, string zipCode, string planCode)
{
string storedProcName = "dbo.get_zip_plan_age";
DataTable table = new DataTable();
using (SqlConnection cn = new SqlConnection(connString))
using (SqlCommand cmd = new SqlCommand(storedProcName, cn))
{
cmd.CommandType = CommandType.StoredProcedure;
// create parameters
cmd.Parameters.Add("@insur_age", SqlDbType.Int64).Value = int64Value;
.......
SqlDataAdapter dap = new SqlDataAdapter(cmd);
dap.Fill(table);
}
return table;
}
用逻辑,
- 如果选择了保险年龄,则仅显示该年龄的最低女性费率,选择年龄为指定年龄的最高(1)最低女性值
- 如果为保险年龄选择了“全部”,则通过选择顶部(1)最小女性值来显示最低女性费率,其中邮政编码、计划代码与指定的搜索值匹配,并且男性费率大于0,按保险年龄、男性值、承运人名称分组,并针对65、70、75、80年龄组的每个年龄组进行联合
ALTER PROCEDURE [dbo].[get_lowest_female_rate]
-- Add the parameters for the stored procedure here
@zip_code nvarchar(16),
@plan_code nvarchar(16),
@insur_age int = 0
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
-- If an Insurance Age is selected, only display the min Female rate for that age
IF @insur_age > 0
BEGIN
SELECT TOP(1)
[carrier_name],
[insur_age],
MIN([female_value])
FROM [state_zipcode_plans]
WHERE (([insur_age] = @insur_age)
AND ([zip_code] = @zip_code)
AND ([plan_code] = @plan_code)
AND ([female_value] > 0))
GROUP BY
[insur_age], [female_value], [carrier_name]
END
-- If ALL is selected for Insurance Age, Display Lowest Female Rate for Each of the Age Groups 65, 70, 75, 80
ELSE BEGIN
SELECT TOP(1)
[carrier_name],
[insur_age],
MIN([female_value])
FROM [state_zipcode_plans]
WHERE (([zip_code] = @zip_code)
AND ([plan_code] = @plan_code)
AND ([female_value] > 0)
AND ([insur_age] = 65))
GROUP BY
[insur_age], [female_value], [carrier_name]
UNION
SELECT TOP(1)
[carrier_name],
[insur_age],
MIN([female_value])
FROM [state_zipcode_plans]
WHERE (([zip_code] = @zip_code)
AND ([plan_code] = @plan_code)
AND ([female_value] > 0)
AND ([insur_age] = 70))
GROUP BY
[insur_age], [female_value], [carrier_name]
UNION
SELECT TOP(1)
[carrier_name],
[insur_age],
MIN([female_value])
FROM [state_zipcode_plans]
WHERE (([zip_code] = @zip_code)
AND ([plan_code] = @plan_code)
AND ([female_value] > 0)
AND ([insur_age] = 75))
GROUP BY
[insur_age], [female_value], [carrier_name]
UNION
SELECT TOP(1)
[carrier_name],
[insur_age],
MIN([female_value])
FROM [state_zipcode_plans]
WHERE (([zip_code] = @zip_code)
AND ([plan_code] = @plan_code)
AND ([female_value] > 0)
AND ([insur_age] = 80))
GROUP BY
[insur_age], [female_value], [carrier_name]
END
END
好的,我将创建一个单独的(SqlCommand cmd123=cn.CreateCommand())对于每个存储过程,是吗?基本上是的,但是如果您使用前面提到的命令模式,您可以隐藏此低级逻辑并以通用方式创建此Sql命令。还可以使用DataTable断开您的结果,正如其他人在下面建议的那样。您可以为此提供一些示例代码吗?目前我编写了使用(SqlCommand cmd=cn.CreateCommand())语句多次使用不同的变量请不要放置“ASP.NET C#SQL”在标题中。我们有相应的标签。感谢您的回复!我不会编辑任何数据,只会显示它。所以我应该使用ORM还是DataTable?您可以在dataTables上添加一个带有更多示例代码的链接吗?除了DataTable data=LoadZipPlanAge(_connStr,…)之外,我还放了什么;?@Brian McCarthy:如果您只想显示数据,那么数据表就可以了。SqlDataAdapter将填充您的DataTable,并从底层SQL语句在DataTable中创建必要的列-您不需要更多,只需要我显示的代码。DataTable是ADO.NET的一部分-任何ADO.NET教程都会向您展示如何使用和充分利用数据表。一些ADO.NET教程链接:,或