2016-09-13 7 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; 
}