Insertar SQL en bucle while

Estoy tratando de usar un bucle while para recorrer algunos datos y luego agregar cada uno a sql. Este es el código que he hecho hasta ahora:

        SqlCommand cmd = new SqlCommand();
        cmd.Connection = SqlConn;
        while (dr.Read())
            {
                cmd.CommandText = "insert into CPC_Coupons(PortalID, CreatedByUser, CouponCode, ProductID, ExpiresOn, Quantity, Title, FirstName, LastName, Company, Address1, City, Region, Zip, Country, WorkPhone, Email, Campaign, Source, Market, Notes) values(@PortalID, @CreatedByUser, @Coupon, @ProductID, @ExpiresOn, @Quantity, @Title, @FirstName, @LastName, @Company, @Address1, @City, @Region, @Zip, @Country, @WorkPhone, @Email, @Campaign, @Source, @Market, @Notes)";
                cmd.Parameters.Add("@PortalID", SqlDbType.NVarChar).Value = 0;
                cmd.Parameters.Add("@Coupon", SqlDbType.NVarChar).Value = dr[0].ToString();
                cmd.Parameters.Add("@CreatedByUser", SqlDbType.NVarChar).Value = "3517";
                cmd.Parameters.Add("@ProductID", SqlDbType.NVarChar).Value = "0";
                cmd.Parameters.Add("@ExpiresOn", SqlDbType.NVarChar).Value = "01/01/2013";
                cmd.Parameters.Add("@Quantity", SqlDbType.NVarChar).Value = "100";
                cmd.Parameters.Add("@Title", SqlDbType.NVarChar).Value = "Mr.";
                cmd.Parameters.Add("@FirstName", SqlDbType.NVarChar).Value = dr[3].ToString();
                cmd.Parameters.Add("@LastName", SqlDbType.NVarChar).Value = dr[4].ToString();
                cmd.Parameters.Add("@Company", SqlDbType.NVarChar).Value = dr[2].ToString();
                cmd.Parameters.Add("@Address1", SqlDbType.NVarChar).Value = dr[5].ToString();
                cmd.Parameters.Add("@City", SqlDbType.NVarChar).Value = dr[6].ToString();
                cmd.Parameters.Add("@Region", SqlDbType.NVarChar).Value = dr[7].ToString();
                cmd.Parameters.Add("@Zip", SqlDbType.NVarChar).Value = dr[8].ToString();
                cmd.Parameters.Add("@Country", SqlDbType.NVarChar).Value = dr[9].ToString();
                cmd.Parameters.Add("@WorkPhone", SqlDbType.NVarChar).Value = dr[10].ToString();
                cmd.Parameters.Add("@Email", SqlDbType.NVarChar).Value = dr[11].ToString();
                cmd.Parameters.Add("@Campaign", SqlDbType.NVarChar).Value = txtCampaign.Text;
                cmd.Parameters.Add("@Source", SqlDbType.NVarChar).Value = dr[12].ToString();
                cmd.Parameters.Add("@Market", SqlDbType.NVarChar).Value = txtMarketSegment.Text;
                cmd.Parameters.Add("@Notes", SqlDbType.NVarChar).Value = txtNotesToSales.Text;
                cmd.CommandType = CommandType.Text;
                SqlConn.Open();
                cmd.ExecuteNonQuery();
                SqlConn.Close();

            }

Pero uno al segundo pasa a través de él llega a la cmd.ExecuteNonQuery(); y da este error: The variable name '@PortalID' has already been declared. Variable names must be unique within a query batch or stored procedure.

¿Alguna idea de lo que estoy haciendo mal?

¡Gracias!

preguntado el 01 de febrero de 12 a las 14:02

5 Respuestas

La creación de una instancia de un nuevo SQLCommand dentro del bucle probablemente solucionaría su problema. Al igual que:

    while (dr.Read())
    {
            SqlCommand cmd = new SqlCommand();
            cmd.Connection = SqlConn;
            cmd.CommandText = "insert into CPC_Coupons(PortalID, CreatedByUser, CouponCode, ProductID, ExpiresOn, Quantity, Title, FirstName, LastName, Company, Address1, City, Region, Zip, Country, WorkPhone, Email, Campaign, Source, Market, Notes) values(@PortalID, @CreatedByUser, @Coupon, @ProductID, @ExpiresOn, @Quantity, @Title, @FirstName, @LastName, @Company, @Address1, @City, @Region, @Zip, @Country, @WorkPhone, @Email, @Campaign, @Source, @Market, @Notes)";
            cmd.Parameters.Add("@PortalID", SqlDbType.NVarChar).Value = 0;
            cmd.Parameters.Add("@Coupon", SqlDbType.NVarChar).Value = dr[0].ToString();
            cmd.Parameters.Add("@CreatedByUser", SqlDbType.NVarChar).Value = "3517";
            cmd.Parameters.Add("@ProductID", SqlDbType.NVarChar).Value = "0";
            cmd.Parameters.Add("@ExpiresOn", SqlDbType.NVarChar).Value = "01/01/2013";
            cmd.Parameters.Add("@Quantity", SqlDbType.NVarChar).Value = "100";
            cmd.Parameters.Add("@Title", SqlDbType.NVarChar).Value = "Mr.";
            cmd.Parameters.Add("@FirstName", SqlDbType.NVarChar).Value = dr[3].ToString();
            cmd.Parameters.Add("@LastName", SqlDbType.NVarChar).Value = dr[4].ToString();
            cmd.Parameters.Add("@Company", SqlDbType.NVarChar).Value = dr[2].ToString();
            cmd.Parameters.Add("@Address1", SqlDbType.NVarChar).Value = dr[5].ToString();
            cmd.Parameters.Add("@City", SqlDbType.NVarChar).Value = dr[6].ToString();
            cmd.Parameters.Add("@Region", SqlDbType.NVarChar).Value = dr[7].ToString();
            cmd.Parameters.Add("@Zip", SqlDbType.NVarChar).Value = dr[8].ToString();
            cmd.Parameters.Add("@Country", SqlDbType.NVarChar).Value = dr[9].ToString();
            cmd.Parameters.Add("@WorkPhone", SqlDbType.NVarChar).Value = dr[10].ToString();
            cmd.Parameters.Add("@Email", SqlDbType.NVarChar).Value = dr[11].ToString();
            cmd.Parameters.Add("@Campaign", SqlDbType.NVarChar).Value = txtCampaign.Text;
            cmd.Parameters.Add("@Source", SqlDbType.NVarChar).Value = dr[12].ToString();
            cmd.Parameters.Add("@Market", SqlDbType.NVarChar).Value = txtMarketSegment.Text;
            cmd.Parameters.Add("@Notes", SqlDbType.NVarChar).Value = txtNotesToSales.Text;
            cmd.CommandType = CommandType.Text;
            SqlConn.Open();
            cmd.ExecuteNonQuery();
            SqlConn.Close();

        }

Pero, ¿estás seguro de que quieres hacer esto? ¿Por qué no inserta todos sus datos de una vez? -Por ejemplo, vea las respuestas de Yucks.

Respondido 01 Feb 12, 18:02

Debe crear estos parámetros fuera del ciclo con valores predeterminados y, durante cada iteración, acceder a ellos y establecer su nuevo parámetros argumentos

Resumen: no los agregue para cada iteración, ¡acceda a ellos!

EDIT:

Para ser más concreto, verifique esta entrada de MSDN:

Respondido 01 Feb 12, 18:02

cmd tiene un alcance fuera de tu while bucles, por lo que todo lo que establezca (es decir, los parámetros) persiste entre iteraciones.

Cámbielo a esto para que funcione:

while (dr.Read())
{
    SqlCommand cmd = new SqlCommand();
    cmd.Connection = SqlConn;
    // ... rest as before
}

Estarías mejor llenando un DataSet y luego recorrer eso, o acumular sus resultados para ser enviados una vez a un procedimiento almacenado. Para cualquier conjunto de resultados grande, esto será muy ineficiente.

Respondido 01 Feb 12, 23:02

lo siento, mi error, probablemente no te dio tiempo suficiente para editar tu respuesta. por favor, vuelva a editarlo para que pueda volver a votar. - Shai

A medida que reutiliza el objeto de comando, agregará otro conjunto de parámetros en la segunda iteración.

Agregue los parámetros fuera del bucle y establezca los valores que cambian dentro del bucle.

Además, debe abrir la conexión de la base de datos antes del bucle y cerrarla después.

Respondido 01 Feb 12, 18:02

No es necesario abrir y cerrar la conexión cada vez.

No es necesario que cree un nuevo SqlCommand cada vez.

SqlCommand cmd = new SqlCommand();
cmd.Connection = SqlConn;
cmd.CommandText = "insert into CPC_Coupons(PortalID, CreatedByUser, CouponCode, ProductID, ExpiresOn, Quantity, Title, FirstName, LastName, Company, Address1, City, Region, Zip, Country, WorkPhone, Email, Campaign, Source, Market, Notes) values(@PortalID, @CreatedByUser, @Coupon, @ProductID, @ExpiresOn, @Quantity, @Title, @FirstName, @LastName, @Company, @Address1, @City, @Region, @Zip, @Country, @WorkPhone, @Email, @Campaign, @Source, @Market, @Notes)";
cmd.CommandType = CommandType.Text;
SqlConn.Open();

while (dr.Read())
{
    cmd.Parameters.Clear()

    cmd.Parameters.Add("@PortalID", SqlDbType.NVarChar).Value = 0;

    ''' other parameters here

    cmd.ExecuteNonQuery();
}

SqlConn.Close();

Respondido 01 Feb 12, 23:02

Realmente no importa si lo haces o no. Agrupar la conexión está bien. - visc

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.