Recuperación del contenido de una tabla especificada por el usuario

El siguiente código muestra las tuplas de una tabla específica. ¿Cómo puedo convertir esto en código dinámico? Entonces, el usuario ingresaría el nombre de la tabla, luego se mostrarán los nombres de filas y columnas además del contenido de la tabla.

* Tenga en cuenta que res.getInt y res.getString deben especificarse tal como son. En un modelo dinámico, no necesitaría saber el número, tipo y nombre de las columnas. *

public void displayTableA()
{
    //Connection already established

    Statement st = conn.createStatement();
    ResultSet res = st.executeQuery("SELECT * FROM A");
    System.out.println("A_code: " + "\t" + "A_name: ");
    while (res.next()) {
        int r = res.getInt("A_code");
        String s = res.getString("A_name");
        System.out.println(r + "\t\t" + s);
    }
    conn.close();  
}

preguntado el 03 de mayo de 12 a las 20:05

Mala idea, a menos que realmente sepa lo que está haciendo y comprenda los riesgos de seguridad. -

Sé. Solo necesito hacer esto. Hay demasiadas tablas para codificar. -

@MarlonBrando Entonces, ¿sabe que tiene una columna 'int' y una columna 'String', pero no sabe cómo se llaman? -

3 Respuestas

Respuesta directa: la consulta es solo una cadena. Puede construirlo a partir de las entradas del usuario. Como leer el nombre de la tabla en una variable, decir "String tablename", luego

String query="select * from " + tablename;

Luego ejecuta la consulta para obtener el conjunto de resultados:

ResultSet rs=st.executeQuery(query);

Luego obtenga los metadatos para el conjunto de resultados:

ResultSetMetaData meta=rs.getMetaData();

Luego recorra las columnas obteniendo sus nombres:

for (int x=1;x<=meta.getColumnCount();++x)
{
  String columnName=meta.getColumnName(x);
  ... do whatever you want with this column name ...
}

(Tenga en cuenta que las columnas están numeradas a partir del 1, no del 0).

En cuanto a los datos en sí, si solo los está descargando, no necesita saber el tipo. Solo haz getString en todo. Cada tipo de datos se puede convertir en una cadena. Bueno, si tiene manchas o imágenes, es posible que desee verificarlas. Hay una función ResultSetMetaData para obtener el tipo de columna, creo que es getType o algo así. Compruebe los javadocs.

Dicho esto, ¿por qué quieres hacer esto? Si está creando algún tipo de herramienta para que los desarrolladores la utilicen para realizar consultas ad hoc, está bien. Pero sería extremadamente cauteloso al exponer algo como esto a los usuarios finales. (a) Es poco probable que entiendan los datos, y (b) Estaría creando un gran agujero de seguridad, los usuarios podrían ver CUALQUIER dato en el sistema. Potencialmente, podría envolver esto en controles para limitar a los usuarios a lo que están autorizados a ver, pero es mucho trabajo hacerlo bien. Es mucho más fácil decir "esto es lo que puedes ver" que tratar de decir "esto es lo que no puedes ver".

contestado el 03 de mayo de 12 a las 20:05

Supongo que podría verificar el nombre de la tabla con una lista de tablas "sin restricciones". Pero tenga en cuenta que cuando crea consultas a partir de las entradas de los usuarios, debe tener cuidado con los ataques de inyección SQL. Supongamos que creó la consulta como la que muestro arriba sin controles de seguridad. Alguien podría ingresar un nombre de tabla de "foobar; eliminar de cuentas a pagar;" Luego borra tu tabla de cuentas por pagar. - arrendajo

public void displayTable(String table)
{
    //Connection already established

    Statement st = conn.createStatement();
    ResultSet res = st.executeQuery("SELECT * FROM " + table);
    ResultSetMetaData rsmd = res.getMetaData();
    while (res.next()) {
        for(int ii = 1; ii <= rsmd.getColumnCount(); ii++) {
            // get type
            int type = rsmt.getColumnType(ii);
            String value = null;
            switch (type) {
                case Types.VARCHAR: value = res.getString(ii); break;
            }
            // print value.
            System.out.print(rsmd.getColumnName(ii) + ": " + value);
        }
    }
    conn.close();  
}

contestado el 03 de mayo de 12 a las 20:05

No sabría los nombres de las columnas. Entonces no puedo usar res.getInt("A_code") y res.getString("A_name"); - Nu GnojMik

lo siento, me comprometí demasiado pronto, mira mi edición. (Lo importante es el ResultSetMetaData) - Ángelo Fuchs

Si quieres imprimir un ResultSet en una consulta dinámica convirtiendo una instancia de ResultSet in String:

public static String toString(ResultSet rs) throws SQLException {
    StringBuilder sb = new StringBuilder();
    ResultSetMetaData metaData = rs.getMetaData();
    int columnCount = metaData.getColumnCount();
    Map<Integer, Integer> sizeMap = new HashMap<>();
    for (int column = 1; column <= columnCount; column++) {
        int size = Math.max(metaData.getColumnDisplaySize(column), metaData.getColumnName(column).length());
        sizeMap.put(column, size);
        sb.append(StringUtils.rightPad(metaData.getColumnName(column), size));
        sb.append(' ');
        sb.append(' ');
    }
    sb.append('\n');
    for (int column = 1; column <= columnCount; column++) {
        sb.append(StringUtils.rightPad("", sizeMap.get(column), '-'));
        sb.append(' ');
        sb.append(' ');
    }
    while(rs.next()) {
        sb.append('\n');
        for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
            String str = rs.getString(columnIndex);
            if (str == null) {
                str = "(null)";
            }
            sb.append(StringUtils.rightPad(str, sizeMap.get(columnIndex)));
            sb.append(' ');
            sb.append(' ');
        }
    }
    return sb.toString();
}

Para imprimir algo así:

user_id       user_code             date_update          
------------  --------------------  -------------------  
01006393      00989573              2011-09-29 19:23:46  
00984742      20192498              2011-12-21 00:00:00

Este método utiliza lenguaje común 3

Nota: debe usar esto con cuidado para evitar errores de memoria. Puedes cambiar el sb.append con System.out.print or System.out.println

contestado el 03 de mayo de 12 a las 20:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.