Liquibase 'addCheckConstraint' for ENUM colum in Oracle DB allows any character - oracle

I have a ENUM column and I am using liquibase addCheckConstraint to allow only ENUM values. However, addCheckConstraint doesnt work and allows any value. My yaml changelog looks as follows:
- changeSet:
id: 1565352995028-1
author: Zafrullah Syed
changes:
- createTable:
columns:
- column:
constraints:
primaryKey: true
name: ID
type: NUMBER(19, 0)
- column:
name: STATUS_ENUM
type: VARCHAR2(10 CHAR)
tableName: BOOKING
- addCheckConstraint:
constraintBody: STATUS_ENUM IN ('ERROR', 'CONFIRMED', 'QUEUED', 'REJECTED')
constraintName: enumcheck
tableName: SOME_TABLE
I am Using Oracle db.
If I try to run a sql query, then constraint works well:
ALTER TABLE SOME_TABLE
ADD CONSTRAINT enumcheck CHECK (status_enum IN ('ERROR', 'CONFIRMED', 'QUEUED', 'REJECTED'));
I tried to add another enableCheckConstraint to enable the existing check constraint but nothing seems to work.

addCheckConstraint is accessible only for the pro version, do you have it?

Related

how to fix liquibase can not create index on oracle

databaseChangeLog:
- preConditions:
- changeSet:
id: 8
author: myname
context: context
changes:
- createIndex:
tableName: table_name
indexname: index_name
columns:
- column:
name: column_1
Get an error:
DatabaseException: ORA-00953: missing or invalid index name
[Failed SQL: CREATE INDEX ON SYSTEM.CABLEMODEMTERMINATIONSYSTEM(KMA_ID)]
The problem is indexname, it should be indexName (upper-case N).

How to add a composite foreign key in liquibase?

I've been struggling for some time now to figure out a way to create a composite foreign key in liquibase.
I have a table A which has a composite PK, let's say (id1, id2). I'm trying to make another table B, in which the A.PK is mapped as a FK.
I'm using liquibase with YAML and something doesn't seem to add up.
I've tried adding the FK when creating the table (so in the column tag)
- column:
name: id1_id2
type: int
constraints:
nullable: false
foreignKeyName: fk_id1_id2
references: A(id1, id2)
Unfortunately this syntax returns an error:
Caused by: java.sql.SQLSyntaxErrorException: ORA-02256: number of referencing columns must match referenced columns
Another thing that I've tried is creating the table first, with the column for the desired FK and try to add a FK constraint on that column. This doesn't throw any error but it does nothing (also the log for LB says "empty" in the description)
changes:
- addForeignKeyContraint:
baseColumnNames: id1, id2
baseTableName: B
constraintName: fb_id1_id2
referencedColumnNames: id1, id2
referencedTableName: A
Any help would be much appreciated.
Thanks
Have you tried addForeignKeyConstraint? Something like this:
- changeSet:
id: 1
author: you
changes:
- addForeignKeyConstraint:
baseColumnNames: id1, id2
baseTableName: tableB
constraintName: FK_tableB_tableA
referencedColumnNames: id1, id2
referencedTableName: tableA
I don't use Liquibase, but here's how it is supposed to look like, as far as Oracle is concerned: if you want to create a composite foreign key (in the detail table), then it has to reference a composite primary key (in the master table).
Have a look at this example:
SQL> create table master
2 (id_1 number,
3 id_2 number,
4 constraint pk_mas primary key (id_1, id_2));
Table created.
SQL> create table detail
2 (id_det number constraint pk_det primary key,
3 --
4 id_1 number,
5 id_2 number,
6 constraint fk_det_mas foreign key (id_1, id_2) references master (id_1, id_2));
Table created.
SQL>
It just wouldn't work otherwise; that's why you got the error
ORA-02256: number of referencing columns must match referenced columns
because your detail table contained a single column (id1_id2) and tried to reference two columns in table A (id1, id2).

Composite Primary Key (Sqlite.Swift)

How can I create a table with a composite primary key with this library. For example:
CREATE TABLE something (
column1,
column2,
column3,
PRIMARY KEY (column1, column2)
);
The only example I see in the documentation is a primary key on single column:
try db.run(users.create { t in
t.column(id, primaryKey: true)
t.column(email, unique: true)
t.column(name)
})
I tried the following but fails with an error (...table "" has more than one primary key) :
try db.run(tblTsMosStaged.create { t in
t.column(colTsMosStagedEventId, primaryKey: true)
t.column(colTsMosStagedEventInstance, primaryKey: true)
t.column(colTsMosStagedTaxId, primaryKey: true)
t.column(colTsMosStagedRankId)
...
Or is this only possible via Executing Arbitrary SQL
The SQLite.swift documentation says:
Table Constraints
Additional constraints may be provided outside the scope of a single column using the following functions.
primaryKey adds a PRIMARY KEY constraint to the table. Unlike the column constraint, above, it supports all SQLite types, ascending and descending orders, and composite (multiple column) keys.
t.primaryKey(email.asc, name)
// PRIMARY KEY("email" ASC, "name")
try db.run(tblTsMosStaged.create { t in
t.column(colTsMosStagedEventId)
t.column(colTsMosStagedEventInstance)
t.column(colTsMosStagedTaxId)
t.column(colTsMosStagedRankId)
//ADD this line
t.primaryKey(colTsMosStagedEventId, colTsMosStagedEventInstance, colTsMosStagedTaxId)

SQLite claims duplicate rows on insert whereas none can be found

I have a table in a SQLite database created with the code below. Note the compound primary key:
db.create_table(:person_hash) do
Integer :person_id
Bignum :hash // MD5 hash in hex stored as numeric: hash.to_i(16)
primary_key [:person_id, :hash]
end
This table has some rows already:
puts db[:person_hash].where(:person_id => 285577).all
# {:person_id=>285577, :hash=>306607097659338192312932577746542919680}
Now, when I try to insert this:
db[:person_hash].insert({:person_id=>285577, :hash=>306607097659338206333361532286405644297})
I get this:
SQLite3::ConstraintException: columns person_id, hash are not unique (Sequel::DatabaseError)
If the row does not already exist in the table, how can it be a duplicate?
I tried inserting another hash for the same person ID instead, and it worked without problems.
This appears to be a bug in SQLite:
$ sqlite3
SQLite version 3.8.9 OpenBSD
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> CREATE TABLE person_hash (person_id integer, hash bigint, primary key (person_id, hash));
sqlite> INSERT INTO person_hash VALUES (285577, 306607097659338192312932577746542919680);
sqlite> INSERT INTO person_hash VALUES (285577, 306607097659338206333361532286405644297);
Error: UNIQUE constraint failed: person_hash.person_id, person_hash.hash

Validation of Unique Entity

I have an account entity which contains a foreign key constraint for a user entity and customer entity.
I'm trying to validate the customer id is numeric and not null. Plus the unique constraint of user_id and customer_id.
My problem the Class Constraint UniqueEntity gets fired regardless of the outcome of the customer_id type: numeric validation result. Which throws a 500 because the customer_id column is an integer.
What I need to do is, validate the customer_id is a valid id (numeric and not null) before checking the unique constraint. Or is there any other way to avoid symfony/doctrine going to the db to test an invalid id?
My validation config,
MY\ApplicationBundle\Entity\Account:
constraints:
- Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity:
fields: [ user_id, customer_id ]
message: Customer Id already exists for User
properties:
customer_id:
- Type:
type: numeric
message: Customer Id should be an integer.
- NotBlank:
message: Customer cannot be blank.
Group Sequences should solve your problem here. Something like that should work:
MY\ApplicationBundle\Entity\Account:
group_sequence:
- Basic
- Account
constraints:
- Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity:
fields: [ user_id, customer_id ]
message: Customer Id already exists for User
properties:
customer_id:
- Type:
type: numeric
message: Customer Id should be an integer.
groups: [Basic]
- NotBlank:
message: Customer cannot be blank.
groups: [Basic]
With group sequences you can define the order of your validations. Basic checks all constraints with the group Basic and Account cheks the other constraints for this entity.

Resources