【发布时间】:2017-10-17 08:12:14
【问题描述】:
在我的应用程序中执行 SQL Server 存储过程时遇到问题。我以前没有遇到过这个问题。
我的数据类是:
public static string conStr
{
get { return ConfigurationManager.ConnectionStrings["conn"].ConnectionString; }
}
public static string Provider
{
get { return ConfigurationManager.ConnectionStrings["conn"].ProviderName; } //Proveedor de DB
}
//DB PROVIDER FACTORY: Objetos de Conexion
public static System.Data.Common.DbProviderFactory dpf
{
get { return DbProviderFactories.GetFactory(Provider); }
}
private static int ejecutaNonQuery(string StoredProcedure, List<DbParameter> parametros)
{//execute nonquery retorna el numero de columnas afectadas en una dB
int Id = 0; //variable para saber cuantos elementos se modificaron despues del ejecutenonquery
try
{
using (DbConnection con = dpf.CreateConnection()) //al usar using la conexion se cerrara automaticamente
{
con.ConnectionString = conStr;
using (DbCommand cmd = dpf.CreateCommand())
{
cmd.Connection = con;
cmd.CommandText = StoredProcedure;
cmd.CommandType = CommandType.StoredProcedure;
foreach (DbParameter param in parametros)
cmd.Parameters.Add(param);
con.Open();
Id = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
}
}
}
catch (Exception ex)
{
throw ex;
}
finally
{ }
return Id;
}
这是执行:
public int Lotes_Crear_Consolidado(string cliCodigo, string cajCodigo, int cajNumero,
int cajConNumero, string cajConCodigo,
string id1Desde, string id1Hasta,
string id2Desde, string id2Hasta,
string id3Desde, string id3Hasta,
string id4Desde, string id4Hasta,
string id5Desde, string id5Hasta,
string altaPor, string lotEstado,
DateTime fecEmiLot, DateTime fecCadLot)
{
List<DbParameter> paramLotesConsol = new List<DbParameter>();
DbParameter param1 = dpf.CreateParameter();
param1.DbType = DbType.String;
param1.Value = cliCodigo;
param1.ParameterName = "CLIENTE_CODIGO";
paramLotesConsol.Add(param1);
DbParameter param2 = dpf.CreateParameter();
param2.DbType = DbType.String;
param2.Value = cajCodigo;
param2.ParameterName = "CAJA_CODIGO";
paramLotesConsol.Add(param2);
DbParameter param3 = dpf.CreateParameter();
param3.DbType = DbType.Int16;
param3.Value = cajNumero;
param3.ParameterName = "CAJA_NUMERO";
paramLotesConsol.Add(param3);
DbParameter param4 = dpf.CreateParameter();
param4.DbType = DbType.Int16;
param4.Value = cajConNumero;
param4.ParameterName = "CAJA_CONTENIDO_NUMERO";
paramLotesConsol.Add(param4);
DbParameter param5 = dpf.CreateParameter();
param5.DbType = DbType.String;
param5.Value = cajConCodigo;
param5.ParameterName = "CAJA_CONTENIDO_CODIGO";
paramLotesConsol.Add(param5);
DbParameter param6 = dpf.CreateParameter();
param6.DbType = DbType.String;
param6.Value = id1Desde;
param6.ParameterName = "ID1_DESDE";
paramLotesConsol.Add(param6);
DbParameter param7 = dpf.CreateParameter();
param7.DbType = DbType.String;
param7.Value = id1Hasta;
param7.ParameterName = "ID1_HASTA";
paramLotesConsol.Add(param7);
DbParameter param8 = dpf.CreateParameter();
param8.DbType = DbType.String;
param8.Value = id2Desde;
param8.ParameterName = "ID2_DESDE";
paramLotesConsol.Add(param8);
DbParameter param9 = dpf.CreateParameter();
param9.DbType = DbType.String;
param9.Value = id2Hasta;
param9.ParameterName = "ID2_HASTA";
paramLotesConsol.Add(param9);
........
DbParameter param26 = dpf.CreateParameter();
param26.DbType = DbType.String;
param26.Value = altaPor;
param26.ParameterName = "ALTA_POR";
paramLotesConsol.Add(param26);
DbParameter param27 = dpf.CreateParameter();
param27.DbType = DbType.String;
param27.Value = lotEstado;
param27.ParameterName = "ESTADO";
paramLotesConsol.Add(param27);
DbParameter param28 = dpf.CreateParameter();
param28.DbType = DbType.Date;
param28.Value = fecEmiLot;
param28.ParameterName = "FECHA_EMISION_LOTE";
paramLotesConsol.Add(param28);
DbParameter param29 = dpf.CreateParameter();
param29.DbType = DbType.Date;
param29.Value = fecCadLot;
param29.ParameterName = "FECHA_CADUCID_LOTE";
paramLotesConsol.Add(param29);
return ejecutaNonQuery("LOTES_CREAR_CONSOLIDADO", paramLotesConsol);
}
那我这样称呼它:
Caja_Contenido_BL loteBL = new Caja_Contenido_BL();
我必须将来自 gridview 的数据插入到我的数据库中,因此我在每一行上运行用于插入数据的存储过程。
我得到的错误是:
SqlParameter 已被另一个 SqlParameterCollection 包含
代码:
protected void Lotes_Crear_Consolidado(object sender, EventArgs e)
{
string altaPor = User.Identity.Name.ToString().ToUpper();
foreach (GridViewRow grdCajUpd_Row in this.gvwLotConsol_Plant.Rows)
{
string cliCod = Convert.ToString(grdCajUpd_Row.Cells[0].Text);
string cajCod = Convert.ToString(grdCajUpd_Row.Cells[1].Text);
int cajNum = Convert.ToInt16(grdCajUpd_Row.Cells[2].Text);
int cajConNum = Convert.ToInt16(grdCajUpd_Row.Cells[3].Text);
string cajConCod = Convert.ToString(grdCajUpd_Row.Cells[4].Text);
string id1Desde = Convert.ToString(grdCajUpd_Row.Cells[5].Text);
string id1Hasta = Convert.ToString(grdCajUpd_Row.Cells[6].Text);
string id2Desde = Convert.ToString(grdCajUpd_Row.Cells[7].Text);
string id2Hasta = Convert.ToString(grdCajUpd_Row.Cells[8].Text);
string id3Desde = Convert.ToString(grdCajUpd_Row.Cells[9].Text);
string id3Hasta = Convert.ToString(grdCajUpd_Row.Cells[10].Text);
string id4Desde = Convert.ToString(grdCajUpd_Row.Cells[11].Text);
string id4Hasta = Convert.ToString(grdCajUpd_Row.Cells[12].Text);
string id5Desde = Convert.ToString(grdCajUpd_Row.Cells[13].Text);
string id5Hasta = Convert.ToString(grdCajUpd_Row.Cells[14].Text);
string id6Desde = Convert.ToString(grdCajUpd_Row.Cells[15].Text);
string id6Hasta = Convert.ToString(grdCajUpd_Row.Cells[16].Text);
string id7Desde = Convert.ToString(grdCajUpd_Row.Cells[17].Text);
string id7Hasta = Convert.ToString(grdCajUpd_Row.Cells[18].Text);
string id8Desde = Convert.ToString(grdCajUpd_Row.Cells[19].Text);
string id8Hasta = Convert.ToString(grdCajUpd_Row.Cells[20].Text);
string id9Desde = Convert.ToString(grdCajUpd_Row.Cells[21].Text);
string id9Hasta = Convert.ToString(grdCajUpd_Row.Cells[22].Text);
string id10Desde = Convert.ToString(grdCajUpd_Row.Cells[23].Text);
string id10Hasta = Convert.ToString(grdCajUpd_Row.Cells[24].Text);
string estado = Convert.ToString(grdCajUpd_Row.Cells[25].Text);
DateTime fecEmiLot = Convert.ToDateTime(grdCajUpd_Row.Cells[26].Text);
DateTime fecCadLot = Convert.ToDateTime(grdCajUpd_Row.Cells[27].Text);
loteBL.Lotes_Crear_Consolidado(cliCod, cajCod, cajNum, cajConNum, cajConCod,
id1Desde, id1Hasta, id2Desde, id2Hasta, id3Desde, id3Hasta, id4Desde, id4Hasta,
id5Desde, id5Hasta, id6Desde, id6Hasta, id7Desde, id7Hasta, id8Desde, id8Hasta,
id9Desde, id9Hasta, id10Desde, id10Hasta, altaPor, estado, fecEmiLot, fecCadLot);
}
Page.ClientScript.RegisterStartupScript(this.GetType(), "AlertScript", "alert('Lote(s) Creado(s)!');", true);
}
我用cmd.Parameters.Clear()清除命令参数。
在 SQL Server 中,我在其他存储过程的 SQL 参数中使用相同的名称。 不知道是什么问题。
如果有人可以帮助我,我将不胜感激
最好的问候
【问题讨论】:
-
异常发生在哪一行?我的第一个想法是使用所有名为
paramXX的变量,您要添加两次。 -
Parameters.Clear()在哪里?我通常会在执行命令后立即执行,然后将命令本身处理掉。 -
旁注:1)如果您不处理异常(您所做的只是重新抛出)并且 finally 是空的,那么将 try/catch/finally 一起删除,它只会给您的代码和潜在的错误。 2) 前一点的例子,并且永远不会通过传入异常来重新抛出异常,即:
throw ex;应该读为throw;。前者重置调用堆栈,使以后的故障排除变得更加困难,后者保留调用堆栈。 -
其他注释 -- 1) 当
TableCell.Text本身返回string时,为什么需要调用Convert.ToString? 2) 我强烈建议创建一个元数据类,它包含目标类型、数据库类型,也许还有一个名称(仅用于调试目的)。然后,实例化并填充这些类的List。最后,您可以使用该列表来构建一系列 DB 参数实例,您可以依次将其添加到存储过程中。
标签: c# asp.net sql-server