I want to add some data only on development database for test purposes.
To do so, I created a test_data.sql that is included using
<include file="./test_data.sql" relativeToChangelogFile="true"/>
The test_data.sql is formatted as follows:
--liquibase formatted sql
--changeset whiad-16453:testdata runOnChange:true failOnError:true endDelimiter:go stripComments:false
--preconditions onFail:HALT onError:HALT
--precondition-sql-check expectedResult:1 select case when db_name()='devdb' then 1 else 0 end
insert into...
I expected that the insert is only performed, when the select returns 1 (it is a Sybase SQL dialect and I executed the query both on Dev and Prod environment using Sybase Central and it return 0 or 1 as expected).
Nevertheless, Liquibase created a script including the inserts (using updateSQL commandline argument).
I alternatively tried to use the precondition right before the include file in the changelog:
<preConditions>
<sqlCheck expectedResult="1">select case when db_name()='devdb' then 1 else 0 end</sqlCheck>
</preConditions>
<include file="./test_data.sql" relativeToChangelogFile="true"/>
But also in this case the insert where perfomed.
I also tried to used a property that i use in the condition:
<changeLogPropertyDefined property="deploy_test_data" value="true"/>
But this also didn't had any effect.
What do I do wrong?
I used now the context for my purpose passing "contexts==!testdata" as parameter on prod.
Related
I have a change log file,part of which looks like:
<include file="ChangeSets/00_SessionAuth.xml"/>
<include file="ChangeSets/01_Legacy_Baseline_V197_ANB.xml" context="legacy"/>
<include file="ChangeSets/02_V198_ANB.xml" context="non-legacy"/>
The change set 01_Legacy_Baseline_V197_ANB.xml has 197 sql scripts included,which are part of legacy database.
The change set 02_V198_ANB.xml is defined as:
<?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"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<include file="ChangeSets/sql/Dummy_schema/V198_AddColumn.sql"/>
</databaseChangeLog>
When i run the Liquibase update with context as non legacy, i get the following error :
Unexpected error running Liquibase: DB2 SQL Error: SQLCODE=-104, SQLSTATE=42601, SQLERRMC=SET SCEHMA = Dummy_schema;;BEGIN-OF-STATEMENT;<space>, DRIVER=3.62.56 [Failed SQL: SET SCEHMA = Dummy_schema;
The SQL file itself is correct.
I think this is an issue related to end delimiter or splitStatements.
The SQL goes like this:
SET SCEHMA = Dummy_schema;
ALTER TABLE T1 ADD COLUMN C1 VARCHAR(35)
ADD COLUMN C2 INTEGER;
Call Sysproc.admin_cmd ('REORG TABLE dummy_schema.T1');
ALTER TABLE T2 ADD COLUMN CT1 INTEGER;
Call Sysproc.admin_cmd ('REORG TABLE dummy_schema.T2');
We are using DB2 V10.5.
Can someone also provide the list of attributes,we can use with tag.
Regards
I think your assertion that
the SQL file itself is correct
is incorrect. That is valid SQL if it was run through the db2 command line application, but it is not valid SQL to be sent through a JDBC query, which is what Liquibase does.
I am using liquibase 2.0.5 and my properties file looks like below
#liquibase.properties
url=jdbc:oracle:thin:#//localhost:1521/orcl
username=myschama
password=myschama
masterUsername=system
masterPassword=system
I want to use system user to create myschema user. Currently, I get the following error.
Unexpected error running Liquibase: Unknown parameter: 'masterUsername'
SEVERE 12/21/17 12:59 PM:liquibase: Unexpected error running Liquibase: Unknown parameter: 'masterUsername'
liquibase.exception.CommandLineParsingException: Unknown parameter: 'masterUsername'
at liquibase.integration.commandline.Main.parsePropertiesFile(Main.java:387)
at liquibase.integration.commandline.Main.main(Main.java:122)
Is it possible to have such custom values in the properties file
If you want to use it in your changeSets as property, e.g.
<changeSet ...>
<sql>
INSERT INTO myTab(some_column) VALUES ('${masterUsername}')
</sql>
</changeSet>
then try putting this into your liquibase.properties:
parameter.masterUsername=your_desired_value
As an alternative, you can pass these on the command line as Java properties, e.g.
liquibase update ... -DmasterUsername=your_desired_value
See http://www.liquibase.org/documentation/changelog_parameters.html and http://www.liquibase.org/documentation/command_line.html for details.
Following is a trigger:
CREATE OR REPLACE TRIGGER "CMDC"."USER_ROADS_UC"
BEFORE INSERT OR UPDATE OF
ASSOCIATED_PARENT_ROAD
ON USER_ROADS
REFERENCES NEW AS NEW
FOR EACH ROW BEGIN
:new.ASSOCIATED_PARENT_ROAD:=upper(:new.ASSOCIATED_PARENT_ROAD);
EXCEPTION
WHEN OTHERS THEN RETURN;
END;
/
ALTER TRIGGER "CMDC"."USER_ROADS_UC" ENABLE
The above runs perfectly in SQL Developer. However, when I get the following error when I run it using Ant:
[sql] Failed to execute: EXCEPTION WHEN OTHERS THEN RETURN
[sql] java.sql.SQLException: ORA-00900: invalid SQL statement
[sql] Failed to execute: END
[sql] java.sql.SQLException: ORA-00900: invalid SQL statement
[sql] Failed to execute: / ALTER TRIGGER "CMDC"."USER_ROADS_UC" ENABLE
[sql] java.sql.SQLException: ORA-00900: invalid SQL statement
I have already reviewed this question. However, I still couldn't modify the script to work with Ant.
Following is the ant target
<target name="create-db-schema" >
<echo message="############################################################"/>
<echo message="# Create Complete DB Schema #"/>
<echo message="############################################################"/>
<sql onerror="continue" classpathref="project.class.path" driver="${database.driverClassName}"
url="${database.url}" userid="${database.username}" password="${database.password}">
<path>
<fileset dir="${test.dbscripts.dir}/schema/">
<include name="*.sql"/>
</fileset>
</path>
</sql>
</target>
With ant sql tag I couldn't run both SQL and PL/SQL in the same script even though I tried in many ways.
But using an external library I could do this.I've used this library to do that dbmaintain
Add following to your build script.
<path id="dbmaintain-lib"><fileset dir="${dbmaintain.home}/lib"><include name="*.jar"/></fileset></path>
<taskdef resource="dbmaintain-anttasks.xml" classpathref="dbmaintain.lib"/>
<target name="update-db">
<updateDatabase scriptLocations="scripts" autoCreateDbMaintainScriptsTable="true">
<database driverClassName="oracle.jdbc.driver.OracleDriver" userName="user" password="pass" url="jdbc:oracle:thin:#//localhost:1521/XE" schemaNames="SCHEMA"/>
</updateDatabase>
</target>
And everthing works perfectly now without changes to sql scripts files to replace ';'.
Hope this'll help for somebody in need.
I don't have environment to test this solution. But for testing purpose you can try something like this.
<sql
driver="xxx"
url="xxx"
userid="xxx"
password="xxx"
delimiter="/"
delimitertype="row"
><![CDATA[
CREATE OR REPLACE TRIGGER "CMDC"."USER_ROADS_UC"
BEFORE INSERT OR UPDATE OF
ASSOCIATED_PARENT_ROAD
ON USER_ROADS
REFERENCES NEW AS NEW
FOR EACH ROW BEGIN
:new.ASSOCIATED_PARENT_ROAD:=upper(:new.ASSOCIATED_PARENT_ROAD);
EXCEPTION
WHEN OTHERS THEN RETURN;
END;
/
ALTER TRIGGER "CMDC"."USER_ROADS_UC" ENABLE
/
]]></sql>
Important ! Your delimiter now is "/" in new line without any surrounding whitespaces.
I've got a SQL Server CE table like so:
...and I'm trying to update its solitary record like so:
update workTables
set fileType = "INV"
Yet I get:
Why?
UPDATE
Please see a related question here
Here check Microsoft support for yor error.
http://support.microsoft.com/kb/825392
This is from the site:
SYMPTOMS:
When you run a query on a Microsoft SQL Server 2000 Windows CE Edition version 2.0 database, and the query has a column that contains one or more space characters, the query may not be successful. Additionally, you may receive the following error message:
FAILED: select <Column Name> from <Table Name>
Error: 0x80040e14 DB_E_ERRORSINCOMMAND
Native Error: (25503)
Description: The column name is not valid. [,,,Node name (if any),Column name,]
Interface defining error: IID_ICommand
Param. 0: 0
Param. 1: 0
Param. 2: 0
Param. 3:
Param. 4: col1
Param. 5:
RESOLUTION:
To resolve this problem, enclose the column name that contains spaces in quotation marks (" "), and then run the query. For example, you can run the following query, and the query results are displayed successfully:
SELECT "col1 " FROM testtable
Your query should be:
update [workTables]
set [fileType] = 'INV'
Note: single quotes ^^^^
to execute an .sql script file from ANT it works fine using the following task:
<sql
classpath="${oracle.jar}" driver="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:###{db.hostname}:#{db.port}:#{db.sid}"
userid="#{db.user}"
password="#{db.password}"
src="#{db.sql.script}" />
But if the .sql file not only contains pure SQL but also PL/SQL the task will fail. This could be solved by using the following snippet:
<sql
classpath="${oracle.jar}" driver="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:###{db.hostname}:#{db.port}:#{db.sid}"
userid="#{db.user}"
password="#{db.password}"
delimiter="/"
delimitertype="row"
src="#{db.sql.script}" />
But if my script contains both SQL and PL/SQL then neither ANT task will work. Another solution would be to use the "exec" task with "sqlplus":
<exec executable="sqlplus" failonerror="true" errorproperty="exit.status">
<arg value="${db.user}/${db.password}#${db.hostname}:${db.port}/${db.sid}"/>
<arg value="#${db.sql.script}"/>
</exec>
But unfortunately this task will never fail, hence the build returns always with "SUCCESSFUL" even though the sql script execution failed. The error property which I tried to set would not return any error code.
Any ideas/suggestions how to solve this problem?
Thanks,
Peter
Peter,
Add at the beginning of scripts
WHENEVER SQLERROR EXIT SQL.CODE;
Then sqlplus will exit with exit code != 0.
Pretty late, I guess - but I hope this will help someone:
In general, I think we should perfer using sql rather than exec executable="sqlplus" for many reasons, such as: in case we change DB provider, you don't spend reaources in a new process with sql, "STOPPING" will work as opposed to sqlplus.exe etc.
Anyway, here's a suggestion on how to let both PL/SQL & SQL in same script so that it will work:
myScript.sql:
<copy todir="...">
<fileset dir="...." includes="myScript.sql"/>
<filterchain>
<replaceregex byline="false" pattern=";" replace="{line.separator}/" flags="mg"/>
<replaceregex byline="false" pattern="/[\s]*/" replace=";${line.separator}/" flags="mg"/>
</filterchain>
</copy>
then give the result to:
<sql delimeter="/" src="myScript.sql"/>
explaination:
If you have regular sql commands:
drop table x;
select blah from blue where bli=blee;
They will be transformed to:
drop table x
/
select blah from blue where bli=blee
/
which is equivlant - and the sql command with "/" delimeter can handle them.
On the other hand,
BEGIN
blah
END;
/
will be transformed to:
BEGIN
blas
END/
/
and using the second regex - transformed back to
BEGIN
blas
END;
/
So everybody wins! Hurray!
Good luck.