Parâmetro SQL

Olá a todos!

Existe a possibilidade de nomear parâmetros sql

no Delphi tem um esquema assim:

select *
from tabela
where campo1 = :param1
and campo2 = :param2

depois:

query.ParamByName('param1').AsString := '1';
query.ParamByName('param2').AsString := '2';
query.Execute();

No java so encontrei algo semanhante assim:

select *
from tabela
where campo1 = ?
and campo2 = ?
stmt = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
stmt.setString(1, '1');
stmt.setString(2, '2');

Porém preciso passar o parametro por nome, pois será definido em runtime e o usuário poderá se confundir visualizando os parametros pelos números. Existe algo semelhante no java igual ao exemplo que passei do Delphi ou terei que implementar no braço?

Abraços

No hibernate tem como você fazer isso se não me engano.

Boa noite,

De uma olhada nesse link: http://www.javaworld.com/javaworld/jw-04-2007/jw-04-jdbc.html
Acho que tem o que você precisa. Qualquer dúvida é só dizer.

Edson Martins

[quote=edsonmartins]Boa noite,

De uma olhada nesse link: http://www.javaworld.com/javaworld/jw-04-2007/jw-04-jdbc.html
Acho que tem o que você precisa. Qualquer dúvida é só dizer.

Edson Martins[/quote]

Edson, bom dia!

O código que está no link, não funciona, adicionei todos os jars do hydra, importei as libs, copiei e colei da forma que estava lá, não sei o que fiz errado. O eclipse disse que não pode instanciar o tipo devido a ser uma interface. Já usou? O que fazer para funcionar?


String query = "select * from people where (first_name = :name or last_name = :name) and address = :address");
NamedParameterStatement p = new NamedParameterStatement(con, query);
p.setString("name", name);
p.setString("address", address);

Tenta com essa classe:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class NamedParameterStatement {

public static void main(String[] args) throws Exception {

	Connection connection = DriverManager.getConnection("xxxxxxxxxxxxxxxxxxxx");
	NamedParameterStatement stmt = new NamedParameterStatement(connection,
			"SELECT * FROM PESSOA WHERE ID_PESSOA >= :PID_PESSOA");

	stmt.setLong("PID_PESSOA", new Long(100));

	ResultSet resultSet = stmt.executeQuery();
}

private final PreparedStatement statement;

private final Map indexMap;

public NamedParameterStatement(Connection connection, String query) throws SQLException {
	indexMap = new HashMap();
	String parsedQuery = parse(query, indexMap);
	statement = connection.prepareStatement(parsedQuery);
}

static final String parse(String query, Map paramMap) {
	int length = query.length();
	StringBuffer parsedQuery = new StringBuffer(length);
	boolean inSingleQuote = false;
	boolean inDoubleQuote = false;
	int index = 1;

	for (int i = 0; i < length; i++) {
		char c = query.charAt(i);
		if (inSingleQuote) {
			if (c == '\'') {
				inSingleQuote = false;
			}
		} else if (inDoubleQuote) {
			if (c == '"') {
				inDoubleQuote = false;
			}
		} else {
			if (c == '\'') {
				inSingleQuote = true;
			} else if (c == '"') {
				inDoubleQuote = true;
			} else if (c == ':' && i + 1 < length && Character.isJavaIdentifierStart(query.charAt(i + 1))) {
				int j = i + 2;
				while (j < length && Character.isJavaIdentifierPart(query.charAt(j))) {
					j++;
				}
				String name = query.substring(i + 1, j);
				c = '?';
				i += name.length();

				List indexList = (List) paramMap.get(name);
				if (indexList == null) {
					indexList = new LinkedList();
					paramMap.put(name, indexList);
				}
				indexList.add(new Integer(index));

				index++;
			}
		}
		parsedQuery.append(c);
	}

	for (Iterator itr = paramMap.entrySet().iterator(); itr.hasNext();) {
		Map.Entry entry = (Map.Entry) itr.next();
		List list = (List) entry.getValue();
		int[] indexes = new int[list.size()];
		int i = 0;
		for (Iterator itr2 = list.iterator(); itr2.hasNext();) {
			Integer x = (Integer) itr2.next();
			indexes[i++] = x.intValue();
		}
		entry.setValue(indexes);
	}

	return parsedQuery.toString();
}

private int[] getIndexes(String name) {
	int[] indexes = (int[]) indexMap.get(name);
	if (indexes == null) {
		throw new IllegalArgumentException("Parameter not found: " + name);
	}
	return indexes;
}

public void setObject(String name, Object value) throws SQLException {
	int[] indexes = getIndexes(name);
	for (int i = 0; i < indexes.length; i++) {
		statement.setObject(indexes[i], value);
	}
}

public void setString(String name, String value) throws SQLException {
	int[] indexes = getIndexes(name);
	for (int i = 0; i < indexes.length; i++) {
		statement.setString(indexes[i], value);
	}
}

public void setInt(String name, int value) throws SQLException {
	int[] indexes = getIndexes(name);
	for (int i = 0; i < indexes.length; i++) {
		statement.setInt(indexes[i], value);
	}
}

public void setLong(String name, long value) throws SQLException {
	int[] indexes = getIndexes(name);
	for (int i = 0; i < indexes.length; i++) {
		statement.setLong(indexes[i], value);
	}
}

public void setTimestamp(String name, Timestamp value) throws SQLException {
	int[] indexes = getIndexes(name);
	for (int i = 0; i < indexes.length; i++) {
		statement.setTimestamp(indexes[i], value);
	}
}

public PreparedStatement getStatement() {
	return statement;
}

public boolean execute() throws SQLException {
	return statement.execute();
}

public ResultSet executeQuery() throws SQLException {
	return statement.executeQuery();
}

public int executeUpdate() throws SQLException {
	return statement.executeUpdate();
}

public void close() throws SQLException {
	statement.close();
}

public void addBatch() throws SQLException {
	statement.addBatch();
}

public int[] executeBatch() throws SQLException {
	return statement.executeBatch();
}

}

Tem um método main de exemplo.

Edson