1
resposta

CREATE TABLE EM POSTGRESQL ATRAVÉS DE CLASSE JAVA

Vou tentar explicar minha situação.

Possuo uma Classe Java que cria as tabelas em postgresql.

porém é uma classe que pode ser alterada posteriormente. Caso seja necessária atualização da tabela, como já existem dados salvos não posso apenas dar um drop e recria-la, preciso que ela persista e seja passível de receber uma nova coluna por exemplo. Esta classe que cria a base, estava 100% operacional quando o SGBD era o Firebird, mas a migração fez-se necessária.

Meu problema esta sendo : administrar o valor de retorno do resultset.

para que funcione desta forma : - se tabela não existir (através do select, valor retornado pelo select ) - rs.next (){ entrar no create table} - else (tabela já existe ) entrar nos alter table a fim de realizar atualizações.

Esta seria a forma ideal de execução, porém no código abaixo é entrado nos 2 ifs. Usei o rs.isClosed() para obrigar ele entrar ali. Quando executo pela segunda vez o código ele entra no rs.next(). E quando cai no gerador de FK da uma exceção e cai fora do método, retornando "FK already exists )

Estou tentando explicar da melhor forma possível. O grande problema é deixar esse código fluido, Gostaria de dicas para resolver isto. Estou tentando já alguns dias, mas nenhuma forma funcionou 100% como deveria.

private static void CLIENTES_ALTER_LOG() {
        try {
            try (Connection conn = Class_Conexao.GetConnection();
                    Statement stmt = conn.createStatement();
                    ResultSet rs = stmt.executeQuery("SELECT EXISTS (SELECT * FROM pg_tables WHERE schemaname = 'public' AND tablename = 'clientes_alter_log')")) {

                if (rs.next()) {
                    stmt.executeUpdate("CREATE TABLE if not exists CLIENTES_ALTER_LOG ( "
                            + "CLIENTE_ALTER_LOG_ID SERIAL PRIMARY KEY, "
                            + "CLIENTE_ALTER_LOG_CLI INT NOT NULL, "
                            + "CLIENTE_ALTER_LOG_USER INT NOT NULL, "
                            + "CLIENTE_ALTER_LOG_DATE TIMESTAMP default current_timestamp NOT NULL, "
                            + "CLIENTE_ALTER_LOG_TEXT VARCHAR(10000) NOT NULL)");

                    stmt.execute("alter table CLIENTES_ALTER_LOG add constraint FK_CLIENTE_ALTER_LOG_CLI foreign key (CLIENTE_ALTER_LOG_CLI) references CLIENTES(CLIENTE_ID)");
                    stmt.execute("alter table CLIENTES_ALTER_LOG add constraint FK_CLIENTE_ALTER_LOG_USER foreign key (CLIENTE_ALTER_LOG_USER) references USERS(USER_ID)");

                    System.out.println("CREATE TABLE CLIENTES_ALTER_LOG →");
                }
                if (rs.isClosed()) {
                    stmt.execute("ALTER TABLE CLIENTES_ALTER_LOG ADD COLUMN if not exists CLIENTE_ALTER_LOG_CLI INT NOT NULL");
                    stmt.execute("ALTER TABLE CLIENTES_ALTER_LOG ADD COLUMN if not exists CLIENTE_ALTER_LOG_USER INT NOT NULL");
                    stmt.execute("ALTER TABLE CLIENTES_ALTER_LOG ADD COLUMN if not exists CLIENTE_ALTER_LOG_DATE TIMESTAMP default current_timestamp NOT NULL");
                    stmt.execute("ALTER TABLE CLIENTES_ALTER_LOG ADD COLUMN if not exists CLIENTE_ALTER_LOG_TEXT VARCHAR(10000) NOT NULL");

                    System.out.println("ALTERAR TABELA CLIENTES_ALTER_LOG");
                    System.out.println("---------------------------------");
                }
            }
        } catch (Exception e) {
            System.out.println("\n " + e.getMessage());
        }
    }
1 resposta

Olá, Patrik! Como vai?

Peço desculpas pela demora no retorno a sua mensagem.

No código que você compartilhou, existem alguns problemas que podem estar causando o comportamento indesejado. Vou tentar ajudá-lo a corrigir esses problemas.

Primeiro, você pode substituir a verificação de tabela existente usando o SELECT EXISTS por uma consulta mais simples, usando o IF NOT EXISTS. Isso irá criar a tabela somente se ela não existir.

Em seguida, você pode usar o método DatabaseMetaData.getColumns para verificar se as colunas já existem na tabela. Isso permite que você adicione colunas somente se elas não estiverem presentes.

Aqui está uma versão modificada do seu código que incorpora essas alterações:

private static void CLIENTES_ALTER_LOG() {
    try (Connection conn = Class_Conexao.GetConnection()) {
        DatabaseMetaData metaData = conn.getMetaData();
        try (ResultSet rs = metaData.getColumns(null, "public", "clientes_alter_log", null)) {
            if (!rs.next()) {
                try (Statement stmt = conn.createStatement()) {
                    stmt.executeUpdate("CREATE TABLE CLIENTES_ALTER_LOG ("
                            + "CLIENTE_ALTER_LOG_ID SERIAL PRIMARY KEY, "
                            + "CLIENTE_ALTER_LOG_CLI INT NOT NULL, "
                            + "CLIENTE_ALTER_LOG_USER INT NOT NULL, "
                            + "CLIENTE_ALTER_LOG_DATE TIMESTAMP DEFAULT current_timestamp NOT NULL, "
                            + "CLIENTE_ALTER_LOG_TEXT VARCHAR(10000) NOT NULL)"
                    );
                    stmt.execute("ALTER TABLE CLIENTES_ALTER_LOG ADD CONSTRAINT FK_CLIENTE_ALTER_LOG_CLI FOREIGN KEY (CLIENTE_ALTER_LOG_CLI) REFERENCES CLIENTES(CLIENTE_ID)");
                    stmt.execute("ALTER TABLE CLIENTES_ALTER_LOG ADD CONSTRAINT FK_CLIENTE_ALTER_LOG_USER FOREIGN KEY (CLIENTE_ALTER_LOG_USER) REFERENCES USERS(USER_ID)");
                    System.out.println("CREATE TABLE CLIENTES_ALTER_LOG →");
                }
            } else {
                boolean columnExists = false;
                while (rs.next()) {
                    String columnName = rs.getString("COLUMN_NAME");
                    if (columnName.equalsIgnoreCase("CLIENTE_ALTER_LOG_CLI")) {
                        columnExists = true;
                        break;
                    }
                }
                if (!columnExists) {
                    try (Statement stmt = conn.createStatement()) {
                        stmt.execute("ALTER TABLE CLIENTES_ALTER_LOG ADD COLUMN CLIENTE_ALTER_LOG_CLI INT NOT NULL");
                        stmt.execute("ALTER TABLE CLIENTES_ALTER_LOG ADD COLUMN CLIENTE_ALTER_LOG_USER INT NOT NULL");
                        stmt.execute("ALTER TABLE CLIENTES_ALTER_LOG ADD COLUMN CLIENTE_ALTER_LOG_DATE TIMESTAMP DEFAULT current_timestamp NOT NULL");
                        stmt.execute("ALTER TABLE CLIENTES_ALTER_LOG ADD COLUMN CLIENTE_ALTER_LOG_TEXT VARCHAR(10000) NOT NULL");
                        System.out.println("ALTERAR TABELA CLIENTES_ALTER_LOG");
                        System.out.println("---------------------------------");
                    }
                }
            }
        }
    } catch (Exception e) {
        System.out.println("\n " + e.getMessage());
    }
}

Essa versão do código verifica primeiro se a tabela clientes_alter_log existe usando o método getColumns do DatabaseMetaData. Em seguida, ele verifica se a coluna CLIENTE_ALTER_LOG_CLI já existe na tabela.

Contudo, essa solução serve apenas para esse trecho de código. Logo, é necessário realizar ajustes para adicioná-lo em todo o seu projeto.

Espero que essa sugestão ajude a resolver o seu problema!

Bons estudos!