sql >> Databasteknik >  >> RDS >> Mysql

Dynamiskt kolumnnamn med förberedd sats + sql-fråga med variabel som innehåller 's

Rätt. Vi kan inte tillhandahålla identifierare som bindningsparametrar. Namnet på kolumnen måste vara en del av SQL-texten.

Vi kan dynamiskt infoga namnet på kolumnen i SQL-texten med något så här:

  sql = "UPDATE diseaseinfo"
      + " SET `" + colname + "` = ?"
      + " WHERE companyname = 'mycom' AND diseaseName = ?";

Och tillhandahålla värden för de två återstående bindningsparametrarna

  preparedStmt.setString(1, attrData);
  preparedStmt.setString(2, medname);

Och du har helt rätt när det gäller att vara orolig för SQL Injection.

Levereras som bindningsvärden, enkla citattecken i värdena för attrData och medname kommer inte att vara ett problem när det gäller SQL Injection.

Men exemplet jag har gett är sårbara genom att införliva colname variabel i SQL-texten, om vi inte har något garanterat det colname är "säkert" att inkludera i uttalandet.

Så vi måste göra tilldelningen av ett värde till colname "säkert".

Flera metoder vi kan använda gör det. Det säkraste skulle vara en "vitlista". Koden kan säkerställa att endast specifika tillåtna "säkra" värden tilldelas colname , före colname inkluderas i SQL-texten.

Som ett enkelt exempel:

  String colname;
  if (attributes.equals("someexpectedvalue") {
      colname = "columnname_to_be_used";
  } else if (attributes.equals("someothervalid") {
      colname = "valid_columname";
  } else {
     // unexpected/unsupported attributes value so
     // handle condition or throw an exception 
  }

En mer flexibel metod är att se till att ett backtick-tecken inte visas i colname . I exemplet, värdet på colname håller på att rymmas genom att omsluta den i backticks. Så länge som ett backtick-tecken inte visas i colname , kommer vi att förhindra att ett tillhandahållet värde tolkas som något annat än som en identifierare.

För ett mer allmänt (och komplicerat) tillvägagångssätt för att använda hårdkodade backtick-tecken kan vi överväga att använda supportsQuotedIdentifiers och getIdentifierQuoteString metoder för java.sql.DatabaseMetaData klass.

(I OP-koden ser vi inte datatypen för innehållet i attributes . Vi ser ett anrop till en metod som heter replace , och de argument som tillhandahålls för det. Förutsatt att attributes är en sträng, och det är tänkt att vara ett kolumnnamn, det är inte alls klart varför vi skulle ha "mellanslag enstaka citattecken" i strängen, eller varför vi behöver ta bort det. Förutom detta omnämnande tar det här svaret inte upp det.)




  1. var är den faktiska datan i en mysql db lagrad på en linux-maskin?

  2. Google App Engine och Cloud SQL:Förlorade anslutningen till MySQL-servern vid "läsning av initialt kommunikationspaket"

  3. MySQL - Gör ett par värden unika

  4. Det gick inte att hitta en giltig datakatalog. MySQL generisk binär installation