datos conexion java derby database

conexion - connect to derby database java



cómo crear una tabla si no existe usando Derby Db (9)

Soy nuevo en apache derby y parece que no puedo hacer el trabajo

CREATE TABLE IF NOT EXISTS table1 ...

como se puede lograr en MySql etc. Estoy obteniendo un ''Syntax error: Encountered "NOT" at line 1, column 17.'' , cuando intento ejecutar esta sentencia SQL en mi programa Java .

Revisé la página de documentación de Derby Db Create Statements , pero no pude encontrar una alternativa.


Aquí hay una solución que usted puede script en SQL.

  1. Crea una clase como la siguiente:

    package user.fenris.spring.extensions; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.SingleConnectionDataSource; public class SqlCreateIfNotExists { private static Log log = LogFactory.getLog(SqlCreateIfNotExists.class); public static void createTableIfNotExists(String tablename, String ddl) throws SQLException { Connection conn = DriverManager.getConnection("jdbc:default:connection"); if (conn != null) { JdbcTemplate template = new JdbcTemplate(new SingleConnectionDataSource(conn, true)); int count = template.queryForInt("select count(*) from SYS.SYSTABLES where TABLENAME = ?", tablename); log.debug("Count: " + count); if (count == 0) { log.debug("Executing sql statement: " + ddl); template.execute(sql); } else { log.debug("Table exists. Skipping sql execution..."); } } }

    }

    Nota : no tiene que usar Spring, puede escribirlo directamente en JDBC, pero luego debe saber cómo hacerlo correctamente. (A la izquierda como ejercicio para el lector). Además, puede volver a escribir esto para analizar el nombre de la tabla desde el parámetro ddl. Otra cosa sería hacer el correcto manejo de errores.

  2. Asegúrese de que la clase esté compilada y colocada en la ruta de clase de la VM en la que se ejecutará la base de datos.

  3. Escriba su script SQL:

    -- 2K for ddl statement should be enough. You want more? Seriously? create procedure CreateTableIfNotExists(in tablename varchar(128), in ddl varchar(2048)) PARAMETER STYLE JAVA MODIFIES SQL DATA language java external name ''user.fenris.spring.extensions.SqlCreateIfNotExists.createTableIfNotExists''; call CreateTableIfNotExists(''TABLE_NAME_MUST_BE_ALL_CAPS'', ''create table TABLE_NAME_MUST_BE_ALL_CAPS (entry_id int generated always as identity not null, entry_timestamp timestamp, username varchar(128) not null, note varchar(1024) not null, primary key (entry_id))''); -- you don''t have to drop this, but you would have to create a similar -- procedure to create the CreateTableIfNotExists procedure, -- (i.e. CreateProcedureIfNotExists) but then it''s turtles all the way down drop procedure CreateIfNotExists;

  4. ???

  5. lucro

Cree la tabla, capture la SQLException y verifique el código de estado de SQL.

La lista completa de códigos de error se puede encontrar here pero no pude encontrar que la Table <value> already exists ; probablemente es X0Y68 . El código que necesitas es X0Y32 .

Simplemente ejecute el código una vez e imprima el código de error. No olvide agregar una prueba para asegurarse de que el código funciona; De esta manera, puede detectar cambios en el código de error (no debería ocurrir ...).

En mis proyectos, generalmente agrego una clase auxiliar con métodos estáticos para poder escribir:

} catch( SQLException e ) { if( DerbyHelper.tableAlreadyExists( e ) ) { return; // That''s OK } throw e; }

Otra opción es ejecutar un SELECT en la tabla y verificar el código de estado (que debe ser 42X05 ). Pero ese es un segundo comando que debe enviar y no ofrece ninguna información adicional.

Lo que es peor, puede fallar por otras razones que no sean "La tabla no existe", por lo que el "error de crear e ignorar" es mejor que el IMO.


Derby no soporta esa declaración SQL.
En mi programa, analizo todas las tablas de la base de datos en un conjunto y verifico si la tabla existe allí. Me gusta esto:

private Set<String> getDBTables(Connection targetDBConn) throws SQLException { Set<String> set = new HashSet<String>(); DatabaseMetaData dbmeta = targetDBConn.getMetaData(); readDBTable(set, dbmeta, "TABLE", null); readDBTable(set, dbmeta, "VIEW", null); return set; } private void readDBTable(Set<String> set, DatabaseMetaData dbmeta, String searchCriteria, String schema) throws SQLException { ResultSet rs = dbmeta.getTables(null, schema, null, new String[] { searchCriteria }); while (rs.next()) { set.add(rs.getString("TABLE_NAME").toLowerCase()); } }


Otra solución con 2 condiciones:

  • Dispuesto a soltar la tabla antes de crear cada vez, con la misma presencia en un archivo .sql

  • Si están utilizando Spring y, por lo tanto, están dispuestos a usar Spring-test como una dependencia de Maven, su vida puede volverse mucho más sencilla con la anotación @Sql.

Entonces, primero agregando esto como una dependencia a tu pom:

<dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.2.5.RELEASE</version> <scope>test</scope> </dependency>

En segundo lugar, asumiendo que tiene un sql que cae, crea la tabla a en un archivo rectangle.sql :

DROP TABLE rectangles; CREATE TABLE rectangles ( id INTEGER NOT NULL PRIMARY KEY, width INTEGER NOT NULL, height INTEGER NOT NULL );

Y tienes una clase de prueba BlahTest que debería ejecutar este sql antes de hacer cualquier prueba que se ejecute, simplemente agrega la siguiente anotación @Sql a tu clase:

import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.SqlConfig; import org.springframework.test.context.jdbc.SqlConfig.ErrorMode; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes=XyzClientConfig.class) @Sql(scripts="/sql/ddl/rectangle.sql", config=@SqlConfig (errorMode=ErrorMode.IGNORE_FAILED_DROPS)) public class BlahTest { ... }

El valor del atributo de configuración especificado @SqlConfig tiene la magia que hace que omita los errores de la declaración de caída en caso de que la tabla no exista. Creo que se ha escrito para apuntar específicamente a estos tipos de bases de datos que no son compatibles con IF EXISTS para la creación de tablas / eliminaciones (que Derby realmente debería, incluso si no es parte del estándar SQL en este momento)


Sé que esto estaba marcado con una respuesta, pero en caso de que alguien quisiera otra forma de verificar, yo quería publicar de todos modos. Aquí verifico los metadatos de la tabla con un método que devuelve un valor booleano, verdadero si existe, falso si no existe. Espero que ayude a otros si están buscando.

private static Connection conn = null; private static Statement st = null; private static ResultSet rs = null; private static DatabaseMetaData dmd; public Boolean firstTime() { try { dmd = conn.getMetaData(); rs = dmd.getTables(null, "APP", "LOGIN", null); return !rs.next(); } catch (SQLException ex) { Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex); return false; } }


Siguiendo el ejemplo de Aaron Digulla con una clase de DerbyUtils para verificar si la tabla existe, esta es la solución que se me ocurrió:

Clase de llamada

public void createTable(String name) { Connection connection = null; PreparedStatement preparedStatement = null; try { connection = daoFactory.getConnection(); String sql = String.format(SQL_CREATE_TABLE, name); preparedStatement = connection.prepareStatement(sql, Statement.NO_GENERATED_KEYS); preparedStatement.execute(); } catch (SQLException e) { if(DerbyUtils.tableAlreadyExists(e)) { //check if the exception is because of pre-existing table. logger.info("Talbe " + name + " already exists. No need to recreate"); } else { logger.error(e.getMessage() + " : " + e.getStackTrace()); } } finally { close(connection, preparedStatement); //DAOUtils silently closes } }

DerbyUtils

public class DerbyUtils { public DerbyUtils() { //empty constructor -- helper class } public static boolean tableAlreadyExists(SQLException e) { boolean exists; if(e.getSQLState().equals("X0Y32")) { exists = true; } else { exists = false; } return exists; } }

Ver también


la consulta que está ejecutando no es compatible con Derby db. En cambio, si conoce el nombre de la tabla, puede encontrar si la tabla existe o no con bastante facilidad.

public boolean isTableExist(String sTablename) throws SQLException{ if(connection!=null) { DatabaseMetaData dbmd = connection.getMetaData(); ResultSet rs = dbmd.getTables(null, null, sTablename.toUpperCase(),null); if(rs.next()) { System.out.println("Table "+rs.getString("TABLE_NAME")+"already exists !!"); } else { System.out.println("Write your create table function here !!!"); } return true; } return false; }

Capturar es especificar el nombre de la tabla en mayúsculas, de lo contrario no podrá encontrar el nombre de la tabla en los metadatos.


para comprobar si la tabla existe:

Connection con = DriverManager.getConnection(url); ResultSet res = con.getMetaData().getTables(null, Schema_Name, table_name.toUpperCase(), null);//Default schema name is "APP" if(res.next()) { //do some thing; }else{ JOptionPane.showMessageDialog(null, table_name +" not exist"); }

para mostrar todas las tablas nombre:

Connection con = DriverManager.getConnection(url); ResultSet res = con.getMetaData().getTables(null, Schema_Name, "%", null);//Default schema name is "APP" while(res.next()) { JOptionPane.showMessageDialog(null, res.getString(3) + " is exist");//Show table name }else{ JOptionPane.showMessageDialog(null, table_name +" not exist"); }


try { connection.createStatement().execute("create table channels(channel varchar(20),topic varchar(20))"); } catch (Exception e) { // TODO Auto-generated catch block // e.printStackTrace(); }

Rodee la declaración de creación con try-catch.y asegúrese de comentar e.printstacktace (); si ya existe, no muestra el error, de lo contrario, crea una tabla .. !!