sql >> Databáze >  >> RDS >> Mysql

Dynamický název sloupce pomocí připraveného příkazu + SQL dotaz s proměnnou obsahující 's

Že jo. Nemůžeme zadat identifikátory jako parametry vazby. Název sloupce musí být součástí textu SQL.

Název sloupce můžeme dynamicky začlenit do textu SQL něčím takovým:

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

A zadejte hodnoty pro dva zbývající parametry vazby

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

A máte naprostou pravdu, že vás znepokojuje SQL Injection.

Dodáváno jako hodnoty vazby, jednoduché uvozovky v hodnotách attrData a medname nebude problém, pokud jde o SQL Injection.

Ale příklad, který jsem uvedl, je zranitelný díky začlenění colname proměnnou do SQL textu, pokud nemáme nějaký zaručený ten colname je „bezpečné“ zahrnout do prohlášení.

Potřebujeme tedy přiřadit hodnotu colname "bezpečné".

K tomu můžeme použít několik přístupů. Nejbezpečnější by byl přístup „bílé listiny“. Kód může zajistit, že do colname budou přiřazeny pouze konkrétní povolené "bezpečné" hodnoty , před colname se zahrne do textu SQL.

Jako jednoduchý příklad:

  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 
  }

Flexibilnějším přístupem je zajistit, aby se v colname neobjevil znak backtick . V příkladu je to hodnota colname je unikán tím, že jej uzavřete do zadních značek. Pokud se tedy v colname neobjeví znak backtick , zabráníme tomu, aby dodaná hodnota byla interpretována jako něco jiného než jako identifikátor.

Pro obecnější (a komplikovanější) přístup k používání napevno zakódovaných zpětných znaků bychom mohli zvážit použití supportsQuotedIdentifiers a getIdentifierQuoteString metody java.sql.DatabaseMetaData třída.

(V kódu OP nevidíme datový typ obsahu attributes . Vidíme volání metody s názvem replace a argumenty, které jsou k tomu dodány. Za předpokladu, že attributes je String, a to má být název sloupce, není vůbec jasné, proč bychom měli v řetězci "mezera s uvozovkami" nebo proč to musíme odstranit. Kromě této zmínky to tato odpověď neřeší.)




  1. rekurzivní vlastní dotaz

  2. Problém s funkcemi a pohledy oken

  3. Dávkový soubor pro připojení mysql a spouštění příkazů

  4. Vytvořte sloupec automatického zvýšení v SQLite