Add foreign column with default value - sql

I need to add a foreign key column in an existing table using alter statement. And need to set default value to insert default in case of null. For that I added below alter query:
ALTER TABLE COM.USER_GENERATED_TASK_LIST
ADD Application_ID INTEGER NOT NULL
CONSTRAINT DK_Application_ID DEFAULT (5) WITH VALUES,
CONSTRAINT FK_Application_ID FOREIGN KEY (Application_ID)
REFERENCES ADMIN.APPLICATION (Application_ID)
But with these, if I excluded value of new column in the insert statement, I will get this error message:
Column name or number of supplied values does not match table definition.

Related

Change primary key from simple to composite with new column

I am trying to change the primary key of one of my tables from a simple to a composite key, where the composite should be composed of the old pk column and a newly created one.
I followed along this answer from a very similar question: https://stackoverflow.com/a/27832197/1948454
It almost works, except that there is no value set in the dependant table for the new column.
Here's the situation:
Suppose I have a table for a catalog, and a table for catalog entries. Before:
-- DDL Catalog
CREATE TABLE public.Catalog (
name_ VARCHAR(255) NOT NULL,
foo_ VARCHAR(255) NULL,
CONSTRAINT Catalog_pkey PRIMARY KEY (name_)
);
-- DDL CatalogEntry
CREATE TABLE public.CatalogEntry (
pricekey_ VARCHAR(255) NOT NULL,
pricekeyroot_ VARCHAR(255) NOT NULL,
catalog_name_ VARCHAR(255) NULL,
bar_ VARCHAR(255) NULL,
CONSTRAINT CatalogEntry_pkey PRIMARY KEY (pricekey_, pricekeyroot_)
);
-- public.CatalogEntry FOREIGN KEYs
ALTER TABLE public.CatalogEntry ADD CONSTRAINT CatalogEntry_catalog_name__fkey FOREIGN KEY (catalog_name_) REFERENCES Catalog(name_) ON DELETE CASCADE;
So CatalogEntry.catalog_name references to Catalog.name_.
Now I need to add another column version_ to the Catalog table, indicating a version of some catalog. This means I will have to create a new composite pk composed of name_ and version_. Here's my script:
-- UPDATE script
-- add the new version column and set all values to default of 1
ALTER TABLE Catalog ADD version_ INTEGER;
UPDATE Catalog SET version_ = 1;
ALTER TABLE Catalog ALTER column version_ SET not null;
-- update primary key and foreign key
BEGIN;
-- first, drop fkey constraint on CatalogEntry
ALTER TABLE CatalogEntry DROP CONSTRAINT CatalogEntry_catalog_name__fkey;
-- then, update Catalog primary key
ALTER TABLE Catalog DROP CONSTRAINT Catalog_pkey,
ADD CONSTRAINT Catalog_uni_name UNIQUE (name_),
ADD PRIMARY KEY (name_, version_);
-- now add new foreign key again to CatalogEntry
ALTER TABLE CatalogEntry ADD catalog_version_ INTEGER;
ALTER TABLE CatalogEntry
ADD CONSTRAINT CatalogEntry_catalog_name__catalog__fkey FOREIGN KEY (catalog_name_, catalog_version_)
references Catalog(name_, version_ ) ON DELETE CASCADE;
COMMIT;
-- finally, remove unique constraint on name since it is not needed anymore
ALTER TABLE Catalog DROP CONSTRAINT Catalog_uni_name;
After performing these steps, the primary and foreign key appear to be set correctly - but the value of CatalogEntry.catalog_version_ is null. The corresponding value of Catalog.version_ is set correctly to 1.
Where is my mistake? Do I also have to set CatalogEntry.catalog_version_ manually to 1? I would have assumed that it would be set automatically.
The value of CatalogEntry.catalog_version_ doesn't magically get set just because you define a foreign key constraint.
What effectively happened is that no row in CatalogEntry references a row in Catalog. The reason is that the default for foreign key constraints is MATCH SIMPLE, see the documentation:
MATCH SIMPLE allows any of the foreign key columns to be null; if any of them are null, the row is not required to have a match in the referenced table.
You should create the foreign key constraint as MATCH FULL so that either all or none of the columns must be NULL. Then you would have received an error creating the foreign key.
Solution: update CatalogEntry and set the column to 1 there as well, then define the foreign key with MATCH FULL.

ALTER COLUMN Command doesn't work SQL Server

i want to add to a primary key in one table a references to the primary key of another table.
my code:
CREATE TABLE[payment]
(ID int Primary key)
CREATE TABLE [tab]
(ID int Primary key references tab2(ID))
Alter Table payment
alter column ID
ADD constraint fk_payment
references tab(ID)
i get the error that the syntax near constraint is wrong, but i don't know what to change
because of the not changeable order of the table Alter table is the only option. to reference from one table to the other doesn't work cause I've references from that table to another one already.
i need two one-to-one-relations from one table to another
If you want to add a FK constraint, just use this code:
ALTER TABLE dbo.payment
ADD CONSTRAINT fk_payment
FOREIGN KEY(ID) REFERENCES dbo.tab(ID)
You don't need to alter the column or table - just add the constraint

Unique key with Empty values

This is the schema for the table, here defined a unique constraint with job_category_id, screening_type_id, test_id, sex.
CREATE TABLE job_profile
(
profile_id numeric(5,0) NOT NULL,
job_category_id numeric(5,0),
test_id numeric(5,0),
sex character(1),
default_yn character(1),
screening_type_id numeric(5,0),
CONSTRAINT job_profile_pkey PRIMARY KEY (profile_id),
CONSTRAINT fk_jobprofile_jobcate FOREIGN KEY (job_category_id)
REFERENCES job_category_mast (job_category_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_jobprofile_test FOREIGN KEY (test_id)
REFERENCES test_mast (test_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_prof_screentype FOREIGN KEY (screening_type_id)
REFERENCES screening_type_mast (screening_type_id) MATCH SIMPLE
ON UPDATE RESTRICT ON DELETE RESTRICT,
CONSTRAINT uk_job_test_sex_screening UNIQUE (job_category_id, screening_type_id, test_id, sex)
)
WITH (
OIDS=FALSE
);
ALTER TABLE job_profile
OWNER TO cdcis;
GRANT ALL ON TABLE job_profile TO cdcis;
GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE job_profile TO cdcis_app;
If one field is empty then the unique constraint fails here.
How to add constraint so that one empty value is accepted, so it will be unique.
Can handle this scenario in the application using JPA?
According to the documentation:
Null values are not considered equal
So unique constraint won't work this way.
You have 2 options:
Create a trigger that will manually check the data integrity and deny changes if the table contains more than one empty value.
Set default value to 0 and NOT NULL constraint on these columns. In that case, you will be able to have only one row containing empty (zero) value.
Update:
As Abelisto suggested, it can be easily done with functional indexes.
CREATE UNIQUE INDEX uix_job_test_sex_screening on job_profile(coalesce(job_category_id, -1), screening_type_id, test_id, sex);

Adding the NOT_NULL constraint to an SQL column

I'm trying to add the NOT_NULL constraint to a column in an SQL h2 database, using
ALTER TABLE CHARACTERS ADD CONSTRAINT nn_PID NOT_NULL (PLAYER_ID);
This follows the pattern I found here:
ALTER TABLE Persons ADD CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
Except I change the constraint, table and column names. But I get this error:
Syntax error in SQL statement "ALTER TABLE CHARACTERS ADD CONSTRAINT NN_PID NOT_NULL[*] (PLAYER_ID) "; expected "., COMMENT, PRIMARY, INDEX, KEY, CHECK, UNIQUE, FOREIGN"; SQL statement:
ALTER TABLE CHARACTERS ADD CONSTRAINT nn_PID NOT_NULL (PLAYER_ID) [42001-168] 42001/42001 (Help)
How can I add the NOT_NULL constraint?
From H2 SQL Grammar:
ALTER TABLE TEST ALTER COLUMN NAME SET NOT NULL;
So we can use:
ALTER TABLE CHARACTERS ALTER PLAYER_ID SET NOT NULL;

Alter Table Add Column with Default value And FK, that Value no existing in FK Reference Data

This is My Tables :
Member : Id, ....
Product: Id, ....
My Member Table have some values none if them with Id = 0 and I don't want to add any member with Id = 0, So I try to run this Script:
ALTER TABLE [Product]
ADD [Member_Id] BIGINT NOT NULL DEFAULT(0),
CONSTRAINT [FK_Product_Member] FOREIGN KEY ([Member_Id]) REFERENCES [Member];
So There is an Error :
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_Product_Member".
So I try this one:
SET IDENTITY_INSERT [Member] ON
INSERT INTO [Member] ([Id]) VALUES (0);
SET IDENTITY_INSERT [Member] OFF
ALTER TABLE [Product]
ADD [Member_Id] BIGINT NOT NULL DEFAULT(0),
CONSTRAINT [FK_Product_Member] FOREIGN KEY ([Member_Id]) REFERENCES [Member];
DELETE FROM [Member] WHERE [Member].[Id] = 0;
Then The new Error is:
The DELETE statement conflicted with the REFERENCE constraint "FK_Product_Member".
If I try to create all Tables again, every thing will be OK of course with lost my Data so need to get backup, create tables and restore data. So Is there any way to alter Table with this situation? what is your suggestion?
The only "value" that you can have in a referencing table, such that the foreign key constraint is not enforced, is NULL. Not 0, or any other magic value.
So the obvious solution is to allow NULLs:
ALTER TABLE [Product]
ADD [Member_Id] BIGINT NULL,
CONSTRAINT [FK_Product_Member] FOREIGN KEY ([Member_Id]) REFERENCES [Member];
your "alter table" is the better way to do this.but at first you are adding the table with value "0" and this is "FOREIGN KEY" but you have not a Member with value "0" so you get error.
the best way as a know is .alter table and then make the true value to the new column and then alter the column and set that to the "FOREIGN KEY"