liquibase subselect - how does one build the XML format? - liquibase

I would like to use a subselect in a in Liquibase. Does Liquibase support SubSelects other than embedded SQL (i.e. the sql tag) ? If so, can you point me to how to build something like a please?

I assume you mean doing a subselect in an insert or update or create tag.
You cannot use sub-selects in the createTable but you can use the valueComputed tags in and . For example:
<update tableName="person">
<column name="employees" valueComputed="(select count(*) from person where manager=person.id)"/>
</update>
NOTE: If you don't want to drop all the way down to a <sql> tag for commands not handled by the standard XML tags (like subselects in createTable) You can also use to introduce changes and additions to what liquibase can generate from the XML.

Related

Liquibase update values inserting single quotes

I'm trying to upgrade Liquibase from 3.3.1 to 3.10.3. Existing changesets are failing because varchar values being udpated are now inserting additional single quotes. Given the following statement in a changeset:
<update tableName="foo_table">
<column name="foo_id" type="VARCHAR(32)" value="'a'"/>
<where>bar_id REGEXP 'A'</where>
</update>
Liquibase seems to be adding additional single quotes in 3.10.3 so that values in the database are now stored with single quotes. Removing the single quotes from value in the changeset corrects the issue but will change the checksum on many of our changesets. I was wondering if there were any options available that will avoid us from needing to do that.
One option would be to create a new changelog (you can keep your old one, refer to both in order using includeAll in a master changelog). In the new changelog, you can just create your changes in sql.
This would allow you to write the change as sql exactly the way you want it, and liquibase would not have to render the sql based on xml.

Liquibase Single Precondition for multiple Changesets

I have a number of changesets that I would like to run if a specific condition exists. For example run changesets 1, 2, and 3 only if sqlCheck executed with the excepted results.
I can copy the precondition into each changeset. However it feels like there should be a more efficient way of doing this. As the number of changesets grows, the files have a lot of these duplicates.
The preConditions element directly under databaseChangeLog seems to only configure dbms and runAs.
Is there a way to define a single preCondition that will be used by multiple change sets?
Any help is appreciated.
Unfortunately this is not possible but sometimes you can avoid using preconditions when you declare a property tag instead. For example when you have preconditions for different databases like Oracle and SQL Server which have different data types like
number in Oracle and float in SQL Server, you can instead of using a precondition for each database use a propertytag:
<property dbms="oracle" name="DECIMALTYPE" value="NUMBER" />
<property dbms="mssql" name="DECIMALTYPE" value="FLOAT" />

SQL Queries with xPath Expressions for finding similar values

This uses oracle database to store the data using the XML type, I was wondering is there any way to do a query to output the name of the people of who are swimmer and teachers? probably alot easier than i think
<swimmer>
<swimmer name>John Goldrick</swimmer name>
<swimmer name>James John</swimmer name>
<teacher>
<teacher name>John Goldrick</teacher name>
</swimmer>
</teacher>

Liquibase : Error executing SQL SET DEFINE OFF

I'm using liquibase to execute oracle scripts. This oracle scripts, are executing merge into statements for oracle, this work fine, but the problem is that the data that I need to insert have strange characters, so in order to work we are using SET DEFINE OFF (at the beginning of the file) and SET DEFINE ON (at the end of the file) in order to avoid the errors.
But if I try to run the same script in liquiBase is not working and I get this error:
Liquibase Update Failed: Error executing SQL SET DEFINE OFF
My changelog looks like this:
<changeSet author="e-ballo" id="nopa_data_email" dbms="oracle" >
<sqlFile path="email/NOPA_ACTIVATE_SECURITY.sql" relativeToChangelogFile="true" splitStatements="true" stripComments="true" />
Anyone know how to avoid this problem ?
Thanks in advance
SET DEFINE is not SQL but a SQL*Plus command. SQL*Plus is an Oracle proprietary client, and most other clients (such as IDEs) don't recognise its commands.
The Liquibase forums suggest using CDATA as the best way to pass non-standard characters. Find out more.

How do I differentiate between databases when using e.g. sequence

I just started using Liquibase and stumpled upon the problem to differentiate between the capabilities of different databases.
We would like to support multiple databases (Oracle, MySQL, Derby - to name three).
The all have different capabilities. In specific Oracle supports sequences whereas MySQL and Derby do not.
When I let hibernate generate the DDL I can choose different dialects and it will consider these different capabilities and generate a Sequencer when using Oracle and use a plain table (for ID-generation) when using Derby or MySQL.
Now, I know I can constraint changesets by specifying 'oracle' in the dbms attribute. But then how can I do the plain table solution for the other databases? There does not seem to be a 'not oracle' attribute for dbms.
How does anyone else handle this? (I could not find anything about it on the liquibase pages nor on the forum.)
Try using a precondition on the changset. Boolean operations are supported.
For example
<preConditions onFail="CONTINUE">
<or>
<dbms type="oracle" />
<dbms type="mysql" />
</or>
</preConditions>
An alternative approach is to put all your sequences in a changlog file which you include in your main changelog, and then do something like this:
<changeSet
dbms="oracle,db2,db2i"
author="mccallim (generated)"
id="1419011907193-1"
>
<createSequence
schemaName="${main.schema}"
...
That changeset only gets executed for the DBMSs listed.