sql >> Base de Datos >  >> RDS >> Oracle

Análisis de nombres de tablas y columnas de SQL/HQL Java

Hay varias formas de lograr esto usando JSqlParser (https://github.com/JSQLParser/JSqlParser):

  1. Podrías proxeneta TableNamesFinder para recorrer todas las columnas también. Como puede ver en la lista de resultados, TableNamesFinder no atraviesa todas las apariciones de Columnas , porque no es necesario para ello. Así que uno tiene que completar la implementación transversal aquí también, lo cual no hice.

  2. Podría usar JSqlParser AST - Función de nodo para obtener todas las columnas. Para producciones específicas, JSqlParser produce nodos para un árbol de análisis. Columna es uno de ellos.

Para completar la implementación, se deben recopilar todas las columnas y hacer que esta lista sea distinta (caso, tabla, etc.)

String sql = "SELECT * FROM  ( ( SELECT TBL.ID AS rRowId, TBL.NAME AS name, TBL.DESCRIPTION as description, TBL.TYPE AS type, TBL1.SHORT_NAME AS shortName  FROM ROLE_TBL TBL WHERE ( TBL.TYPE = 'CORE' OR  TBL1.SHORT_NAME = 'TNG' AND  TBL.IS_DELETED <> 1  ) ) MINUS ( SELECT TBL.ID AS rRowId, TBL.NAME AS name, TBL.DESCRIPTION as description, TBL.TYPE AS type, TBL3.SHORT_NAME AS shortName,TBL3.NAME AS tenantName FROM ROLE_TBL TBL INNER JOIN TYPE_ROLE_TBL TBL1 ON TBL.ID=TBL1.ROLE_FK LEFT OUTER JOIN TNT_TBL TBL3 ON TBL3.ID = TBL.TENANT_FK LEFT OUTER JOIN USER_TBL TBL4 ON TBL4.ID = TBL1.USER_FK WHERE ( TBL4.ID =771100 AND  TBL.IS_DELETED <> 1  ) ) ) ORDER BY name ASC";

    System.out.println("using TableNamesFinder to get column names");
    Statement statement = CCJSqlParserUtil.parse(sql);
    Select selectStatement = (Select) statement;
    TablesNamesFinder tablesNamesFinder = new TablesNamesFinder() {
        @Override
        public void visit(Column tableColumn) {
            System.out.println(tableColumn);
        }
    };
    tablesNamesFinder.getTableList(selectStatement);

    System.out.println("-------------------------------------------");
    System.out.println("using ast nodes to get column names");
    SimpleNode node = (SimpleNode) CCJSqlParserUtil.parseAST(sql);

    node.jjtAccept(new CCJSqlParserDefaultVisitor() {
        @Override
        public Object visit(SimpleNode node, Object data) {
            if (node.getId() == CCJSqlParserTreeConstants.JJTCOLUMN) {
                System.out.println(node.jjtGetValue());
                return super.visit(node, data);
            } else {
                return super.visit(node, data);
            }
        }
    }, null);

Hay que tener en cuenta que JSqlParser es solo un analizador. Por lo tanto, no es posible obtener el nombre de la tabla de columnas sin especificarlo como en (table.column). Para hacerlo bien, el esquema de la base de datos debe estar disponible. Esto queda claro si miras:

select a from table1, table2

que es un SQL válido.