2016-09-13 9 views
0

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例外をスローし、何も変わりません。

答えて

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