Liquibase adding default value and not null constraint - liquibase

I am bit new to Liquibase. I came across a scenario where in one changeSet it is trying to add a default value first and not null constraint next to that.
But problem over here is both <addDefaultValue/> and <addNotNullConstraint/> tags have a default value attributes so eventually I am ending up with an exception.
Below is the changeSet that I have,
<changeSet id="f3047816-2d48-4341-a4ce-deface083cea" author="MineStar" failOnError="true">
<preConditions onFailMessage="Ignored AlterColumn for REHANDLE of table LOCATION as column does not exist or already has a NOT NULL constraint." onFail="MARK_RAN">
<columnExists tableName="LOCATION" columnName="REHANDLE"/>
<ext:columnIsNullable tableName="LOCATION" columnName="REHANDLE"/>
</preConditions>
<comment>AHS-1373: AlterColumn LOCATION.REHANDLE - nullability changed from true to false - defaultValue changed from 'null' to '0'</comment>
<addDefaultValue columnName="REHANDLE" columnDataType="BOOLEAN" defaultValueNumeric="0" tableName="LOCATION"/>
<addNotNullConstraint columnName="REHANDLE" defaultNullValue="0" columnDataType="BOOLEAN" tableName="LOCATION"/>
</changeSet>
Here one more strange thing I could see is if I rearrange the order of adding default value and not null constraints tags I won't get any exception that is first adding not null constraint and then default value like below. But I should not do that as it effects checksum in database all that I can do is adding a new changeSet to resolve the exception.
<addNotNullConstraint columnName="REHANDLE" defaultNullValue="0" columnDataType="BOOLEAN" tableName="LOCATION"/>
<addDefaultValue columnName="REHANDLE" columnDataType="BOOLEAN" defaultValueNumeric="0" tableName="LOCATION"/>.

There is a difference between the defautlNullValue in addNotNullConstraint and defaultValueNumeric in addDefaultValue. Using addDefaultValue just sets a default value for future rows inserted into the column but defaultNullValue in addNotNullConstraint will cause liquibase to generate an additional SQL statement of update location set rehandle=0 where rehandle is null to change the value of already existing rows so that a null constraint can be added.
I would think either order would work fine, what exception were you seeing?

Related

Why is UPDATE statement not working in SQL code?

I am trying to update one row of the storeID column. When I do the first code below, it runs but will not affect any row. However, the bottom two are producing the following error " The UPDATE statement conflicted with the REFERENCE constraint "Products_FK". The conflict occurred in database "group7", table "dbo.Products", column 'storeID'."
Could anyone help? Thanks!
Table in SQL
UPDATE Store
SET storeID='E50'
WHERE storeID='D50'
AND storeID is Null;
UPDATE Store
SET storeID='E50'
WHERE storeID='D50'
UPDATE Store
SET storeID='E50'
WHERE storeName='A Plus Cables'
Above is the code that I have tried and nothing is being updated.
The first one can't possibly match any rows, because a single value can't equal two different things at the same time:
WHERE storeID='D50'
AND storeID is Null
So that one is kind of a moot point. You'd need to update the WHERE clause to target the record(s) you want to target.
For the latter two, the error is telling you what's wrong. You're trying to write this value to a column:
SET storeID='E50'
But the error is telling you:
That column is a foreign key to another table. (Products?)
The value you're writing isn't presentin that other table.
So your options are:
Use a value that is present in the other table.
Use NULL (and update the column to allow NULL if necessary).
Remove the foreign key constraint to that other table.

Add column to table with existing data in SQL Server

I have a table Rates with data in it and I need to add new column to the table however I get the error:
ALTER TABLE only allows columns to be added that can contain nulls, or have a DEFAULT definition specified, or the column being added is an identity or timestamp column, or alternatively if none of the previous conditions are satisfied the table must be empty to allow addition of this column. Column 'CreatedOn' cannot be added to non-empty table 'RateIncreases' because it does not satisfy these conditions
How can I do this, I have disabled prevent saving changes that required table re-creation
What part of the error do you not understand? When a column is added to an existing table, there are rows. The column is assigned to each of those rows. SQL Server has to give those rows a value. How does it do this?
It can assign the default value for the column.
It can assign NULL.
In your case, you have defined the column as NOT NULL but not provided a default value. Hence, the database does not know what to do, so it returns an error.
The simplest solution is to remove the NOT NULL constraint in the definition. Very close behind is assigning a default value.

Can I set not null clause in all columns without specifying not null clause?

Can I set not null clause in all columns without specifying not null clause at the time of creation?
Does a setting exist to configure this for the entire database or SQL Server instance?
For T-SQL: SET ANSI_NULL_DFLT_OFF {ON | OFF}
Alters the behavior of the session to override default nullability of new columns when the ANSI null default option for the database is true.
This setting only affects the nullability of new columns when the nullability of the column is not specified in the CREATE TABLE and ALTER TABLE statements. By default, when SET ANSI_NULL_DFLT_OFF is ON, new columns that are created by using the ALTER TABLE and CREATE TABLE statements are NOT NULL if the nullability status of the column is not explicitly specified. SET ANSI_NULL_DFLT_OFF does not affect columns that are created by using an explicit NULL or NOT NULL.

Liquibase Insert computed value with multiple ids

I am trying to insert values into a database. I think the SQL would look like this:
INSERT INTO `tb_config` (`name`, `value`, `description`, `unity_id`)
(SELECT 'new_rule', true, 'rule description', id FROM tb_unity );
However, I want to do it with Liquibase, using a changeset:
<changeSet author="Luis Sukys" id="1022" >
<insert tableName="tb_config">
<column name="name">new_rule</column>
<column name="value">false</column>
<column name="descricao">rule description</column>
<column name="unidade_id" valueComputed="SELECT id FROM tb_unity" />
</insert>
</changeSet>
I've seen the use of valueComputed but with a where clause.
The idea is that it includes one row in tb_config for each id in tb_unity.
I am actually getting a 'ValidationFailedException' from liquibase.
Any help?
I use Navicat with MySQL and when I run this code, it includes one new row int tb_config for each row in tb_unity. The field i use from tb_unity is 'id'.
If I have 05 unities in tb_unity, it must add 05 rows in tb_config, with same values, only change the unity's id.
If you try running that SQL using whatever SQL tool you use, you will see that the problem is that you do indeed need a where clause. Which row of tb_unity do you want to use the id from?

phpPgAdmin automatically creates null row during adding a column

I have a table, called "Route" (part of a production postgres database). Because of a missing column "arrival_time", I used the "Add column" function of phpPgAdmin. There, I added each important property (name, type). When I browse the column after it was created, there is automatically created a value:
arrival_time | count
--------------------
NULL | 9358
Because of this, I cannot set the constraint "NOT_NULL", but which is required. What is the reason for this automatically created value? And how can I avoid it or fix this issue?
This is not a phpPgAdmin issue. You must either add the new column with NULL (which is the default anyway), or add with NOT NULL constraint and a DEFAULT clause. If neither is present, PostgreSQL doesn't know what to do with existing rows.
When a column is added with ADD COLUMN, all existing rows in the table are initialized with the column's default value (NULL if no DEFAULT clause is specified). If there is no DEFAULT clause, this is merely a metadata change and does not require any immediate update of the table's data; the added NULL values are supplied on readout, instead.
If you already added the column, you can use a single UPDATE to set all existing rows to a starting value, f.ex.:
UPDATE table SET arrival_time = NOW();
After that, you can add a NOT NULL constraint to this column.