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

loading

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

loading

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

loading

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>