jdbc getMetaData用于特定查询

时间:2013-06-06 13:35:17

标签: jdbc clojure

在clojure / java jdbc中,我了解到使用 getMetaData 我可以返回大量有关通过jdbc连接的数据库的有趣信息。可以根据目录,架构和表名对其进行过滤。

(defn get-db-metadata 
    [db-spec ]
    (with-connection (get-db-connection-map db-spec)  
      ; get columns returs the following:
      ;  TABLE_CAT String       => table catalog (may be null)
      ;  TABLE_SCHEM String     => table schema (may be null)
      ;  TABLE_NAME String      => table name
      ;  COLUMN_NAME String     => column name
      ;  DATA_TYPE int          => SQL type from java.sql.Types
      ;  TYPE_NAME String       => Data source dependent type name, for a UDT the type name is fully qualified
      ;  COLUMN_SIZE int        => column size. For char or date types this is the maximum number of characters, for numeric or decimal types this is precision.
      ;  BUFFER_LENGTH          => not used.
      ;  DECIMAL_DIGITS int     => the number of fractional digits
      ;  NUM_PREC_RADIX int     => Radix (typically either 10 or 2)
      ;  NULLABLE int           => is NULL allowed.
      ;  columnNoNulls          => might not allow NULL values
      ;  columnNullable         => definitely allows NULL values
      ;  columnNullableUnknown  => nullability unknown
      ;  REMARKS String         => comment describing column (may be null)
      ;  COLUMN_DEF String      => default value (may be null)
      ;  SQL_DATA_TYPE int      => unused
      ;  SQL_DATETIME_SUB int   => unused
      ;  CHAR_OCTET_LENGTH int  => for char types the maximum number of bytes in the column
      ;  ORDINAL_POSITION int   => index of column in table (starting at 1)
      ;  IS_NULLABLE String     => "NO" means column definitely does not allow NULL values; "YES" means the column might allow NULL values. An empty string means nobody knows.
      ;  SCOPE_CATLOG String    => catalog of table that is the scope of a reference attribute (null if DATA_TYPE isn't REF)
      ;  SCOPE_SCHEMA String    => schema of table that is the scope of a reference attribute (null if the DATA_TYPE isn't REF)
      ;  SCOPE_TABLE String     => table name that this the scope of a reference attribure (null if the DATA_TYPE isn't REF)
      ;  SOURCE_DATA_TYPE short => source type of a distinct type or user-generated Ref type, SQL type from java.sql.Types (null if DATA_TYPE isn't DISTINCT or user-generated REF)
      (into #{}
            (map #(str (% :table_name) "." (% :column_name) "\n")
                 (resultset-seq (->
                                  (connection)
                                  (.getMetaData)
                                  ; Params in are catalog, schemapattern, tablenamepattern  
                                  ;(.getColumns "stuff" "public" nil "%")
                                  (.getColumns "db_catalog" "schema_name" "some_table" "%")
                                  )
                                )
                 )
            )
      )
    )

我对这些信息不感兴趣,不是对于数据库中的每个表,而是对特定查询返回的结果集感兴趣。此时我特别需要知道检索到的特定列的最大长度,以固定宽度格式打印到屏幕上。

到目前为止我考虑过的事情(我不确定):

  1. 尝试解析入站的sql语句以找出哪些表 正在查询,然后获取这些表的元数据 特别。结果证明这很复杂 具有函数或公用表表达式等的select语句的说明 我认为它可能会很快变得混乱(并且不准确)。

  2. 还可以创建一个基于的临时视图     入站查询...然后我可以获取此视图上的元数据。这个     但是,如果我只有一个只读连接,那就无法工作     我正在使用的数据库。通常情况下我相信我想要做的事情。

  3. 获取结果,然后为每个列返回查找结果     最大值的长度,然后创建我的固定宽度网格     因此。如果我在看大的话,这不会很好     结果集.....

  4. 有没有更好的方法来确定我从查询中返回的所有内容的类型?其他程序如何做到这一点?看起来我应该能够在我以某种方式发出查询请求时获取元数据:

    (defn fetch-results 
      "Treat lazy result sets in whole for returning a database query"  
      [db-spec query] 
      (with-connection 
        (get-db-connection-map db-spec) 
        (with-query-results res query 
          ; (get the medata here somehow for columns returned ????)
          (doall res))
        )
      )
    
    提前谢谢。

1 个答案:

答案 0 :(得分:0)

你可以在scala中这样做,也许这可以帮助你:

var stmt: PreparedStatement = null
var rs: ResultSetMetaData = null
try {
  stmt = conn.prepareStatement(query)
  rs = stmt.getMetaData()
} finally {
  cleanup(stmt)
}
}