Liquibase with column type numeric(x, y) is creating postgreSQL table with column type number - spring

I have a spring application connected to a postgreSQL DB. My issue is that this bit of script:
<column name="utmx" type="numeric(20, 5)">
<constraints nullable="true"/>
</column>
<column name="utmy" type="numeric(20, 5)">
<constraints nullable="true"/>
</column>
Is being executed like this:
CREATE TABLE PUBLIC.table (... utmx NUMBER(20, 5), utmy NUMBER(20, 5)...
As you can see, the column type NUMERIC is being changed to NUMBER on table creation.
Why is that? How can I solve it?
Thanks in advance

Related

Liquibase ignores autoIncrement="true" for Oracle DB

I generated a schema/tables via the DDL that Hibernate generated which was correct:
create table cat_component.organisation (
id number(19,0) generated as identity,
archived number(1,0),
is_in_avaloq_group number(1,0) not null,
mdm_uuid varchar2(255 char),
name varchar2(255 char),
primary key (id)
)
After that, I tried to generate Liquibase changelog which looks like this:
<changeSet author="blabla (generated)" id="1582733383680-5">
<createTable tableName="organisation">
<column autoIncrement="true" name="id" type="NUMBER(19, 0)">
<constraints primaryKey="true" primaryKeyName="organisationPK"/>
</column>
<column name="archived" type="NUMBER(1, 0)"/>
<column name="is_in_avaloq_group" type="NUMBER(1, 0)">
<constraints nullable="false"/>
</column>
<column name="mdm_uuid" type="VARCHAR2(255 CHAR)"/>
<column name="name" type="VARCHAR2(255 CHAR)"/>
</createTable>
</changeSet>
The problem is that if I try to run the liquibase changelog, it translates the XML definition into this:
2020-02-26 16:15:10.779 INFO 8064 --- [main] liquibase.executor.jvm.JdbcExecutor : CREATE TABLE CAT_COMPONENT.organisation (id NUMBER(19, 0) NOT NULL, archived NUMBER(1, 0), is_in_avaloq_group NUMBER(1, 0) NOT NULL, mdm_uuid VARCHAR2(255 CHAR), name VARCHAR2(255 CHAR), CONSTRAINT organisationPK PRIMARY KEY (id))
2020-02-26 16:15:10.787 INFO 8064 --- [main] liquibase.changelog.ChangeSet : Table organisation created
2020-02-26 16:15:10.787 INFO 8064 --- [main] liquibase.changelog.ChangeSet : ChangeSet classpath:/db/changelog/db.changelog-master.xml::1582733383680-5::blabla (generated) ran successfully in 9ms
As you may have noticed, "generated as identity" is missing, which
makes me believe that for whatever reason, the autoIncrement="true"
is ignored.
I use Oracle 12.1.0.2 and org.liquibase:liquibase-core 3.8.2.
The OJDBC driver is version 19.3.0.0.
The gradle properties are:
spring.datasource.url=jdbc:oracle:thin:#//host:1522/SID
spring.datasource.driverClassName=oracle.jdbc.OracleDriver
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.datasource.username=user
spring.datasource.password=pass
spring.jpa.database-platform=org.hibernate.dialect.Oracle12cDialect
spring.jpa.show-sql=true
logging.level.org.hibernate.SQL=debug
logging.level.org.hibernate.type=trace
spring.datasource.continue-on-error=true
spring.datasource.platform=oracle
spring.liquibase.url=${spring.datasource.url}
spring.liquibase.user=${spring.datasource.username}
spring.liquibase.password=${spring.datasource.password}
spring.liquibase.url=${spring.datasource.url}
spring.liquibase.user=${spring.datasource.username}
spring.liquibase.password=${spring.datasource.password}
spring.liquibase.change-log=classpath:/db/changelog/db.changelog-master.xml
spring.liquibase.default-schema=${spring.jpa.properties.hibernate.default_schema}
spring.liquibase.liquibase-schema=${spring.jpa.properties.hibernate.default_schema}
I've read the Internet, and I know that my Oracle version is compatible with this column type and I don't need to create extra oracle Sequences.
Any clue what could be the problem?
It seems to be a bug in Liquibase. I just found it here https://liquibase.jira.com/projects/CORE/issues/CORE-3524?filter=allissues&orderby=updated%20DESC&keyword=Oracle
As it states, there is a work-around to add the
generationType="BY DEFAULT"
at each column definition, where autoIncrement="true" has been used.
Correct the autoIncrement="true" is ignored due to the missing support on Oracle side for auto incremented columns as seen in the docs from liquienter link description here:
Is column an auto-increment column. Ignored on databases that do not
support autoincrement/identity functionality.
You will need to create a sequence for generating the IDs and providing the sequence to the id column when inserting the data i.e. with hibernate:
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "XXX_ID_GEN")
#SequenceGenerator(name = "XXX_ID_GEN", sequenceName = "SEQ_XXX")
long id;

Parsing multiple columns from XMLTYPE

I want to select data from a XML file using Oracle SQL.
Here is my XML file:
<worksheet>
<sheetData>
<row>
<column>
<value>0</value>
</column>
<column>
<value>1</value>
</column>
<column>
<value>2</value>
</column>
</row>
<row>
<column>
<value>3</value>
</column>
<column>
<value>4</value>
</column>
<column>
<value>5</value>
</column>
</row>
<row>
<column>
<value>6</value>
</column>
<column>
<value>7</value>
</column>
<column>
<value>8</value>
</column>
</row>
</sheetData>
</worksheet>
The following code is the SQL I'm using to extract the XML (minified in SQL query):
SELECT
*
FROM
XMLTABLE(
'for $i in worksheet/sheetData/row return $i'
PASSING XMLTYPE('<worksheet><sheetData><row><column><value>0</value></column><column><value>1</value></column><column><value>2</value></column></row><row><column><value>3</value></column><column><value>4</value></column><column><value>5</value></column></row><row><column><value>6</value></column><column><value>7</value></column><column><value>8</value></column></row></sheetData></worksheet>')
COLUMNS
column1 CLOB PATH 'column[1]/value',
column2 CLOB PATH 'column[2]/value'
) xml;
And this is the output:
---------------------
| COLUMN1 | COLUMN2 |
|---------|---------|
| 0 | 1 |
| 3 | 4 |
| 6 | 7 |
---------------------
You can see that the third <column> child of <row> is missing from the output but if I add column3 CLOB PATH 'column[3]/value' to the COLUMNS property, it will appear.
My problem is that the XML can have any number of <column> tags and since I don't know the count from the beginning, I can't define a fixed solution.
Can you help to tell me which modification should make my query to work for multiple <column> tags? Or which query should output a dynamic number of <column>?
Easy ways
Predefined redundant amount of columns.
SELECT
*
FROM
XMLTABLE(
'/worksheet/sheetData/row'
PASSING XMLTYPE('<worksheet><sheetData><row><column><value>0</value></column><column><value>1</value></column><column><value>2</value></column></row><row><column><value>3</value></column><column><value>4</value></column><column><value>5</value></column></row><row><column><value>6</value></column><column><value>7</value></column><column><value>8</value></column></row></sheetData></worksheet>')
COLUMNS
column_cnt number path 'count(column)',
column1 varchar2(4000) PATH 'column[1]/value',
column2 varchar2(4000) PATH 'column[2]/value',
--etc. ...
column10 varchar2(4000) path 'column[10]/value'
) xml;
Pivot the result
SELECT
row_nr,
col_nr,
col_value
FROM
XMLTABLE(
'/worksheet/sheetData/row'
PASSING XMLTYPE('<worksheet><sheetData><row><column><value>0</value></column><column><value>1</value></column><column><value>2</value></column></row><row><column><value>3</value></column><column><value>4</value></column><column><value>5</value></column></row><row><column><value>6</value></column><column><value>7</value></column><column><value>8</value></column></row></sheetData></worksheet>')
COLUMNS
columns_xml xmltype path '.',
row_nr FOR ORDINALITY
) xml
,xmltable('row/column' passing columns_xml
columns
col_nr for ordinality,
col_value varchar2(10) path './value/text()')
Hardcore approach.
Alway you can use pipelined table function.
1) Find max count of columns
2) Generate dynamic type
3) Populate dynamic type
4) Two days later enjoy the most sophisticated code written in pl sql :)
Good example of pipelline function below. This is not exactly what you need but you can build on it
Return dynamic result set from sys_refcursor

Liquibase Different Datatypes H2/Oracle

So I do have the following changeset in my dbchangelog:
<changeSet id="04_04_2018" author="codeit">
<createTable tableName="BSP_TABELLE">
<column name="name" type="varchar(255)"/>
<column name="datum" type="datetime"/>
<column name="richtigfalsch" type="boolean"/>
<column name="blub" type="blob"/>
<column name="club" type="clob"/>
<column name="ganzzahl" type="int"/>
<column name="grosseganzzahl" type="bigint"/>
<column name="gleitkommazahl" type="decimal(17,5)"/>
</createTable>
</changeSet>
In H2 I do get what I expected like:
CREATE TABLE BSP_TABELLE
(
NAME VARCHAR(255),
DATUM TIMESTAMP,
RICHTIGFALSCH BOOLEAN,
BLUB BLOB,
CLUB CLOB,
GANZZAHL INTEGER,
GROSSEGANZZAHL BIGINT,
GLEITKOMMAZAHL DECIMAL(17, 5)
)
But in Oracle I do get:
CREATE TABLE BSP_TABELLE
(
NAME VARCHAR2(255),
DATUM TIMESTAMP(6),
RICHTIGFALSCH NUMBER(1),
BLUB BLOB,
CLUB CLOB,
GANZZAHL NUMBER,
GROSSEGANZZAHL NUMBER,
GLEITKOMMAZAHL NUMBER(17, 5)
)
And I expected:
CREATE TABLE BSP_TABELLE
(
NAME VARCHAR2(255),
DATUM TIMESTAMP(6),
RICHTIGFALSCH NUMBER(1),
BLUB BLOB,
CLUB CLOB,
GANZZAHL NUMBER(10),
GROSSEGANZZAHL NUMBER(19,0),
GLEITKOMMAZAHL NUMBER(17, 5)
)
How can I achieve it, that the DataType for Oracle will fit, without modifying the datatypes in H2?
I am currently loading the changelog from the java implementation at runtime like:
Connection connection = openDatabaseConnection();
Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connection));
String[] validatedLiquibaseChangelogs = validateLiquibaseChangelogs();
for (String validatedChangelog : validatedLiquibaseChangelogs) {
Liquibase liquibase = new liquibase.Liquibase(validatedChangelog, new FileSystemResourceAccessor(), database);
//Updaten der Datenbank
liquibase.update(new Contexts(), new LabelExpression());
}

Propel ORM: Query searches for table name in starting character in uppercase

I am using Propel ORM
<table name="tawcompanyresearch" idMethod="native" phpName="Tawcompanyresearch">
<column name="TawCompanyResearchID" phpName="Tawcompanyresearchid" type="INTEGER" primaryKey="true" autoIncrement="true" required="true"/>
This is the generator in my schema.xml. When I make a query it returns as
42S02 - SQLSTATE[42S02]: Base table or view not found: 1146 Table 'taw.Tawcompanyresearch' doesn't exist
Please note that the table name is in small letters but search result returns the first character of the table as capital.
Where can this value be changed? Please give me some insights of this error.
Thank You

How to get Oracle next sequence value in liqiibase 1.9.5 for insert

How to get Oracle next sequence value in liqiibase 1.9.5 for insert
<changeSet author="MIGRATE" id="070214010049877">
<insert tableName="MYTABLE">
<column name="ID" valueNumeric=" nextval( 'MYTABLE_SEQ' ) "/>
<column name="NUMBER" value="5"/>
</insert>
</changeSet>
it is trying to put the value of ID " nextval( 'MYTABLE_SEQ' )" in table so it gives error
With Liquibase 1.9.5, there is no support for finding the next sequence value with the <insert> tag. You will have to either drop back to using <sql> or use <modifySql> assuming that existed in 1.9.5.

Resources