Derby数据库不支持create or replace view
构造。如何替换其他视图所依赖的视图?当我在创建之前尝试删除视图时,Derby会抛出异常
Operation 'DROP VIEW' cannot be performed on object 'VIEW_NAME' because VIEW 'OTHER_VIEW_NAME' is dependent on that object.
set constraints all deferred
不会改变任何内容。
答案 0 :(得分:1)
在运行时用依赖项替换视图:
Pattern messagePattern = Pattern.compile(
"Operation 'DROP VIEW' cannot be performed on object '\\w+' because VIEW '(\\w+)' is dependent on that object.");
class ViewDefinition {
String name;
String definition;
}
public void replaceView(ViewDefinition view, Connection conn) throws SQLException {
Deque<ViewDefinition> viewsToDrop = new LinkedList<ViewDefinition>();
Deque<ViewDefinition> viewsToAdd = new LinkedList<ViewDefinition>();
viewsToDrop.push(view);
viewsToAdd.push(view);
Statement st = conn.createStatement();
try {
while (!viewsToDrop.isEmpty()) {
ViewDefinition nextView = viewsToDrop.getFirst();
try {
st.execute("drop view " + nextView.name);
} catch (SQLException e) {
if ("X0Y23".equals(e.getSQLState())) {
// dependency error
String message = e.getMessage();
Matcher matcher = messagePattern.matcher(message);
if (matcher.matches()) {
ViewDefinition dependentView = new ViewDefinition();
dependentView.name = matcher.group(1);
dependentView.definition = getViewDefinition(dependentView.name, conn);
viewsToDrop.addFirst(dependentView);
viewsToAdd.addFirst(dependentView);
continue;
} else {
throw new RuntimeException(
String.format("Can't detect dependent view name for view %s", nextView.name));
}
} else {
throw e;
}
}
// view dropped
viewsToDrop.removeFirst();
}
while (!viewsToAdd.isEmpty()) {
ViewDefinition nextView = viewsToAdd.pollLast();
st.execute(nextView.definition);
}
} finally {
if (!st.isClosed())
st.close();
}
}
private String getViewDefinition(String viewName, Connection conn) throws SQLException {
String definition = null;
PreparedStatement ps = conn.prepareStatement(
"select v.viewdefinition from sys.sysviews v inner join sys.systables t on t.tableid = v.tableid where lower(t.tablename) = lower(?) and t.tabletype = ?");
ps.setString(1, viewName);
ps.setString(2, "V");
ResultSet rs = ps.executeQuery();
if (rs.next()) {
definition = rs.getString("viewdefinition");
}
rs.close();
ps.close();
return definition;
}