如何使用Flyway 2.0.1处理Oracle同义词?

时间:2013-05-10 15:26:31

标签: sql oracle flyway synonym

我现在正在使用飞路很长一段时间。非常好/完整的工具!

我实际上遇到了意想不到的情况......我有两个模式:

  • 处理表和序列的所有者
  • 使用同义词访问所有者对象的用户

自定义不希望我向所有者提供'grant create any synonym / drop any anyonym'权限。 但我可以向用户提供'grant create synonym'。

所以我需要

  1. 创建表格/序列(与所有者连接)
  2. 格兰特选择,删除...到我的用户架构(与所有者连接)
  3. 为用户创建同义词以访问所有者对象(与用户连接)
  4. 第3点是我的问题。

    如果我向所有者提供'授予任何同义词'并使用flyway占位符,我可以这样做:

    CREATE OR REPLACE SYNONYM ${user}.WORKITEMINFO FOR WORKITEMINFO;
    

    但我不能;)

    所以我实现的解决方案是使用连接到User模式的另一个DataSource来使用java迁移。 (我的MigrationUtils.replacePlaceholders允许我访问任何flyway.properties属性作为占位符)

    private final static String[] queries =
            {"CREATE OR REPLACE SYNONYM TASK_COMMENT FOR ${flyway.user}.TASK_COMMENT"}
    
    @Override
    public void migrate(final Connection connection) throws Exception {
    
        final DataSource dataSource = MigrationUtils.getUserDataSource();
    
        final Connection connectionForMigrations = dataSource.getConnection();
    
        final JdbcTemplate jdbcTemplate = new JdbcTemplate(connectionForMigrations);
        new TransactionTemplate(connectionForMigrations).execute(new TransactionCallback<Void>() {
    
            @Override
            public Void doInTransaction() {
    
                try {
                    for (final String query : queries) {
                        final String replacedQuery = MigrationUtils.replacePlaceholders(query);
                        LOG.debug("Executing SQL: " + replacedQuery);
                        jdbcTemplate.executeStatement(replacedQuery);
                    }
                } catch (final SQLException exc) {
                    throw new FlywayException("Could not drop synonym", exc);
                }
                return null;
            }
        });
    
    }
    

    还有另一种方法可以解决这种情况吗?

    谢谢!

2 个答案:

答案 0 :(得分:0)

最好的方法是在应用程序中限定模式名称。

如果那是不可能的并且应用程序仅使用SQL(而不是PL / SQL)来访问“Owner”对象,则可以通过在登录后触发器中更改默认架构来避免使用同义词:

create or replace trigger USERX.a_logon_USERX
after logon on USERX
BEGIN
  EXECUTE IMMEDIATE ('ALTER SESSION SET current_schema=standard');
END;

但是,当应用程序将PL / SQL块(“begin ... end;”)发送到数据库时,要掌握这种技术失败有点困难。 PL / SQL已编译,因此无法考虑当前架构。

答案 1 :(得分:0)

在您运行flyway时使用-Dflyway.schemas=OWNER_NAME