sql >> Database >  >> RDS >> Mysql

Dynamische kolomnaam met behulp van voorbereide instructie + sql-query met variabele die 's . bevat

Rechts. We kunnen geen id's leveren als bindparameters. De naam van de kolom moet onderdeel zijn van de SQL-tekst.

We kunnen de naam van de kolom dynamisch opnemen in de SQL-tekst met zoiets als dit:

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

En geef waarden op voor de twee resterende bindparameters

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

En je hebt helemaal gelijk dat je je zorgen maakt over SQL-injectie.

Geleverd als bindwaarden, enkele aanhalingstekens in de waarden van attrData en medname zal geen probleem zijn, in termen van SQL-injectie.

Maar het voorbeeld dat ik heb gegeven is kwetsbaar door het opnemen van de colname variabele in de SQL-tekst, als we geen garantie hebben dat colname is "veilig" om in de verklaring op te nemen.

We moeten dus een waarde toekennen aan colname "veilig".

Verschillende benaderingen die we kunnen gebruiken, doen dat. Het veiligst zou een "witte lijst"-benadering zijn. De code kan ervoor zorgen dat alleen specifieke toegestane "veilige" waarden worden toegewezen aan colname , voor colname wordt opgenomen in de SQL-tekst.

Als een eenvoudig voorbeeld:

  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 
  }

Een flexibelere benadering is ervoor te zorgen dat er geen backtick-teken verschijnt in colname . In het voorbeeld is de waarde van colname wordt ontsnapt door het in te sluiten in backticks. Dus zolang er geen backtick-teken verschijnt in colname , zullen we voorkomen dat een opgegeven waarde wordt geïnterpreteerd als iets anders dan als een identifier.

Voor een meer generieke (en gecompliceerde) benadering van het gebruik van hardgecodeerde backtick-tekens, kunnen we overwegen om de supportsQuotedIdentifiers te gebruiken en getIdentifierQuoteString methoden van java.sql.DatabaseMetaData klas.

(In de OP-code zien we niet het datatype van de inhoud van attributes . We zien een aanroep van een methode met de naam replace , en de argumenten die daarbij aangevoerd worden. Ervan uitgaande dat attributes is een String, en dat zou een kolomnaam moeten zijn, het is helemaal niet duidelijk waarom we "spatie met enkele aanhalingstekens" in de string zouden hebben, of waarom we dat moeten verwijderen. Afgezien van deze vermelding, gaat dit antwoord daar niet op in.)




  1. Hoe maak je een SQL-weergave met SQLAlchemy?

  2. MySQL-limiet met variabele

  3. een MySql-waarschuwing vangen

  4. MySQL-groepering van resultaten per tijdsperiode