Direita. Não podemos fornecer identificadores como parâmetros de ligação. O nome da coluna deve fazer parte do texto SQL.
Podemos incorporar dinamicamente o nome da coluna no texto SQL com algo assim:
sql = "UPDATE diseaseinfo"
+ " SET `" + colname + "` = ?"
+ " WHERE companyname = 'mycom' AND diseaseName = ?";
E forneça valores para os dois parâmetros de ligação restantes
preparedStmt.setString(1, attrData);
preparedStmt.setString(2, medname);
E você está absolutamente correto em se preocupar com SQL Injection.
Fornecido como valores de ligação, aspas simples nos valores de
attrData
e medname
não será um problema, em termos de SQL Injection. Mas o exemplo que forneci é vulnerável ao incorporar o
colname
variável no texto SQL, se não tivermos alguma garantia de que colname
é "seguro" para incluir na declaração. Então precisamos fazer a atribuição de um valor para
colname
"seguro". Várias abordagens que podemos usar fazem isso. O mais seguro seria uma abordagem de "lista branca". O código pode garantir que apenas valores "seguros" permitidos específicos sejam atribuídos a
colname
, antes de colname
é incluído no texto SQL. Como um exemplo simples:
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
}
Uma abordagem mais flexível é garantir que um caractere de backtick não apareça em
colname
. No exemplo, o valor de colname
está sendo escapado colocando-o em backticks. Portanto, desde que um caractere de backtick não apareça em colname
, impediremos que um valor fornecido seja interpretado como algo diferente de um identificador. Para uma abordagem mais genérica (e complicada) de usar caracteres de backtick codificados, podemos considerar o uso de
supportsQuotedIdentifiers
e getIdentifierQuoteString
métodos de java.sql.DatabaseMetaData
aula. (No código OP, não vemos o tipo de dados do conteúdo de
attributes
. Vemos uma chamada para um método chamado replace
, e os argumentos que são fornecidos para isso. Supondo que attributes
é uma String, e isso deveria ser um nome de coluna, não está claro por que teríamos "espaço de aspas simples" na string ou por que precisamos remover isso. Além dessa menção, esta resposta não aborda isso.)