我有一个Oracle表(COMBO_VALUES),它已被许多其他表引用。例如,COMBO_VALUES中的1条记录可能已被100个不同的表引用。
我想找到指向COMBO_VALUES记录的所有相关记录(它们的ID和表名),以便稍后我可以更新它们。
我更喜欢在这个问题中使用Java代码,它可以利用Oracle Metadata来收集我正在寻找的数据(我不熟练使用PL / SQL)。
顺便说一句,我不想改变我的桌面以获得一个" CASCADE"选项。我想要的(至少现在)是找到依赖行Id和表名。
谢谢...
答案 0 :(得分:1)
虽然这是一种丑陋的方式,但这是你所要求的。您可以加入 all_cons_columns 和 all_constraints 视图,以根据主键 - 外键关系获取父子信息。获得父表,子表和引用列名后,您可以稍后在子表上执行 MERGE ,并将匹配的行形成父表。
例如,
SQL> column owner format a10
SQL> column parent_table format a15
SQL> column child_table format a15
SQL> column column_name format a15
SQL> column constraint_name format a15
SQL> column referenced_key format a15
SQL> column constraint_type format a15
SQL> set linesize 200
SQL> SELECT a.owner,
2 a.table_name parent_table,
3 b.table_name child_table,
4 a.column_name,
5 a.constraint_name,
6 b.constraint_name referenced_key,
7 b.constraint_type
8 FROM all_cons_columns a ,
9 all_constraints b
10 WHERE a.owner ='SCOTT'
11 AND a.constraint_name = b.r_constraint_name
12 AND a.table_name ='DEPT';
OWNER PARENT_TABLE CHILD_TABLE COLUMN_NAME CONSTRAINT_NAME REFERENCED_KEY CONSTRAINT_TYPE
----- ------------ ----------- ----------- --------------- --------------- ---------------
SCOTT DEPT EMP DEPTNO PK_DEPT FK_DEPTNO R
SQL>
因此,上面的查询给出了父表和子表信息以及引用的列名。根据此信息,使用 MERGE 语句:
MERGE child_table c
USING parent_table p
ON (p.key = c.key)
WHEN MATCHED THEN
UPDATE SET...
请记住,您无法合并用于加入ON子句的列。
答案 1 :(得分:0)
答案 2 :(得分:0)
我刚写了一个完全符合我要求的课程:
这是我提出的代码(抱歉,这可能不够好):
public class RowFinder {
boolean autoCommit;
public RowFinder(boolean autoCommit) {
this.autoCommit = autoCommit;
}
public static void main(String[] args) {
RowFinder rowFinder = new RowFinder(false);
rowFinder.findRows("YOUR_TABLE_NAME", "PRIMARY_KEY_FIELD_NAME", "OLD_ID", "NEW_ID_FOR_CHILDREN");
}
public void findRows(String tableName, String columnName, String oldId, String newId) {
Connection connection = null;
java.sql.Statement statement = null;
try {
Class.forName("oracle.jdbc.OracleDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
connection = DriverManager.getConnection("jdbc:oracle:thin@DB_IP_ADDRESS:1521:SID", "USER", "PASS");
connection.setAutoCommit(autoCommit);
statement = connection.createStatement();
System.out.println(String.format("\nTrying to Delete %s with Old ID: '%s' and Update Children with New ID: '%s'", tableName, oldId, newId));
boolean flag = true;
long counter = 1;
while (flag) {
try {
String deleteQuery = String.format("delete from %s where %s = %s", tableName, columnName, oldId);
statement.executeUpdate(deleteQuery);
flag = false;
} catch (SQLException e) {
String errorMessage = e.getMessage();
//TRYING TO FIND THE CONSTRAINT NAME FROM ERROR - YOU CAN CHANGE IT ACCORDING TO YOUR PROJECT SETTINGS
Pattern pattern = Pattern.compile("\\(PROJECT_NAME\\.(.*)\\)");
Matcher matcher = pattern.matcher(errorMessage);
String referenceName;
if (matcher.find()) {
referenceName = matcher.group(1);
String constraintTableQuery = String.format("SELECT ucc.table_name,ucc.column_name FROM user_cons_columns ucc WHERE ucc.constraint_name = '%s'", referenceName);
try {
ResultSet resultSet = statement.executeQuery(constraintTableQuery);
resultSet.next();
String constraintTableName = resultSet.getString(1);
String constraintColumnName = resultSet.getString(2);
String updateQuery = String.format("UPDATE %s SET %s = '%s' WHERE %s = '%s'", constraintTableName, constraintColumnName, newId, constraintColumnName, oldId);
statement.executeUpdate(updateQuery);
System.out.println(String.format("%s. Updated Child Located at : %s => %s",counter++,constraintTableName,constraintColumnName));
} catch (SQLException e1) {
e1.printStackTrace();
}
} else {
System.out.println("Matcher didn't find anything... Exiting...");
if (autoCommit)
connection.commit();
else
connection.rollback();
statement.close();
connection.close();
System.exit(0);
}
}
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (autoCommit){
System.out.println("Deleted the Record and Changed its Children.");
connection.commit();
}
else{
System.out.println("Rolling Back Changes...");
connection.rollback();
}
statement.close();
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}