I am using liquibase to create triggers for postgressql database. Below is the syntax which I use in liquibase
<?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.1.xsd">
<changeSet id="1" author="yc14ik1">
<createProcedure catalogName="cat" dbms="postgresql"
encoding="utf8" procedureName="UPDATE_LAST_ROW_CHG_TS()" relativeToChangelogFile="true" schemaName="sub">
CREATE OR REPLACE FUNCTION UPDATE_LAST_ROW_CHG_TS() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
NEW.LAST_ROW_CHG_TS = NOW();
RETURN NEW;
END;
$$;
</createProcedure>
<sql></sql>
</changeSet>
When this procedure is executed in Jenkins Job, I get this error
Unexpected error running Liquibase: ERROR: language "plpgsql" does not exist
Hint: Use CREATE LANGUAGE to load the language into the database. [Failed SQL: CREATE OR REPLACE FUNCTION UPDATE_LAST_ROW_CHG_TS() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
NEW.LAST_ROW_CHG_TS = NOW();
RETURN NEW;
END;
$$;]
Build step 'Execute shell' marked build as failure
Notifying upstream projects of job completion
Warning: you have no plugins providing access control for builds, so falling back to legacy behavior of permitting any downstream builds to be triggered
Can some one help me how can I fix this problem ?
I set up mine differently and it works just fine.
<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"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<changeSet author="l" id="UPDATE_LAST_ROW_CHG_TS" runOnChange="true">
<createProcedure catalogName="UPDATE_LAST_ROW_CHG_TS"
dbms="postgresql"
encoding="utf8"
path="../files/UPDATE_LAST_ROW_CHG_TS.sql"
procedureName="UPDATE_LAST_ROW_CHG_TS"
relativeToChangelogFile="true"
schemaName="public"></createProcedure>
</changeSet>
</databaseChangeLog>
from there you put all the sql inside a .sql file referenced in the path attribute.
I dont know that your way wont work but it seems odd to me that you have empty tags towards the bottom. Maybe you meant for those to wrap your sql function?
Anyways I know the example above will work if liquibase is configured and ran properly.
Related
I got this error while trying to run docker-compose up --build, I'm using postgresql as my database service. I think there's wrong with my query.When i remove the CREATE TRIGGER it somehow run without erros.
LINE 13: CREATE TRIGGER update_communication
backend-postgres-1 |^
Here is my sql file
CREATE OR REPLACE FUNCTION dts.save_communication_revision()
RETURNS TRIGGER
LANGUAGE PLPGSQL
AS
$$
BEGIN
INSERT INTO dts.communication_revisions(com_id, class_id, com_subject, user_id, com_source_name, "com_dateCreated", "com_dateReceived", com_urgency, com_source_position, com_source_office, com_draft, com_other_remarks, "com_controlNo", com_due_date)
VALUES(OLD.com_id, OLD.class_id, OLD.com_subject, OLD.user_id, OLD.com_source_name, OLD."com_dateCreated", OLD."com_dateReceived", OLD.com_urgency, OLD.com_source_position, OLD.com_source_office, OLD.com_draft, OLD.com_other_remarks, OLD."com_controlNo", OLD.com_due_date);
END;
$$
CREATE TRIGGER update_communication
AFTER UPDATE
ON dts.communications
FOR EACH ROW
EXECUTE PROCEDURE dts.save_communication_revision();
END;
$$;
Just added this semicolon.
I'm trying to upload a lot of data from a .sql file using the COPY command for Postgresql.
I have those data in a file.sql in the following format :
COPY my_table(id, name, status) FROM stdin;
1 peter active
1 steve active
1 maria active
\.
And my changeset like this:
<changeSet id="sqlFile-example" author="me" >
<sqlFile encoding="UTF-8"
path="file.sql"
relativeToChangelogFile="true"
endDelimiter=";"
splitStatements="false"
/>
</changeSet>
And get this error:
[ERROR] Failed to execute goal
org.liquibase:liquibase-maven-plugin:3.6.3:update (default-cli) on
project lincoln-soft: Error setting up or running Liquibase: Migration
failed for change set
src/main/resources/db/liquibase/db-changelog.xml::sqlFile-example::me
[ERROR] Reason: liquibase.exception.DatabaseException: ERROR: unexpected message type 0x50 during COPY from stdin
[ERROR] Where:
COPY my_table, line 1 [Failed SQL: COPY my_table(id, name, status)
FROM stdin;
[ERROR] 1 peter active
[ERROR] 1 steve active
[ERROR] 1 maria active
[ERROR] \.]
I there a way to upload those data by liquibase?
Finally got a solution, as #a_horse_with_no_name and #Laurenz Albe
mentioned, can't use COPY FROM STDIN directly in JDBC, so I used pg_dump to generate insert statements like this:
pg_dump --table=public.my_table --data-only --column-inserts my_databse > /tmp/my_table_data.sql
It gives me a file my_table_data.sql with the inserts statements like this:
INSERT INTO public.my_table (id, name, status) VALUES (1,peter,active);
INSERT INTO public.my_table (id, name, status) VALUES (1,peter,active);
INSERT INTO public.my_table (id, name, status) VALUES (1,peter,active);
And then I use this liquibase Chageset to upload the sql file:
<changeSet id="sqlFile-example" author="me" >
<sqlFile encoding="UTF-8"
path="my_table_data.sql"
relativeToChangelogFile="true"
splitStatements="true"
stripComments="true"
/>
</changeSet>
It works for me
As Laurenz already mentioned: you can't use COPY FROM STDIN directly in JDBC (you can use the CopyManager API to implement that manually, but Liquibase doesn't support that and I also don't know of any plugin that would do that)
I would suggest you use Liquibase's built-in ability to load CSV (text) files. Put your input data in CSV file, e.g. my_table_data.txt with a header line for the columns:
id,name,status
1,peter,active
1,steve,active
1,maria,active
Then use <loadData> instead of running a SQL script:
<changeSet id="sqlFile-example" author="me" >
<loadData tableName="my_table"
file="my_table_data.txt"
separator=","
encoding="UTF-8">
</changeSet>
Mixing the COPY statement and the data in the same file only works in psql scripts.
Moreover, COPY FROM STDIN is not supported by the JDBC driver at all.
You should use INSERT statements in your script.
I would like to create or replace a view on DB2 using liquibase and its changeSet tag: XML Sample
This is what I include in the changelog.xml file:
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
logicalFilePath="lon-service-mpd/gin/15.100/15.100.0.0.changelog.xml"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet author="mas-gin-gestion-echelon-service" id="create-view-from-table-periodeavancement-type-personnel">
<createView schemaName="GIN" viewName="V_PERIODEAVANCEMENT_1">select IDPERIODE, CAMPAGNETA from GIN.PERIODEAVANCEMENT</createView>
</changeSet>
</databaseChangeLog>
However, during the creation of the view, DB2 returns the following error liquibase.exception.DatabaseException: DB2 SQL Error: SQLCODE=-206, SQLSTATE=42703
I do not find the way to fix the problem, even if the SQL syntax is correct.
I have fixed the problem by calling directly a sql file instead of using the XML sample. Here is my solution:
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
logicalFilePath="mas-gin-gestion-echelon-service-mpd/gin/15.100/15.100.0.0.changelog.xml"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet id="create_view_periodeavancement" author="mas-gin-gestion-echelon-service">
<sqlFile path="sql/create_view_periodeavancement.sql" relativeToChangelogFile="true"/>
</changeSet>
And the sql file:
CREATE OR REPLACE VIEW GIN.V_PERIODEAVANCEMENT_1 (IDPERIODE, TS_INSERT, BL_DELETE )
AS SELECT IDPERIODE, TS_INSERT, BL_DELETE
FROM PERIODEAVANCEMENT;
I am trying to build View PostgreSQL table in Liquibase for my JHipster application. Therefore, I have tried createView and sqlFile methods.
My query has date_trunc() function as following:
CREATE OR REPLACE VIEW periodical_statistics AS
SELECT tran.id, date_trunc('day', tran.pub_date) as, ...
FROM transaction tran
...(LEFT JOINS - not relative)...
WHERE ...(condtions - not relative)...
When I run my JHispster app as Dev Mode in maven(./mvnw). It is working ver fine.
But when I run it as Prod Mode in maven(./mvnw -Pprod package). It gives following error.
20180817101122-1::liquibase-docs failed. Error: Function "DATE_TRUNC" not found;
SQL statement: CREATE OR REPLACE VIEW periodical_statistics AS ....
is there are any way to solve this error problem?
After adding dbms='postgresql' to the changeset. Liquibase recognized the 'date_trunc' function. It is as following:
<changeSet author="sanatbek" id="20180904094713" dbms="postgresql">
<createView replaceIfExists="true"
schemaName="public"
viewName="periodical_statistics">
SELECT
tran.id
date_trunc('day', tran.pub_date) as truncated_date,
....
...(LEFT JOINS - not relative)...
WHERE ...(condtions - not relative)...
</createView>
</changeSet>
I'm using the dropwizard-migrations module for liquibase db refactoring. See the guide here: http://dropwizard.codahale.com/manual/migrations/
When I run
java -jar my_project.jar db migrate my_project.yml
I get the following error:
ERROR [2013-09-11 20:53:43,089] liquibase: Change Set migrations.xml::11::me failed. Error: Error executing SQL CREATE OR REPLACE TRIGGER add_current_date_to_my_table BEFORE UPDATE ON my_table FOR EACH ROW EXECUTE PROCEDURE change_update_time();: ERROR: syntax error at or near "TRIGGER"
Position: 19
Here are some relevant changesets from my migrations.xml file:
<changeSet id="1" author="me">
<createProcedure>
CREATE OR REPLACE FUNCTION change_update_time() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
NEW.updated_at := CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$;
</createProcedure>
<rollback>
DROP FUNCTION change_update_time();
</rollback>
</changeSet>
<changeSet id="2" author="me">
<preConditions>
<not>
<tableExists tableName="my_table"/>
</not>
</preConditions>
<createTable tableName="my_table">
<column name="_id" type="integer" defaultValue="0">
<constraints nullable="false"/>
</column>
<column name="updated_at" type="timestamp without time zone" defaultValue="now()">
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>
<changeSet id="3" author="me">
<sql splitStatements="false">
CREATE OR REPLACE TRIGGER add_current_date_to_my_table BEFORE UPDATE ON my_table FOR EACH ROW EXECUTE PROCEDURE change_update_time();
</sql>
<rollback>
DROP TRIGGER add_current_date_to_my_table ON my_table;
</rollback>
</changeSet>
Is there any way I can create the trigger add_current_date_to_my_table? Is this redundant with the "RETURNS trigger" from creating the function?
The solution is:
<changeSet id="3" author="me">
<sql>
DROP TRIGGER IF EXISTS add_current_date_to_my_table ON my_table;
CREATE TRIGGER add_current_date_to_my_table BEFORE UPDATE ON my_table FOR EACH ROW EXECUTE PROCEDURE change_update_time();
</sql>
<rollback>
DROP TRIGGER add_current_date_to_my_table ON my_table;
</rollback>
</changeSet>
H/T Jens.
Ann Kilzer has provided the right answer as there is no CREATE OR REPLACE statement in Postgres, unlike PL/SQL.
So we need to split this statement into 2 atomic operations:
DROP TRIGGER
CREATE TRIGGER