从未知数据库SQL和Java中查找外键

从未知数据库SQL和Java中查找外键,java,sql,postgresql,Java,Sql,Postgresql,我有一个java程序,可以查询任何类型的数据库和任意数量的表。用户可以输入一个字符串,它将返回包含该字符串的表和行。问题是这些表中的某些表具有外键。我如何能够在没有任何数据库知识的情况下递归地遍历所有表来查找外键和行 平台:Windows764 数据库类型:Postgres 代码: public static void connectPostGres(String type, String server, String database, String port, String username

我有一个java程序,可以查询任何类型的数据库和任意数量的表。用户可以输入一个字符串,它将返回包含该字符串的表和行。问题是这些表中的某些表具有外键。我如何能够在没有任何数据库知识的情况下递归地遍历所有表来查找外键和行

平台:Windows764 数据库类型:Postgres

代码:

public static void connectPostGres(String type, String server, String database, String port, String username, String password) { System.out.println("-------- PostgreSQL JDBC Connection Testing ------------"); try { Class.forName("org.postgresql.Driver"); } catch (ClassNotFoundException e) { System.out.println("Where is your PostgreSQL JDBC Driver? Include in your library path!"); e.printStackTrace(); return; } System.out.println("PostgreSQL JDBC Driver Registered!"); Connection connection = null; try { connection = DriverManager.getConnection("jdbc:postgresql://" + server + ":" + port + "/" + database, username, password); //connection = DriverManager.getConnection("*********); } catch (SQLException e) { System.out.println("doh!"); e.printStackTrace(); return; } if (connection != null) { System.out.println("Searching..."); LinkedList allTables = new LinkedList(); try { Statement st = connection.createStatement(); ResultSet rs = st.executeQuery("select * from pg_tables");//get all the tables while (rs.next()) { String myString = rs.getString("tablename"); if (myString.trim().charAt(0) == 'p' && myString.trim().charAt(1) == 'g') { //this is just some crappy tables we dont want to query through } else if (myString.trim().charAt(0) == 's' && myString.trim().charAt(1) == 'q' && myString.trim().charAt(2) == 'l') { //this is just some crappy tables we dont want to query through } else { allTables.add(myString);//add all tables to a linkedlist } } rs.close(); String masterQuery = ""; for (int i = 0; i columnList = new LinkedList(); for (int j = 1; j 0) { for (int j = 0; j
您可以阅读有关检索postgres元数据的信息

通常,您必须深入了解信息模式或使用系统目录

编辑 此外,将尽可能多的逻辑放在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';

您可以查询数据库元数据以获取此类信息:

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();
    }
    }

参见

附加链接:哇,太快了。非常感谢。我要试一试。