sql >> Databasteknik >  >> RDS >> Sqlserver

Parametrisera en SQL IN-sats

Du kan parametrisera var och en värde, så något som:

string[] tags = new string[] { "ruby", "rails", "scruffy", "rubyonrails" };
string cmdText = "SELECT * FROM Tags WHERE Name IN ({0})";

string[] paramNames = tags.Select(
    (s, i) => "@tag" + i.ToString()
).ToArray();

string inClause = string.Join(", ", paramNames);
using (SqlCommand cmd = new SqlCommand(string.Format(cmdText, inClause))) {
    for(int i = 0; i < paramNames.Length; i++) {
       cmd.Parameters.AddWithValue(paramNames[i], tags[i]);
    }
}

Vilket ger dig:

cmd.CommandText = "SELECT * FROM Tags WHERE Name IN (@tag0, @tag1, @tag2, @tag3)"
cmd.Parameters["@tag0"] = "ruby"
cmd.Parameters["@tag1"] = "rails"
cmd.Parameters["@tag2"] = "scruffy"
cmd.Parameters["@tag3"] = "rubyonrails"

Nej, detta är inte öppet för SQL-injektion. Den enda injicerade texten i CommandText är inte baserad på användarinmatning. Den är enbart baserad på det hårdkodade prefixet "@tagg" och indexet för en array. Indexet kommer alltid vara ett heltal, är inte användargenererat och är säkert.

De användarinmatade värdena är fortfarande instoppade i parametrar, så det finns ingen sårbarhet där.

Redigera:

Bortsett från injiceringsproblem, var noga med att notera att konstruktion av kommandotexten för att ta emot ett varierande antal parametrar (enligt ovan) hindrar SQL-serverns förmåga att dra fördel av cachade frågor. Nettoresultatet är att du nästan säkert förlorar värdet av att använda parametrar i första hand (i motsats till att bara infoga predikatsträngarna i själva SQL).

Inte för att cachade frågeplaner inte är värdefulla, men IMO är den här frågan inte tillnärmelsevis komplicerad nog för att se mycket nytta av den. Även om kompileringskostnaderna kan närma sig (eller till och med överstiga) exekveringskostnaderna, pratar du fortfarande millisekunder.

Om du har tillräckligt med RAM-minne skulle jag förvänta mig att SQL Server förmodligen också skulle cachelagra en plan för de vanliga räkningarna av parametrar. Jag antar att du alltid kan lägga till fem parametrar och låta de ospecificerade taggarna vara NULL - frågeplanen bör vara densamma, men det verkar ganska fult för mig och jag är inte säker på att det skulle vara värt mikrooptimeringen (även om, på Stack Overflow – det kan mycket väl vara värt det).

Dessutom kommer SQL Server 7 och senare att automatiskt parametrisera frågor, så att använda parametrar är egentligen inte nödvändigt ur prestandasynpunkt – det är dock kritiskt ur säkerhetssynpunkt - speciellt med användarinmatade data som denna.



  1. Problem med infogningsfråga i Sqlite?( variabel infoga)

  2. Hur man duplicerar en databas med phpMyAdmin

  3. Använda INSERT INTO från SQL Server för att ändra Salesforce-data

  4. Hur kan jag ansluta flera SQL-tabeller med ID:n?