使用MSSQL的通用数据库返回函数

时间:2018-12-12 16:51:04

标签: java sql

我正在写(已经写过)一种通用的数据库查询功能。由于将在不同的地方使用不同的字段名称和不同的列来调用它,因此我想列出一个Map。所以我想我将获取元数据,找到每个列名称并获取列值。但这会抛出ArrayIndexOutOfBoundsException:

        try {
            ResultSet rs = Query.OpenQuery(conn, sql);
            while (rs.next()) {
                Map<String, String> map = new HashMap<>();
                ResultSetMetaData md = rs.getMetaData();
                int cnt = md.getColumnCount();
                for (int i = 0; i < cnt; i++) {
                    String col = md.getColumnName(i);
                    String val = rs.getString(col);
                    col = col.toLowerCase();
                    map.put(col, val);
                }
                res.add(map);
            }
        } catch (SQLException e1) {
            throw new KDTException("Could not query directconnectionsubmittracking", e1);
        }

当我逐步执行该操作时,cnt的值为2。当i为0时,它将在第一次迭代中引发异常,但不应超出范围。不确定为什么会抛出异常。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

  1. 传递查询听起来像您的系统很容易受到SQL注入攻击。您应该很少基于sql语句进行查询;通常它是一个带有问号的sql语句,以及所有单独传递的参数,使用PreparedStatement将它们联系在一起。否则,您将无法避免SQL注入安全性问题。

  2. 有些库已经对此进行了考虑。特别是JDBI和JOOQ;在继续改造这个特殊的车轮之前,我会给他们阅读。

  3. JDBC中的大多数东西都是奇异的1索引,而不是0索引。因此,它是md.getColumnName(i + 1)或可能将循环从1开始并使用<= cnt而不是< cnt

  4. 重新查询返回的行的列标题很愚蠢;任何给定的结果集都不会在对rs.next()的调用之间更改标头。一次,而不是每行一次。