从未知数据库 SQL 和 Java 中查找外键
Posted
技术标签:
【中文标题】从未知数据库 SQL 和 Java 中查找外键【英文标题】:Finding Foreign Keys From Unknown Database SQL and Java 【发布时间】:2011-04-20 21:18:07 【问题描述】:我有一个 java 程序,它可以通过任何类型的数据库和任何数量的表进行查询。用户可以输入一个字符串,它将返回包含该字符串的表和行。问题是其中一些表有外键。在事先不了解数据库的情况下,如何递归地遍历所有表以查找外键和行?
平台:Windows 7(64) 数据库类型:Postgres
代码:
public static void connectPostGres(String type, String server, String database, String port, String username, String password) System.out.println("-------- PostgreSQL JDBC连接测试------------"); 尝试 Class.forName("org.postgresql.Driver"); 捕捉(ClassNotFoundException e) System.out.println("您的 PostgreSQL JDBC 驱动程序在哪里?包含在您的库路径中!"); e.printStackTrace(); 返回; System.out.println("PostgreSQL JDBC 驱动注册!"); 连接连接 = null; 尝试 connection = DriverManager.getConnection("jdbc:postgresql://" + server + ":" + port + "/" + 数据库、用户名、密码); //connection = DriverManager.getConnection("*********); 捕捉(SQLException e) System.out.println("doh!"); e.printStackTrace(); 返回; 如果(连接!= null) System.out.println("正在搜索..."); LinkedList allTables = new LinkedList(); 尝试 语句 st = connection.createStatement(); ResultSet rs = st.executeQuery("select * from pg_tables");//获取所有表 而(rs.next()) String myString = rs.getString("tablename"); if (myString.trim().charAt(0) == 'p' && myString.trim().charAt(1) == 'g') //这只是一些我们不想查询的蹩脚表 else if (myString.trim().charAt(0) == 's' && myString.trim().charAt(1) == 'q' && myString.trim().charAt(2) == 'l ') //这只是一些我们不想查询的蹩脚表 别的 allTables.add(myString);//将所有表添加到链表 rs.close(); 字符串 masterQuery = ""; for (int i = 0; i columnList = new LinkedList(); 对于 (int j = 1; j 0) for (int j = 0; j【问题讨论】:
【参考方案1】:您可以阅读这篇关于检索 postgres 元数据的信息 article。
通常您必须深入了解 INFORMATION SCHEMA 或使用系统目录。
编辑 此外,将尽可能多的逻辑放入 SQL 中,以避免检索和处理您根本不需要的数据。
这是上述文章的复制/粘贴,其中列出了所有约束(您会在此处找到这两种方法)
SELECT c.conname AS constraint_name,
CASE c.contype
WHEN 'c' THEN 'CHECK'
WHEN 'f' THEN 'FOREIGN KEY'
WHEN 'p' THEN 'PRIMARY KEY'
WHEN 'u' THEN 'UNIQUE'
END AS "constraint_type",
CASE WHEN c.condeferrable = 'f' THEN 0 ELSE 1 END AS is_deferrable,
CASE WHEN c.condeferred = 'f' THEN 0 ELSE 1 END AS is_deferred,
t.relname AS table_name,
array_to_string(c.conkey, ' ') AS constraint_key,
CASE confupdtype
WHEN 'a' THEN 'NO ACTION'
WHEN 'r' THEN 'RESTRICT'
WHEN 'c' THEN 'CASCADE'
WHEN 'n' THEN 'SET NULL'
WHEN 'd' THEN 'SET DEFAULT'
END AS on_update,
CASE confdeltype
WHEN 'a' THEN 'NO ACTION'
WHEN 'r' THEN 'RESTRICT'
WHEN 'c' THEN 'CASCADE'
WHEN 'n' THEN 'SET NULL'
WHEN 'd' THEN 'SET DEFAULT'
END AS on_delete,
CASE confmatchtype
WHEN 'u' THEN 'UNSPECIFIED'
WHEN 'f' THEN 'FULL'
WHEN 'p' THEN 'PARTIAL'
END AS match_type,
t2.relname AS references_table,
array_to_string(c.confkey, ' ') AS fk_constraint_key
FROM pg_constraint c
LEFT JOIN pg_class t ON c.conrelid = t.oid
LEFT JOIN pg_class t2 ON c.confrelid = t2.oid
WHERE t.relname = 'testconstraints2'
AND c.conname = 'testconstraints_id_fk';
-- with INFORMATION_SCHEMA:
SELECT tc.constraint_name,
tc.constraint_type,
tc.table_name,
kcu.column_name,
tc.is_deferrable,
tc.initially_deferred,
rc.match_option AS match_type,
rc.update_rule AS on_update,
rc.delete_rule AS on_delete,
ccu.table_name AS references_table,
ccu.column_name AS references_field
FROM information_schema.table_constraints tc
LEFT JOIN information_schema.key_column_usage kcu
ON tc.constraint_catalog = kcu.constraint_catalog
AND tc.constraint_schema = kcu.constraint_schema
AND tc.constraint_name = kcu.constraint_name
LEFT JOIN information_schema.referential_constraints rc
ON tc.constraint_catalog = rc.constraint_catalog
AND tc.constraint_schema = rc.constraint_schema
AND tc.constraint_name = rc.constraint_name
LEFT JOIN information_schema.constraint_column_usage ccu
ON rc.unique_constraint_catalog = ccu.constraint_catalog
AND rc.unique_constraint_schema = ccu.constraint_schema
AND rc.unique_constraint_name = ccu.constraint_name
WHERE tc.table_name = 'testconstraints2'
AND tc.constraint_name = 'testconstraints_id_fk';
【讨论】:
附加链接:postgresql.org/docs/9.0/static/catalog-pg-constraint.html 哇,真快。谢谢你。我会试一试。【参考方案2】:您可以在 DatabaseMetaData 中查询此类信息:
public static void main(String[] args) throws Exception
Connection connection = null;
try
Class.forName(DRIVER);
connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
DatabaseMetaData metadata = connection.getMetaData();
ResultSet resultSet = metadata
.getExportedKeys(null, null, TABLE);
while (resultSet.next())
String pkTableName = resultSet.getString("PKTABLE_NAME");
String pkColName = resultSet.getString("PKCOLUMN_NAME");
String fkTableName = resultSet.getString("FKTABLE_NAME");
String fkColName = resultSet.getString("FKCOLUMN_NAME");
catch (SQLException e)
e.printStackTrace();
finally
connection.close();
见DatabaseMetaData
【讨论】:
以上是关于从未知数据库 SQL 和 Java 中查找外键的主要内容,如果未能解决你的问题,请参考以下文章
SQL SERVER–2005–在数据库中查找具有外键约束的表