Liquibase create/alter DB user - oracle

I want to create and alter DB user using Liquibase. Following are the SQL queries to do so for Oracle DB.
change password:
ALTER USER ADMIN IDENTIFIED BY ${user.password};
create user:
CREATE USER appuser IDENTIFIED BY ${user.password};
I want to make the password parameterized, but changelog Property Substitution is not available in SQL format.
I am choosing XML as the fallback option, but not able to convert above queries into Liquibase XML format. I need help in converting alter/create user queries into XML.

You can use the SQL tag inside XML changeset and write any SQL query withing the tag as follows:
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd">
<changeSet author="authorName" id="some-unique-id" dbms="${dbType}">
<sql endDelimiter=";" splitStatements="true" stripComments="true">
**My SQL query/ transactional logic goes here**
CREATE USER appuser IDENTIFIED BY ${user.password};
</sql>
</changeSet>
</databaseChangeLog>
and then you can use Liquibase changelog property substitution with the password value. Using SQL tag will allow you to execute any SQL query (ofcourse in proper syntax) without you having to worry about the XML syntax for liquibase changeset.
For more details on property substitution, have a look at my answer on this post

Related

Efficient way to export data.xml with correct order (table dependency) in Liquibase

What’s the most efficient way to insert data with a proper order? For example I have 2 tables:
create table Primary (dataset_id number, info varchar2(100) PRIMARY KEY dataset_id);
create table Foreign (dataset_id number, category varchar2(100) FOREIGN KEY dataset_id REFERENCES Primary(dataset_id))
Now I run liquibase data to generate data.xml for the insertion. However, when I deployed to the Oracle DB, I found the foreign key issue. Liquibase exported data.xml in the alphabetical order of tables so the data in Primary is executed after Foreign (since P is behind F).
Each time I have to manully copy and paste the data for Foreign below the Primary… Is there any efficient way to insert the data with the dependency order? In other words, alway insert Primary table at first.
I found some solutions from the Internet but all of them are out of date. Was it added as a new feature so that we can achieve via command directly? I don’t want to touch data.xml once it’s auto-exported. Thanks!
It is always necessary to inspect the XML changesets Liquibase generates. As you mention, Liquibase may end up generating changesets in the incorrect order and you will need to update generated changesets and reorder them so that they can be deployed in the correct order.
Why not export to different XML changelogs such that data for Primary tables goes into primary.xml and data for Foreign table goes into foreign.xml. Then you can use a master changelog to instruct Liquibase the order in which to deploy, e.g.,
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/pro/liquibase-pro-4.3.xsd">
<include file="primary.xml"/>
<include file="foreign.xml"/>
</databaseChangeLog>

Liquibase-generated SQL gives ORA-01735 error

I am running the following changeset on an Oracle 12 database (the latest official docker image). When the changeset is executed, I get a SQL error:
Error: ORA-01735: invalid ALTER TABLE option
[Failed SQL: ALTER TABLE TEST.LANGUAGE ADD CONSTRAINT SYS_C0010528 PRIMARY KEY (ID) USING INDEX TEST.SYS_C0010528]
I generated the changeset from an existing Oracle database schema using Liquibase tools, with minor alterations.
Does liquibase not support Oracle 12?
How do I configure liquibase to generate Oracle 12-compatible SQL?
Is this a settings issue, or a bug in Liquibase?
Details:
It looks like Oracle doesn't accept the qualifier for the index name in the USING INDEX statement. The following revised SQL seems to work as intended:
ALTER TABLE TEST.LANGUAGE ADD CONSTRAINT SYS_C0010528 PRIMARY KEY (ID) USING INDEX SYS_C0010528
Here is the changeset definition:
<changeSet author="rmorrise (generated)" id="1507039841670-7">
<preConditions onFail="MARK_RAN">
<not>
<primaryKeyExists tableName="LANGUAGE"/>
</not>
</preConditions>
<createIndex indexName="SYS_C0010528" tableName="LANGUAGE" unique="true">
<column name="ID"/>
</createIndex>
<addPrimaryKey columnNames="ID" constraintName="SYS_C0010528" forIndexName="SYS_C0010528" tableName="LANGUAGE"/>
</changeSet>
Update:
I fixed the <addPrimaryKey> entries by replacing them with <sql> tags, but I got the same error on <addUniqueConstraint> with forIndexName.
Here is the generated SQL to create the index. It appears to be created in the same schema.
CREATE UNIQUE INDEX TEST.UK46FCA532E38E4F92860631AA28CB ON TEST.MESSAGE_ROLE(TEMPLATE_ID, LABEL);
ALTER TABLE TEST.MESSAGE_ROLE ADD CONSTRAINT UK46FCA532E38E4F92860631AA28CB UNIQUE (TEMPLATE_ID, LABEL) USING INDEX TEST.UK46FCA532E38E4F92860631AA28CB;
To answer Alex's question about the use of system object names: The schema was originally generated by hbm2ddl and migrated to liquibase using generateChangelog.
A query to dba_objects confirms that the OWNER is TEST.
I had a similar problem and as I was reading this topic I see that we both named our schema "TEST".
I changed the schema's name and it worked immediatly.

Liquibase duplicate changeSet not failing as expected

So I have an Oracle database which I am updating in liquibase... in the process of testing my DB build system, I created a new change which is identical in content to an older change with a different ID. Both are adding a column with the same name, using SQL. I would expect the 2nd to fail, since it would attempt to create a column which already exists, but the liquibase command updateTestingRollback reports:
Liquibase 'updateTestingRollback' Successful
Any ideas what the potential cause may be?
<changeSet id="2" author="anonymous" failOnError="true">
<sql>ALTER TABLE person ADD (col_a VARCHAR(1));</sql>
<rollback>ALTER TABLE person DROP COLUMN col_a;</rollback>
</changeSet>
<changeSet id="3" author="anonymous" failOnError="true">
<sql>ALTER TABLE person ADD (col_a VARCHAR(1));</sql>
<rollback>ALTER TABLE person DROP COLUMN col_a;</rollback>
</changeSet>
You might try running with the --logLevel=debug flag added to make sure, but my guess is that oracle is not returning an error code when the sql for the second change is applied. if you use the <sql> tag rather than more specific change type tags (i.e. the <addColumn> tag), liquibase has a more difficult time detecting problems.

How to change the schema name using liquibase

I am using embedded database H2 which has default schema PUBLIC.
I want to have a schema XYZ as opposed to the default H2 schema. How can I change it using liquibase. I tried to create the very first changeset to create schema XYZ and added schemaName attribute to all the DDL statements henceforth to use the schemaName. But databasechangelog and databasechangeloglock are created in PUBLIC schema. How can specify the schema for those tables as well ?
Thank you in advance for your response.
Used INIT=CREATE SCHEMA IF NOT EXISTS TEST and specify 'defaultSchema' attribute to the 'schemaName' in the liquibase bean.

Schema name prefix issue in SQL query

I have WMADMIN schema. This schema is configured as connection credential in websphere datasource.
I have table in other schema/user OCS_JOBS. But the problem is my application looking for the table in WMADMIN schema.
It looks i need to prefix schemaname OCS_JOBS in SQL query to run them.
Is there any other way to run the SQL query the table which is in other user/schema without prefixing the other schema name
You can create a SYNONYM see it here: http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_7001.htm

Resources