Default value or NULL in Room database entity - android-room

I'm trying to understand Room database library. I am struck with a scenario where two tables are linked via #ForeignKey constraint. What I need is, when the parent row is deleted, all the child columns in the child table should be set to NULL or some default value. But when I tried to use
onDelete=SET_NULL or SET_DEFAULT with #ForeignKey
I get the following error:
android.database.sqlite.SQLiteConstraintException: NOT NULL constraint
failed: Log.tagId
From the error I can see that the child column has been set as NOT NULL during the table definition, can someone say how to change it to be NULLABLE since room creates the tables for us? Also, it is ok if we can set a standard default value on the columns. If so, how to set the default value of columns? I think there should be some way else the constants SET_NULL or SET_DEFAULT has no meaning and purpose.
Thanks in advance!

Related

Adding a boolean coulmn into existing table of oracle database

I am using oracle database and I have a table named MyTitle and into this existing table I have to add a column of type boolean so the name of the column is IsChecked and the default value should be false of that column, I have tried the below way please advise is it correct or not
alter Table MyTitle add IsChecked Number(1) default 0 not null ;
It looks reasonable. Do you have a problem with it? Different people/ systems have different conventions for pseudo-boolean columns. Some use a number with 0 and 1. Some use a char(1) with a 'Y' and 'N'. Be consistent with whatever convention exists in your system.
I'd normally include a check constraint that limits the values in the column to the values you want, i.e.
check( isChecked in (0,1) )
If you're building a data warehouse, though, there are schools of thought that including check constraints like this is unnecessary overhead since there is (or should be) only a very small number of paths (ideally one) to load the data via the ETL process so you merely need to ensure that the ETL process isn't inserting invalid values.

ORACLE: How to alter table defaults with existing NULL values

I have a nullable column with null values and I want to add a default constraint for only new inserts into the table.
My alter code:
alter table customer_02
modify reference default on null
'No References';
I keep getting error ORA-02296 meaning, I have null values pre-existing in the table so I cant enable my new default. How can I insert the default for only new inserts and not affect the previous data?
Run
Update customer_02 set reference = 'No references' where reference is null
First
The entire column has to comply with the constraint; you can't have the old data remain null and then install a "not null" rule. You're saying it's ok for the references column to contain "no references" where it once contained null (meaning "no reference") so there shouldn't be any harm in updating those old null values so they're consistent with the new rule, then you can implement the new rule
If you desperately want to have old rows remain null while new rows cannot be null you'll need to use a (before insert) trigger that throws an error if the :new.reference column is null, and leave the column as nullable. I would avoid this for two reasons, one that it uses triggers and they're usually a bad way to get things done and two because it establishes a seemingly needless inconsistency that would puzzle future developers. As mentioned before, if null has fallen out of favour as the way to indicate there are no references, the old data should be adjusted. Keeping it null might also leave to errors elsewhere, if the front end expects a value - you might end up with your users experiencing crashes when they call up old records.
I'd recommend to always strive for consistency in data modelling, even if it means adjusting old data

session item does not change when using lov in primary key

I am implementing a Interactive grid to perform DML operations on a table.
it has combined primary key of two columns
One primary key column is display only and refer to master table and another primary key column I want to have a LOV to select value. LOV is dynamic lov having a display and return value picked from another table.
Inserts are fine but session state item value is set for one row and all the operations are performed on that same row irrespective of which row is selected.
you can see a sample here
https://apex.oracle.com/pls/apex/f?p=128616:2:1964277347439::NO:::
master table name: sample
detail table name: sample_child
primary key in sample child : ID and Name
pop lov is implemented in NAME
LOV values are picked from table: Sample_uncle
LOV display : ID || '-' || NAME
LOV return : ID
you can try to update blabla column of sample_child table to see the issue.
I am not sure how I can give you access to look at the implementation.
I have already tried all the options I can think of
This is to do with your primary keys, the detail table does not appear to have proper ones, thats why it always tried to update the first entry, and I think this is also why every row is marked when you load the table.
Primary keys also do the annoying thing of refusing to be empty, as you can see if you insert a new row, the middle column(which is a PK) is filled with 't1001'.
Since you are dealing with simple tables(and not a whole bunch of joined tables) I always consider it best to use ROWID as PK. So set ROWID as PK for the master table, and ROWID for the detail table. And have the detail table have a Master table be your master table, and then click on the first column in the detail table and set the master column for it. And I also personaly always hide the column that is linked.
I would advise you use ROWID whenever possible as its just so much easier to work with, it does mean you might need to set up a validation to prevent someone adding duplicated values for your actual PK, but since the PK is in the underlying table, they cant enter it anyways(but if you have a validation, the error will be much prettier), whilst if the column is a PK, APEX will prevent duplicates by default.
I hope this helps

ORA-00001 in UPDATE statement without duplicate

I fail to understand the logic of the unique constraint when it's based on 2 fields.
I have the following table named DESCRIPTIONS including 3 columns: ID_DESCRIPTION, NAME, ID_DESCRIPTION_TYPE
Now ID_DESCRIPTION is the primary key, and there is a unique constraint UK_DESCRIPTION on couple (ID_DESCRIPTION, NAME).
If I try to run the following query:
UPDATE DESCRIPTIONS SET NAME = 'USA' WHERE ID_DESCRIPTION = 9255813
I'm getting an ORA-00001 exception, saying that unique constraint UK_DESCRIPTION is violated.
Now this would mean that the couple (9255813,'USA') already exists right ?
However, I don't see how this is possible since the ID_DESCRIPTION is a primary key and therefore unique AND the results of the query
SELECT * FROM DESCRIPTIONS WHERE ID_DESCRIPTION = 9255813
only return 1 result, the one I want to update.
What am I failing to understand here ?
I am going to guess that uk_description is in fact a unique key based on the single column of NAME.
"It is unfortunately not."
Okay, the other explanation is that it is a multi-column key based on a different set of columns from what you think. (NAME, ID_DESCRIPTION_TYPE) would also fit the described behaviour.
To be fair, a unique key on(NAME, ID_DESCRIPTION_TYPE) makes more sense. For example, this is the key you'd want when the table is a single reference data look-up (which is a horrible model but common enough). Whereas a compound key of ID_DESCRIPTION, NAME) would do nothing but undermine the primary key.

Unique constraint violation during insert: why? (Oracle)

I'm trying to create a new row in a table. There are two constraints on the table -- one is on the key field (DB_ID), the other constrains a value to be one of several the the field ENV. When I do an insert, I do not include the key field as one of the fields I'm trying to insert, yet I'm getting this error:
unique constraint (N390.PK_DB_ID) violated
Here's the SQL that causes the error:
insert into cmdb_db
(narrative_name, db_name, db_type, schema, node, env, server_id, state, path)
values
('Test Database', 'DB', 'TYPE', 'SCH', '', 'SB01', 381, 'TEST', '')
The only thing I've been able to turn up is the possibility that Oracle might be trying to assign an already in-use DB_ID if rows were inserted manually. The data in this database was somehow restored/moved from a production database, but I don't have the details as to how that was done.
Any thoughts?
Presumably, since you're not providing a value for the DB_ID column, that value is being populated by a row-level before insert trigger defined on the table. That trigger, presumably, is selecting the value from a sequence.
Since the data was moved (presumably recently) from the production database, my wager would be that when the data was copied, the sequence was not modified as well. I would guess that the sequence is generating values that are much lower than the largest DB_ID that is currently in the table leading to the error.
You could confirm this suspicion by looking at the trigger to determine which sequence is being used and doing a
SELECT <<sequence name>>.nextval
FROM dual
and comparing that to
SELECT MAX(db_id)
FROM cmdb_db
If, as I suspect, the sequence is generating values that already exist in the database, you could increment the sequence until it was generating unused values or you could alter it to set the INCREMENT to something very large, get the nextval once, and set the INCREMENT back to 1.
Your error looks like you are duplicating an already existing Primary Key in your DB. You should modify your sql code to implement its own primary key by using something like the IDENTITY keyword.
CREATE TABLE [DB] (
[DBId] bigint NOT NULL IDENTITY,
...
CONSTRAINT [DB_PK] PRIMARY KEY ([DB] ASC),
);
It looks like you are not providing a value for the primary key field DB_ID. If that is a primary key, you must provide a unique value for that column. The only way not to provide it would be to create a database trigger that, on insert, would provide a value, most likely derived from a sequence.
If this is a restoration from another database and there is a sequence on this new instance, it might be trying to reuse a value. If the old data had unique keys from 1 - 1000 and your current sequence is at 500, it would be generating values that already exist. If a sequence does exist for this table and it is trying to use it, you would need to reconcile the values in your table with the current value of the sequence.
You can use SEQUENCE_NAME.CURRVAL to see the current value of the sequence (if it exists of course)

Resources