Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Dynamiczna nazwa kolumny za pomocą przygotowanej instrukcji + zapytanie sql ze zmienną zawierającą 's

Dobrze. Nie możemy dostarczyć identyfikatorów jako parametrów wiązania. Nazwa kolumny musi być częścią tekstu SQL.

Możemy dynamicznie włączyć nazwę kolumny do tekstu SQL za pomocą czegoś takiego:

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

I podaj wartości dla dwóch pozostałych parametrów wiązania

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

I masz całkowitą rację, jeśli chodzi o obawy związane z wstrzykiwaniem SQL.

Dostarczane jako wartości wiązania, pojedyncze cudzysłowy w wartościach attrData i medname nie będzie problemem, jeśli chodzi o wstrzykiwanie SQL.

Ale podany przeze mnie przykład to podatny na ataki poprzez włączenie colname zmienną do tekstu SQL, jeśli nie mamy gwarancji, że colname jest „bezpieczny” do umieszczenia w oświadczeniu.

Musimy więc dokonać przypisania wartości do colname "bezpieczny".

Możemy to zrobić na kilka sposobów. Najbezpieczniejszym byłoby podejście „białej listy”. Kod może zapewnić, że tylko określone dozwolone „bezpieczne” wartości zostaną przypisane do colname , przed colname zostaje uwzględniony w tekście SQL.

Jako prosty przykład:

  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 
  }

Bardziej elastycznym podejściem jest upewnienie się, że znak wsteczny nie pojawia się w colname . W tym przykładzie wartość colname jest uciekana umieszczając go w backtickach. Tak długo, jak znak cofania nie pojawia się w colname , zapobiegniemy interpretacji podanej wartości jako czegoś innego niż identyfikator.

Aby uzyskać bardziej ogólne (i skomplikowane) podejście do używania zakodowanych na stałe znaków backtick, możemy rozważyć użycie supportsQuotedIdentifiers i getIdentifierQuoteString metody java.sql.DatabaseMetaData klasa.

(W kodzie OP nie widzimy typu danych zawartości attributes . Widzimy wywołanie metody o nazwie replace i argumenty, które są do tego dostarczone. Zakładając, że attributes jest ciągiem i ma to być nazwa kolumny, nie jest wcale jasne, dlaczego mielibyśmy mieć w ciągu „spację w pojedynczym cudzysłowie” ani dlaczego musimy ją usunąć. Poza tą wzmianką ta odpowiedź nie dotyczy tego.)




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zaktualizuj dane do tabeli z dynamicznie tworzonego pola wejściowego

  2. Jak przesłać wiele obrazów w laravel?

  3. django.core.exceptions.ImproperlyConfigured:Błąd podczas ładowania modułu MySQLdb:Brak modułu o nazwie MySQLdb

  4. Wstaw kolejny numer w MySQL

  5. Wskazówki dotyczące migracji z HAProxy do ProxySQL