2010-12-21 14 views
15

Parece que estoy confundido sobre cómo realizar una declaración In con un SqlParameter. Hasta ahora tengo el siguiente código:¿Cómo traduzco una Lista <string> en un SqlParameter para una instrucción Sql In?

cmd.CommandText = "Select dscr from system_settings where setting in @settings"; 
cmd.Connection = conn; 
cmd.Parameters.Add(new SqlParameter("@settings", settingList)); 

reader = cmd.ExecuteReader(); 

settingsList es una List<string>. Cuando se llama al cmd.ExecuteReader(), obtengo un ArgumentException debido a que no puedo asignar un List<string> a "un tipo de proveedor conocido".

¿Cómo realizo (con seguridad) una consulta In con SqlCommand s?

+1

¿A qué tipo * SQL espera su lista convertida? No hay matrices ... –

+0

Necesito que la lista sea una lista de cadenas sql, por ejemplo 'donde se establece ('configuración1', 'configuración2')' – KallDrexx

+2

@KallDrexx, eso no tiene sentido. No hay tal tipo de datos en SQL. Lo mejor que puede hacer es modificar su "Texto de comando" para construir el SQL deseado usted mismo (incrustando los valores de los parámetros dentro del SQL). No puede ser encapsulado en un 'SqlParameter'. –

Respuesta

21

usted podría intentar algo como esto:

string sql = "SELECT dscr FROM system_settings WHERE setting IN ({0})"; 
string[] paramArray = settingList.Select((x, i) => "@settings" + i).ToArray(); 
cmd.CommandText = string.Format(sql, string.Join(",", paramArray)); 

for (int i = 0; i < settingList.Count; ++i) 
{ 
    cmd.Parameters.Add(new SqlParameter("@settings" + i, settingList[i])); 
} 
+0

Como no es posible hacer lo que yo quería, usó este método Me encanta linq! – KallDrexx

+3

Esto funciona hasta que settingList.Count = 0, luego obtendrá un error en SQL porque DONDE establecer IN() es una sintaxis no válida. El parámetro de valor de tabla es más correcto, vea la respuesta de rizzle. – Dude0001

8

Parece que está tratando de pasar un parámetro de varios valores, que la sintaxis SQL no va a hacer lo que usted espera. Es posible que desee pasar un parámetro de valor de tabla.

Lea esto: http://www.sommarskog.se/arrays-in-sql.html#iter-list-of-strings

específicamente: http://www.sommarskog.se/arrays-in-sql-2008.html#ListSqlDataRecord

private static void datatable_example() { 

    string [] custids = {"ALFKI", "BONAP", "CACTU", "FRANK"}; 

    DataTable custid_list = new DataTable(); 
    custid_list.Columns.Add("custid", typeof(String)); 

    foreach (string custid in custids) { 
     DataRow dr = custid_list.NewRow(); 
     dr["custid"] = custid; 
     custid_list.Rows.Add(dr); 
    } 

    using(SqlConnection cn = setup_connection()) { 
     using(SqlCommand cmd = cn.CreateCommand()) { 

     cmd.CommandText = 
      @"SELECT C.CustomerID, C.CompanyName 
      FROM Northwind.dbo.Customers C 
      WHERE C.CustomerID IN (SELECT id.custid FROM @custids id)"; 
     cmd.CommandType = CommandType.Text; 

     cmd.Parameters.Add("@custids", SqlDbType.Structured); 
     cmd.Parameters["@custids"].Direction = ParameterDirection.Input; 
     cmd.Parameters["@custids"].TypeName = "custid_list_tbltype"; 
     cmd.Parameters["@custids"].Value = custid_list; 

     using (SqlDataAdapter da = new SqlDataAdapter(cmd)) 
     using (DataSet  ds = new DataSet()) { 
      da.Fill(ds); 
      PrintDataSet(ds); 
     } 
     } 
    } 
} 
0

alguna vez usar mi propia función para crear parámetros como este:

public void SomeDataFunction() {  
    ArrayList params = GetParameters(someEntity); 
    CommandObject.Parameters.AddRange(parameters.ToArray()); 
} 

public static ArrayList GetParameters(ISomeEntity entity) { 
    ArrayList result = new ArrayList {     
      OleDbUtility.NewDbParam("@Param1", OleDbType.Integer, , entity.Parameter1), 
      OleDbUtility.NewDbParam("@Param2", OleDbType.VarChar, 9, entity.Parameter2), 
     } 
} 

public static OleDbParameter NewDbParam(string parameterName, OleDbType dataType, 
        int size, object value) { 
    OleDbParameter result = new OleDbParameter(parameterName, dataType, size, string.Empty); 
    result.Value = value; 
    return result; 
} 
0

Si está utilizando Servidor SQL 2008 o más adelante, puede hacer uso de parámetros con valores de tabla: esto le permite pasar una tabla de valores como parámetro. Desde .net define un tipo SqlParameter de tipo "estructurado" y establece el valor en algo que implementa IEnumerable.

Véase la referencia de MSDN completa con ejemplos aquí: http://msdn.microsoft.com/en-us/library/bb675163.aspx

-2

acostumbro a pasar en la lista como una cadena separada por comas, y luego utilizar una función con valores de tabla a 'dividir' la cadena en una mesa que puede entonces utilizar para unirse a en otra consulta.

DECLARE @Settings TABLE (Sid INT) 
INSERT INTO @Settings(Sid) 
SELECT CAST(Items AS INT) FROM dbo.Split(@SettingsParameter, ',') 

A menos que, por supuesto, esté utilizando SQL Server 2008, entonces utilizaría los parámetros de la tabla valorada.

-1

Utilice XML, es bastante rápido para este escenario. Convertiría su lista en XML y simplemente pasaría una cadena:

CREATE TABLE #myTempTable 
( Letter VARCHAR(20)) 

INSERT INTO #myTempTable (Letter) VALUES ('A'), ('B') 

Declare @xml XML = '<a>A</a><a>B</a><a>C</a>' 

Select * from #myTempTable 
Where Letter in 
(Select p.value('.', 'VARCHAR(40)') AS [Letter] from @xml.nodes('//a') as t(p)) 

DROP TABLE #myTempTable 
+0

no ha especificado cómo convertir la lista a xml. –

Cuestiones relacionadas