在 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" "%")
)
)
)
)
)
)
我对这些信息感兴趣的不是数据库中的每个表,而是特定查询返回的结果集。在这一点上,我特别需要知道检索到的特定列的最大长度,例如以固定宽度格式打印到屏幕上。
到目前为止我所考虑的(我确定不理想):
尝试解析入站 sql 语句以找出正在查询哪些表,然后专门获取这些表的元数据。事实证明,带有函数或公用表表达式等的 select 语句的结果会很复杂。我认为它很快就会变得混乱(并且不准确)。
什么也可能是基于入站查询创建一个临时视图......然后我可以在这个视图上获取元数据。但是,如果我只有与我正在使用的数据库的只读连接,这将不起作用。通常情况下,我相信我正在尝试做的事情。
获取结果,然后为返回的每一列找到值的最大长度,然后相应地创建我的固定宽度网格。如果我正在查看大型结果集,这将不会很好......
有没有更好的方法来确定我从查询中返回的所有内容的类型?其他程序如何做到这一点?似乎我应该能够从我在这里以某种方式发出查询请求时获取元数据:
(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))
)
)
提前致谢。