我正在尝试在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语句。)这可能吗?我见过人们使用'解码'功能,但我不知道如何在这里使用它。
答案 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)
。