SQL how to update a column with a value that depends on the value of a different column in the same table - sql

I have a table with 2 date columns, open_date and close_date. And when I insert a new row the close_date can be null. But in the future I will want to update the close_date, and I want to ensure that the close_date is bigger than the open_date?
Thanx
I'm using oracle...

You can add a check constraint to make sure Close_date is bigger than the Open_Date,
ALTER TABLE Table_Name
ADD CONSTRAINT ck_Con_Name CHECK (Close_date > Open_Date)
To make sure a value is provided for Close_Date column and its not left null, make the column NON-NULABLE.
For this you will need to make sure first there isnt any NULL Values in that column. UPDATE the column to some defualt value. Then Alter table definition something like this...
ALTER TABLE Table_Name
ALTER COLUMN Close_date DATETIME NOT NULL;

A check constraint like this will do ask you ask:
ALTER TABLE YourTable ADD CONSTRAINT CK_open_date_before_close_date
CHECK (open_date < close_date);
This will reject any transactions that update the table to a state that violates the condition. If, for example, you updated 5 rows but only one of them violated the constraint, the entire update will fail.
Additionally, I would recommend that instead of NULL for an open-ended close date, you use a sentinel value of 99991231. There are many reasons for this, not the least of which is performance of queries (so you can do simple inequality statements without needing an OR IS NULL clause). You can additionally then make the column NOT NULL and simplify the above check condition. This also affects front-end application code positively.
UPDATE
The check constraint does not require OR close_date IS NULL in it, since if close_date is NULL, the whole expression will be evaluated to NULL, and this will not violate the CHECK constraint.

You may be needing the CHECK Constraints.
PLease refer to the link

Related

Autogenerated timestamp column( primary key) to existing table DB2

Is it possible to add an autogenerated primary key column ( timestamp) to the existing table with alter table?
Something like this but it doesn't compile
ALTER TABLE DB2ADMIN.xxxyyyy ADD COLUMN ID TIMESTAMP NOT NULL WITH DEFAULT timestamp(generate_unique())#
Error during Prepare
42601(-104)[IBM][CLI Driver][DB2/AIX64] SQL0104N An unexpected token "timestamp" was found following "OT NULL WITH DEFAULT". Expected tokens may include: "CHECK". SQLSTATE=42601
It is unwise to use a fake (from generate_unique) timestamp datatype as a primary key because it makes setting values for pre-existing rows more awkward, and makes date arithmetic impossible.
The datatype TIMESTAMP is better suited for real dates/times because then you can use date arithmetic, which is practical for business. If the values in your fake timestamp-column are from generate-unique then you cannot sensibly use date arithmetic.
If you try to use a real timestamp value , (instead of generate_unique) , such as current timestamp then you are likely to get collisions, depending on the insert-rate. Usually that's a bad idea. Also this makes setting values for any pre-existing rows more difficult.
It is usually much easier and faster to use an autogenerated identity column as a surrogate primary key, especially if the table already has existing data.
Here is a typical way to do this which works with Db2-LUW and also on older versions of Db2. Other ways are possible with later versions of Db2.
Firs you need to verify that the table does not already have a primary key, as there can only be at most one of these per table.
Next, check if the table already has a unique index on a NOT NULL column, because if such a column exists then it can be promoted to be the primary key column.
If neither of the above exist, then you can use logic like this below to add an autgenerated column, set unique values in any existing rows, and ensure that any future inserts automatically get a unique value in the column without application intervention.
alter table myschema.mytab add column id bigint not null default 0 ;
alter table myschema.mytab alter column id drop default ;
alter table myschema.mytab alter column id set generated always as identity ;
update myschema.mytab set id = default ;
alter table myschema.mytab add constraint pkey primary key(id) ;
reorg table myschema.mytab ;
runstats on table myschema.mytab with distribution and detailed indexes all;
You can use CURRENT_TIMESTAMP instead of timestamp(generate_unique())
ALTER TABLE sellers ADD COLUMN ID TIMESTAMP NOT NULL WITH DEFAULT CURRENT_TIMESTAMP
You can test here

Modify SQL column field to be nullable, if I added constraint do I need to remove constraint as well?

I altered a table with the following script
ALTER TABLE TABLENAME ADD [flagField] CHAR(1) DEFAULT 'N' NOT NULL;
ALTER TABLE TABLENAME ADD CONSTRAINT XCK6_tablename CHECK([flagField] in ('Y', 'N'));
If I want to reverse this script to change that field in the table to allow a nullable state, do I need to remove the constraint before making the field nullable?
so if I run
ALTER TABLE TABLENAME ALTER COLUMN fieldFlag CHAR(1) NULL
will that be fine as is or should I also remove the constraint?
You only have to make the field NULLable.
The logic for constraints differs from the logic for WHERE and CASE WHEN conditions. For WHERE and CASE WHEN, NULL results are treated the same as false.
CHECK is instead validating the data. It accepts as valid anything that is not explicitly false. So, there is no need to include NULL checking in the constraint.
If you did, the correct logic would be:
CHECK (flagField in ('Y', 'N') or flagField is null)
Here is a db<>fiddle illustrating that the behavior is as described above.

How to add a not null constraint on column containing null values

I have a table with a column that contains a few null values. I want to add a NOT NULL constraint on that column without updating the existing nulls to a non-null value. I want to keep the existing null values and check for future rows that they contain a not null value for this column. Is this possible? How?
You can add an unvalidated constraint - it will not look at existing rows, but it will be checked for any new or updated rows.
ALTER TABLE mytable MODIFY mycolumn NOT NULL NOVALIDATE;
Just be aware that you won't be able to update an existing row unless it satisfies the constraint.
Also, be aware of the downside that the optimizer will not be able to take advantage of this constraint in making its plans - it has to assume that some rows may still have a null.
ALTER TABLE table_name
SET column_name = '0'
WHERE column_name IS NULL;
ALTER TABLE table_name
MODIFY COLUMN(column_name NUMBER CONSTRAINT constraint_identifier NOT NULL);
This is of course assuming that your column is a number but it's the same thing really, you would just change the '0' to a default value that isn't null.
Hammad:
I face the problem and solve like following:
Alter table thr_empl_info modify THR_EM_DESIGNATION_ID not null

Check Constraints in SQL- Specify a value could be null or a constraint

I am trying to incorporate a check constraint in SQLite where the requirement is the following:
The value could be null
If the value is not null then it should be greater than 3.
So, in my create table I wrote
create table T(A real check(A = null or A>3));
For this it looks like it creates the table, but it does not enforce the greater than condition.
And I also tried
create table T(A real check(A is null or A>3));
This does not even create the table in the first place.
Can somebody please help on how to enforce both of these constraints?
Thanks
Why do you need both? Simply allow the field to be NULL and make the condition A>3. The field will either be NULL or if NOT NULL, greater than 3...
CREATE TABLE (A real NULL check(A>3))
From the SQL-92 Standard:
A table check constraint is satisfied if and only if the specified
search condition is not false for any row of a table.
If A is null then A > 3 will, thanks to SQL's three-valued logic, evaluate to UNKNOWN. Because UNKNOWN is not FALSE the constraint will be satisfied.
Consider that if the Standard was not written that way then every constraint would have to explicitly test for null, which would be more 'noise' and pain for coders.

Best way to add a new column with an initial (but not default) value?

I need to add a new column to a MS SQL 2005 database with an initial value. However, I do NOT want to automatically create a default constraint on this column. At the point in time that I add the column the default/initial value is correct, but this can change over time. So, future access to the table MUST specify a value instead of accepting a default.
The best I could come up with is:
ALTER TABLE tbl ADD col INTEGER NULL
UPDATE tbl SET col = 1
ALTER TABLE tbl ALTER COLUMN col INTEGER NOT NULL
This seems a bit inefficient for largish tables (100,000 to 1,000,000 records).
I have experimented with adding the column with a default and then deleting the default constraint. However, I don't know what the name of the default constraint is and would rather not access sysobjects and put in database specific knowledge.
Please, there must be a better way.
To add the column with a default and then delete the default, you can name the default:
ALTER TABLE tbl ADD col INTEGER NOT NULL CONSTRAINT tbl_temp_default DEFAULT 1
ALTER TABLE tbl drop constraint tbl_temp_default
This filled in the value 1, but leaves the table without a default. Using SQL Server 2008, I ran this and your code, of alter update alter and did not see any noticeable difference on a table of 100,000 small rows. SSMS would not show me the query plans for the alter table statements, so I was not able to compare the resources used between the two methods.
I'd ALTER TABLE tbl ADD col INTEGER CONSTRAINT tempname DEFAULT 1 first,, and drop the explicitly named constraint after (presumably within a transaction).
Another, maybe more native, way would be:
ALTER TABLE tbl ADD COLUMN col INTEGER NOT NULL DEFAULT 1;
ALTER TABLE tbl ALTER COLUMN col DROP DEFAULT;
I'm not sure how long this function exists, but the PostgreSQL documentation goes back to version 7.1 and for 7.1 it is already described.
You can do it in an insert trigger
If you add a default constraint when creating the table, you won't know what it is called. However, if you add a constraint with ALTER TABLE, you must name the constraint. In this case, you would be able to ALTER TABLE DROP CONSTRAINT (This applies to T-SQL, not sure about other databases.)
However, this would require you to CREATE TABLE with NULL column, ALTER TABLE to add the constraint, make the column NOT NULL, and finally DROP CONSTRAINT.
I don't believe an insert trigger would work as someone else mentioned, because your rows are already added.
I think the way you describe may, in fact, be the most efficient and elegant solution.