Generate SQL to update database schemas
Last updated: September 2, 2025
There are two reasons you would want to generate SQL in Liquibase.
1. You need to know exactly what is being done to your database. 2. Your company policies prevent you from using Liquibase in certain environments.
Generating SQL can be helpful when you want to update your database schemas, but want to view those database changes before applying them. There are several commands that generate deployable SQL, these are:
update-sql command
Running the update-sql command tells Liquibase to evaluate all the changesets in your changelog, then generates the corresponding SQL for what will be deployed to the database so you can preview the changes.
To use the update-sql command, type the following into your command prompt:
liquibase update-sql --changelog-file=changelog.xml
update-sql command with the labels parameter
Theupdate-sqlcommand allows you to also run a--labelsparameter to determine which changesets in the changelog to evaluate based on its label. You can view your labels in your changelog.
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<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:secure="http://www.liquibase.org/xml/ns/secure"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.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/secure
http://www.liquibase.org/xml/ns/secure/liquibase-secure-latest.xsd">
<!-- SETUP: Create tables and function for other objects to use. -->
<changeSet author="Liquibase Secure User" id="1::createTableforSynonym-proschema" labels="setup" objectQuotingStrategy="QUOTE_ALL_OBJECTS">
<createTable schemaName="proschema" tableName="primary_table">
<column name="name" type="CHAR(20)"/>
</createTable>
</changeSet>
<changeSet author="Liquibase Secure User" id="2::createTableforView-proschema" labels="setup" objectQuotingStrategy="QUOTE_ALL_OBJECTS">
<createTable schemaName="proschema" tableName="account">
<column name="acct_num" type="NUMBER(20,0)"/>
<column name="amoount" type="NUMBER(10,2)"/>
</createTable>
</changeSet>
<changeSet author="Liquibase Secure User" id="3::createTableforCC-proschema" labels="setup" objectQuotingStrategy="QUOTE_ALL_OBJECTS">
<createTable schemaName="proschema" tableName="suppliers">
<column name="supplier_id" type="NUMBER(4, 0)"/>
<column name="supplier_name" type="VARCHAR2(50 BYTE)"/>
</createTable>
</changeSet>
<changeSet author="Liquibase Secure User" id="4::functionForTrigger" objectQuotingStrategy="QUOTE_ALL_OBJECTS" labels="setup">
<secure:createFunction path="sql/postgres_setup_function.sql" functionName="canned_spam" schemaName="proschema"/>
<rollback>
<sqlFile endDelimiter=";" path="sql/postgres_setup_rollback.sql" splitStatements="true" stripComments="true"/>
</rollback>
</changeSet>
<!--SYNONYM - Not supported in Postgres Community -->
<!-- VIEW -->
<!-- Views are not coming from the Secure extension, but exist in Community, and we should validate view changes work after our changes. -->
<changeSet author="Liquibase Secure User" id="1::createView-PROSCHEMA" objectQuotingStrategy="QUOTE_ALL_OBJECTS" labels="createView,lbl-view">
<createView fullDefinition="true" path="sql/postgres_master_view.sql" schemaName="proschema" viewName="view1"/>
</changeSet>
<changeSet author="Liquibase Secure User" id="2::dropView-proschema" labels="dropView,lbl-view">
<dropView viewName="view1" schemaName="proschema"/>
</changeSet>
<!-- PROCEDURE -->
<!-- Procedures are not coming from the Secure extension, but exist in Community, and we should validate procedure changes work after our changes. -->
<changeSet author="Liquibase Secure User" id="1::createProc-proschema" objectQuotingStrategy="QUOTE_ALL_OBJECTS" labels="createProcedure,lbl-proc">
<createProcedure path="sql/postgres_master_proc.sql" procedureName="simple_proc" schemaName="proschema"/>
</changeSet>
<changeSet author="Liquibase Secure User" id="2::dropProc-proschema" labels="dropProcedure,lbl-proc">
<dropProcedure procedureName="simple_proc" schemaName="proschema"/>
</changeSet>
<!-- FUNCTION -->
<changeSet author="Liquibase Secure User" id="1::createFunction-proschema" objectQuotingStrategy="QUOTE_ALL_OBJECTS" labels="createFunction,rollbackFunction, lbl-func">
<secure:createFunction functionName="last_updated" path="sql/postgres_master_function.sql" schemaName="proschema"/>
<rollback>
<sqlFile endDelimiter=";" path="sql/postgres_master_rollback.sql" splitStatements="true" stripComments="true"/>
</rollback>
</changeSet>
<changeSet author="Liquibase Secure User" id="2::dropFunc-proschema" labels="dropFunction,lbl-func">
<secure:dropFunction functionName="last_updated" schemaName="proschema"/>
</changeSet>
<!-- TRIGGER -->
<changeSet author="Liquibase Secure User" id="1::addTrigger-proschema" objectQuotingStrategy="QUOTE_ALL_OBJECTS" labels="createTrigger,lbl-trg">
<secure:createTrigger disabled="false" path="sql/postgres_master_trigger.sql" schemaName="proschema" tableName="primary_table" triggerName="dinner_time"/>
</changeSet>
<changeSet author="Liquibase Secure User" id="2::disableTrigger-proschema" labels="disableTrigger,lbl-trig">
<secure:disableTrigger triggerName="dinner_time" tableName="primary_table" schemaName="proschema"/>
</changeSet>
<changeSet author="Liquibase Secure User" id="3::enableTrigger-proschema" labels="enableTrigger,lbl-trig">
<secure:enableTrigger triggerName="dinner_time" tableName="primary_table" schemaName="proschema"/>
</changeSet>
<changeSet author="Liquibase Secure User" id="4::renameTrigger-proschema" labels="renameTrigger,lbl-trg">
<secure:renameTrigger oldTriggerName="dinner_time" newTriggerName="midnight_snack" tableName="primary_table" schemaName="proschema"/>
</changeSet>
<changeSet author="Liquibase Secure User" id="5::dropTrigger-proschema" labels="dropTrigger,lbl-trg">
<secure:dropTrigger triggerName="midnight_snack" schemaName="proschema" tableName="primary_table"/>
</changeSet>
<!-- CHECK CONSTRAINT -->
<!-- disable/enableCheckConstraint are not supported on Postgres. -->
<changeSet author="Liquibase Secure User" id="1::addCC-proschema" objectQuotingStrategy="QUOTE_ALL_OBJECTS" labels="addCheckConstraint,lbl-cc">
<secure:addCheckConstraint constraintName="check_supplier_id" schemaName="proschema" disabled="false" tableName="suppliers">supplier_id BETWEEN 100 and 9999</secure:addCheckConstraint>
</changeSet>
<changeSet author="Liquibase Secure User" id="4::dropCC-PROSCHEMA" labels="dropCheckConstraint,lbl-cc">
<secure:dropCheckConstraint constraintName="check_supplier_id" tableName="suppliers" schemaName="proschema"/>
</changeSet>
</databaseChangeLog>To use the update-sql command with the labels parameter, type the following into your command prompt:
liquibase update-sql --changelog-file=changelog.xml --output-file=update-sql.txt --labelFilter=setup
future-rollback-sql command
Thefuture-rollback-sqlcommand generates SQL that reverses changes you applied while using theupdate-sqlcommand.
To run thefuture-rollback-sqlcommand, type the following into your command prompt:
liquibase future-rollback-sql --changelog-file=changelog.xml
Note for Liquibase Secure Users
Liquibase Secure allows users to also produce deployable SQL for Stored Logic. If you are a Liquibase Secure user, and you are trying to run thefuture-rollback-sqlcommand, make sure you add a<rollback>tag to your changesets so you output the correct SQL, as:
<changeSet author="Liquibase Secure User" id="1::createFunction-proCatalog" objectQuotingStrategy="QUOTE_ALL_OBJECTS" labels="createFunction,rollbackFunction, lbl-func">
<secure:createFunction functionName="emailFunction" path="sql/lbpro_master_func.sql" schemaName="dbo"/>
<rollback>
<sqlFile endDelimiter="GO" path="sql/lbpro_master_func_rollback.sql" splitStatements="true" stripComments="true"/>
</rollback>
</changeSet>