parametros ejemplos con c# .net mysql mysql-connector mysql-parameter

c# - ejemplos - sqldataadapter parameters



Añadir lista<int> a un parámetro mysql (8)

Tengo esta pregunta sobre el MySqlParameter del conector .NET.

Tengo esta consulta:

SELECT * FROM table WHERE id IN (@parameter)

Y el parámetro de MySql es:

intArray = new List<int>(){1,2,3,4}; ...connection.Command.Parameters.AddWithValue("parameter", intArray);

¿Esto es posible? ¿Es posible pasar una matriz de int a un único MySqlParameter? La otra solución será convertir la matriz de int en una cadena como "1,2,3,4", pero esto, cuando la paso al MySqlParameter y esto se reconoce como una cadena, se coloca en la consulta SQL como "1 /, 2 /, 3 /, 4" y esto no devuelve los valores esperados.

@ ACTUALIZACIÓN: Parece que el equipo del conector mysql debería trabajar un poco más.


cuando lo paso a MySqlParameter y esto se reconoce como una cadena, coloca en la consulta sql como "1 /, 2 /, 3 /, 4" y esto no devuelve los valores esperados.

Me encontré con esto anoche Encontré que FIND_IN_SET funciona aquí:

SELECT * FROM table WHERE FIND_IN_SET(id, @parameter) != 0 ... intArray = new List<int>(){1,2,3,4}; conn.Command.Parameters.AddWithValue("parameter", string.Join(",", intArray));

Aparentemente esto tiene algunas limitaciones de longitud (encontré tu publicación buscando una solución alternativa), pero esto puede funcionar para ti.


Answer from Mud solo funciona para la primera int en la lista de parámetros. Esto significa que ''2,1,3,4'' no funcionará si id es 1 por ejemplo.

Ver FIND_IN_SET () vs IN () .

No hay comentarios posibles por ahora, pero también vea la respuesta de Matt Ellen. Editaría su respuesta pero no podría. INSTR no parece funcionar en un caso DONDE con más de un ID (devuelve solo en el resultado).

Pero reemplazar INSTR con LOCATE hace que su solución funcione (con String.Join(",", intArray) como parámetro agregado) ... VOTAR DE ARRIBA desde mí:

LOCATE(CONCAT('','' , CAST(id AS CHAR) , '','') , CONCAT('','' , CAST(@paramter AS CHAR) , '','')) <> 0


Como sé, no puede proporcionar ninguna matriz como parámetro a la declaración preparada. IN () no admite parámetros como una matriz.


Esto no funciona bien para listas grandes, pero es lo único que he encontrado que funciona si tiene que pasar una lista como parámetro.

En lugar de

SELECT * FROM table WHERE id IN (@parameter)

Tienes que hacer esto:

SELECT * FROM table WHERE INSTR('',''+@parameter+'','', '',''+CAST(the_column AS CHAR) + '','')

Luego puedes pasar tu lista con string.Join(",", intArray)

Es un kludge, pero funciona.


Los parámetros no funcionan con IN. Siempre he incrustado cosas como una cadena en la consulta. Si bien esto generalmente se considera una forma incorrecta debido a la inyección de SQL, si está construyendo la consulta a partir de una lista numérica de tipo fuerte, entonces no debería haber ninguna posibilidad de que una entrada externa la corrompa de manera significativa.


No creo que haya una manera de agregarlos de esa manera, pero quizás podría recorrer la lista y generar la consulta de forma dinámica.

Por ejemplo:

var intArray = new List<int>(){1,2,3,4}; if (intArray.Count > 0) { var query = "SELECT * FROM table WHERE id IN ("; for (int i = 0; i < intArray.Count; i++) { //Append the parameter to the query //Note: I''m not sure if mysql uses "@" but you can replace this if needed query += "@num" + i + ","; //Add the value to the parameters collection ...connection.Command.Parameters.AddWithValue("num" + i, intArray[i]); } //Remove the last comma and add the closing bracket query = query.Substring(0, query.Length - 1) + ");"; //Execute the query here }

De esta manera, incluso podría usar una lista tipificada de manera diferente y aun así obtener los beneficios de las consultas parametrizadas. Sin embargo, no sé si habría problemas de rendimiento con listas más grandes, pero sospecho que ese sería el caso.


Tienes algunas opciones aquí (en orden de preferencia):

  1. Utilice una base de datos que admita parámetros con valores de tabla . Esta es la única forma de obtener la sintaxis exacta que desea.
  2. Los datos deben provenir de algún lugar: su base de datos, la acción del usuario o la fuente generada por la máquina.

    • Si los datos ya están en su base de datos, use una subconsulta en su lugar.
    • Para otros datos generados por la máquina, use BULK INSERT, SqlBulkCopy o las herramientas de importación masivas preferidas de su base de datos.
    • Si es creado por el usuario, agréguelo a una tabla separada en cada acción de usuario individual y luego use una consulta secundaria.

      Un ejemplo de esto es un carrito de compras. Un usuario puede seleccionar varios artículos para comprar. En lugar de mantenerlos en la aplicación y necesita agregar todos los artículos a un pedido de una sola vez cuando se retiran, agregue cada artículo a una tabla en la base de datos cuando el usuario lo seleccione o lo cambie.

  3. Tenga una función definida por el usuario de SQL que desempaqueta un parámetro de cadena en una tabla y devuelve esa tabla como un conjunto que puede usar con una expresión IN (). Vea el artículo vinculado a continuación para obtener información más detallada sobre cómo funciona esto.
  4. Cree una lista de cadenas o una lista de parámetros dinámicamente en el cliente (como se muestra en otras respuestas). Tenga en cuenta que esta es mi opción menos preferida.

El trabajo definitivo (y me refiero a definitivo ) sobre el tema está aquí:

http://www.sommarskog.se/arrays-in-sql.html

El artículo largo, pero de buena manera. El autor es un experto en servidores SQL, pero los conceptos en general se aplican también a MySQL.


vas a tener que iterar sobre tu matriz y crear la lista tú mismo

// no parameters var sb = new StringBuilder(); for(int i=0;i<intArray.Length;i++) { sb.Append(intArray[i] + ",");// no SQL injection they are numbers } if (sb.Length>0) {sb.Length-=1;} string sql = "SELECT * FROM table WHERE id IN (" + sb.ToString() + ")";

ACTUALIZACIÓN: Habiendo pensado más sobre esto, volveré a mi respuesta original (a continuación) que es usar parámetros. Las optimizaciones de las consultas integradas y de lo que pueda reunir el motor de la base de datos depende de usted.

// no parameters var sb = new StringBuilder(); for(int i=0;i<intArray.Length;i++) { sb.AppendFormat("p{0},", i);// no SQL injection they are numbers connection.Command.Parameters.AddWithValue("p"+i, intArray[i]); } if (sb.Length>0) {sb.Length-=1;} string sql = "SELECT * FROM table WHERE id IN (" + sb.ToString() + ")";