甲骨文& java动态'Order by'子句

时间:2010-09-16 13:01:07

标签: java sql oracle jdbc

我正在尝试在java中构建动态sql查询(如下所示)

    sqlStr = "Select * " +
        "from " + tableName

    if(tableName!=null){
        if(tableName.equals("Table1"){
            sqlStr = sqlStr.concat("order by city desc");
        }else if(tableName.equals("Table2"){
            sqlStr = sqlStr.concat("order by country desc");
        }else if(tableName.equals("Table3"){
            sqlStr = sqlStr.concat("order by price desc");
        }
    }

现在我想要做的是添加一个最终的'else'语句,该语句将根据表中是否包含名为'custID'的列来对查询进行排序。将有几个表与该列,所以我想按custID排序那些列。 (而不是为每个具有该列名的表提供数百个额外的if语句。)这可能吗?我见过人们使用'解码'功能,但我不知道如何在这里使用它。

5 个答案:

答案 0 :(得分:6)

使用DatabaseMetaData获取表格信息。

您可以使用getTablexxx()getColumnxx()方法获取表格信息。

Connection conn = DriverManager.getConnection(.....);
DatabaseMetaData dbmd = conn.getMetaData();
dbmd.getxxxx(); 

注意:在ORDER BY子句之前,您忘记了代码中的空格。

答案 1 :(得分:2)

如果您对硬编码事项感到满意,那么避免多个条件的方法是存储包含custID的所有表的列表。

private final static String tablesWithCustID = "/TableX/TableY/TableZ/";

...

if (tablesWithCustID.contains( tableName )) {
  sqlStr = sqlStr.concat("order by custID")
}

如果您愿意,可以使用List而不是简单的分隔字符串。

也许更好,您可以存储一个以表名作为键的映射,并将sort字符串作为值存储。加载一次,然后根本不需要任何条件。

答案 2 :(得分:1)

最直接的方法是从USER_TAB_COLUMNS或ALL_TAB_COLUMNS读取列定义,并检查是否存在custID列。没有疯狂的PL / SQL技巧,你将无法单独用SQL解决这个问题。

顺便说一句,tableName和order by子句之间缺少“”。

答案 3 :(得分:1)

我知道您正在寻找一种可以在一个查询中执行此操作的解决方案,即不事先运行单独的元数据查询。

不幸的是,这是不可能的。 decode 函数可以使用列值执行某些动态操作,但不能使用列名称执行某些动态操作。而且您正在寻找一种动态获取列名称的解决方案。

另一种方法是添加ORDER BY 1, 2。这是一种旧语法,表示第一列和第二列的顺序。如果custID列是第一列,这可能是一个很好的解决方案。否则它至少会给你一些排序。

答案 4 :(得分:1)

ArrayList.contains()怎么样? 您可以创建包含该列的表列表,并在最终if条件中检查tables.contains(tablename)