How Do I Specify a Column Name for a Default Constraint? - sql-server

I know I can specify it inline like this:
CREATE TABLE dbo.MyTable
(
Id INT NOT NULL CONSTRAINT PK_MyTable_Id PRIMARY KEY IDENTITY,
Created DATETIME NOT NULL CONSTRAINT DF_MyTable_Created DEFAULT GETDATE()
)
But I'd like to put all my constraints at the end of the table definition to keep them separate. I can't seem to find out how to name the column for the default constraint if I put it at the end of the table definition. I can do it with primary/foreign keys and unique constraints, but don't know how to specify the column name with a default constraint.
CREATE TABLE dbo.MyTable
(
Id INT NOT NULL IDENTITY,
Created DATETIME NOT NULL,
CONSTRAINT PK_MyTable_Id PRIMARY KEY( Id ),
CONSTRAINT DF_MyTable_Created DEFAULT GETDATE()
)

Do it separate with ALTER TABLE ADD..... syntax
like this
CREATE TABLE dbo.MyTable
(
Id INT NOT NULL IDENTITY,
Created DATETIME NOT NULL
)
GO
ALTER TABLE dbo.MyTable ADD CONSTRAINT PK_MyTable_Id PRIMARY KEY( Id ),
CONSTRAINT DF_MyTable_Created DEFAULT GETDATE() FOR Created
GO

Related

Update/Delete violate foreign key on either side

I have two tables, below are the strutures
CREATE TABLE IF NOT EXISTS nl_address (
id int NOT NULL GENERATED BY DEFAULT AS IDENTITY,
address_text varchar(100),
pincode varchar(6),
city_id int NOT NULL,
state_id int NOT NULL,
country_id int NOT null,
is_active boolean default true,
PRIMARY KEY (id),
CONSTRAINT fk_city_id FOREIGN KEY(city_id) REFERENCES nl_city(id),
CONSTRAINT fk_state_id FOREIGN KEY(state_id) REFERENCES nl_state(id),
CONSTRAINT fk_country_id FOREIGN KEY(country_id) REFERENCES nl_country(id)
);
CREATE TABLE IF NOT EXISTS nl_customer (
cust_id int NOT NULL,
prefix varchar(10) default 'CUST-',
suffix varchar(2),
org_name varchar(100) NOT NULL,
domain_name varchar(100) NOT NULL,
pan_number varchar(10) NOT null,
pri_contact varchar(10) NOT NULL,
pri_number varchar(10) NOT NULL,
pri_email varchar(30) NOT NULL,
sec_contact varchar(10),
sec_number varchar(10),
sec_email varchar(30),
is_active boolean default true,
addr_id int not null,
created_date date,
created_by varchar(10),
updated_date date,
updated_by varchar(10),
PRIMARY KEY (cust_id),
CONSTRAINT fk_address_id FOREIGN KEY(addr_id) REFERENCES nl_address(id)
);
The problem is, neither I am able to update or delete
If i am trying to update record in nl_address, I got an violation error that the field is used inside `nl_customer.
If i tried to update from nl_customer, then I got an violation error that the field is used inside nl_address
It was originated, when JPA trying to persist the data, I have inserted a dummy data with id 1, when JPA trying to insert another record then it throws
.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "nl_address_pkey"
Detail: Key (id)=(1) already exists.
It seems there is something wrong with the table structure, any help appreciated
Actually this is common that you cannot update or delete that belong to primary/foreign key if you generate duplicates, as all values should be unique (i.e. if you have already id=1 and update id=2 to id=1, you will get the error you mentioned) and because a foreign key construct is a specific relationship it should be clarified what will happen with this relationship.
In case of 'nl_address' you used 'GENERATED BY DEFAULT AS IDENTITY' which have the same purpose as SERIAL (i.e. auto increment), but it is more compliant with SQL standard. (I assume you are also aware of difference between GENERATED BY DEFAULT and GENERATED ALWAYS)
However, you can specify the sequence in order to ensure the proper auto increment functionality.
ALTER TABLE nl_address
ALTER COLUMN "id"
DROP IDENTITY IF EXISTS;
ALTER TABLE nl_address
ALTER COLUMN "id"
ADD GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT 1);
If you use UPDATE or DELETE on FOREIGN KEY construct ensure what should happen with relationship:
[CONSTRAINT fk_name]
FOREIGN KEY(fk_columns)
REFERENCES parent_table(parent_key_columns)
[ON DELETE delete_action]
[ON UPDATE update_action]
/* as delete_action or update_action you can use e.g. SET NULL, RESTRICT or CASCADE;
so ensure what happen with records in related table*/

Can't create tables with Foreign Key of each other

Is there a way to create both tables while being a foreign key of one another? I am using SQL Server Management Studio
--DROP TABLE orders
CREATE TABLE orders
(
orderId bigint PRIMARY KEY IDENTITY(880001, 1) NOT NULL,
receiptNo bigint FOREIGN KEY REFERENCES receipt(receiptId),
productId bigint FOREIGN KEY REFERENCES productServices(productId),
quantity int,
dateOrdered datetime DEFAULT CURRENT_TIMESTAMP
)
--DROP TABLE receipt
CREATE TABLE receipt
(
receiptNo bigint PRIMARY KEY IDENTITY(900001, 1) NOT NULL,
employeeId bigint FOREIGN KEY REFERENCES employeeInfo(employeeId),
customerId bigint FOREIGN KEY REFERENCES customerInfo(customerId),
orderId bigint FOREIGN KEY REFERENCES orders(orderId),
paymentMethod varchar(4),
dateOfPurchase datetime DEFAULT CURRENT_TIMESTAMP
)
The requirement always is: a table must exist before you can create a foreign key reference to it. So in your case, obviously, you cannot create both table with the full FK references in place, since they reference each other.
What you need to do is:
CREATE TABLE orders without the FK reference to Receipt (since that table doesn't exist yet at this time)
CREATE TABLE receipt - here you can include the FK reference to orders - that table has been created and exists
Alter your table orders to add the FK reference to receipt:
ALTER TABLE dbo.orders
ADD CONSTRAINT FK_Orders_Receipt
FOREIGN KEY (receiptNo) REFERENCES dbo.receipt(receiptId);
Of course, the same applies to all the other FK constraints you have - you cannot reference a table that doesn't exist yet. You must first create the tables, then you can add the FK constraints.
For you Case, you change the order of creating the Table.
1.) Before adding a Foreign Key References to a new table, the table to be refereed as a foreign key must be already exists.
2.) Also a add a batch Separator GO statement while single Execution of creating tables.
--DROP TABLE receipt
CREATE TABLE receipt
(
receiptNo bigint PRIMARY KEY IDENTITY(900001, 1) NOT NULL,
employeeId bigint FOREIGN KEY REFERENCES employeeInfo(employeeId),
customerId bigint FOREIGN KEY REFERENCES customerInfo(customerId),
orderId bigint FOREIGN KEY REFERENCES orders(orderId),
paymentMethod varchar(4),
dateOfPurchase datetime DEFAULT CURRENT_TIMESTAMP
)
GO
--DROP TABLE orders
CREATE TABLE orders
(
orderId bigint PRIMARY KEY IDENTITY(880001, 1) NOT NULL,
receiptNo bigint FOREIGN KEY REFERENCES receipt(receiptId),
productId bigint FOREIGN KEY REFERENCES productServices(productId),
quantity int,
dateOrdered datetime DEFAULT CURRENT_TIMESTAMP
)
GO
This is hard because it's wrong. There's no need for two FKs and they are actively harmful as you could have an order whose receipt points to a different order. The right design here is to just have one FK, and enforce uniqueness on the FK column. Thus an order may be created first, and later at most one receipt can be added for that order.
eg:
create table employeeInfo(employeeid bigint primary key)
create table customerInfo(customerID bigint primary key)
create table productServices(productId bigint primary key)
CREATE TABLE orders
(
orderId bigint PRIMARY KEY IDENTITY(880001, 1) NOT NULL,
--receiptNo bigint FOREIGN KEY REFERENCES receipt(receiptId),
productId bigint FOREIGN KEY REFERENCES productServices(productId),
quantity int,
dateOrdered datetime DEFAULT CURRENT_TIMESTAMP
)
CREATE TABLE receipt
(
receiptNo bigint PRIMARY KEY IDENTITY(900001, 1) NOT NULL,
employeeId bigint FOREIGN KEY REFERENCES employeeInfo(employeeId),
customerId bigint FOREIGN KEY REFERENCES customerInfo(customerId),
orderId bigint FOREIGN KEY REFERENCES orders(orderId) unique,
paymentMethod varchar(4),
dateOfPurchase datetime DEFAULT CURRENT_TIMESTAMP
)

Spring boot cannot create session

I am getting the following exception when creating the session.
INSERT INTO SPRING_SESSION
(
SESSION_ID,
CREATION_TIME,
LAST_ACCESS_TIME,
MAX_INACTIVE_INTERVAL,
PRINCIPAL_NAME
)
VALUES (?, ?, ?, ?, ?)];
Cannot insert the value NULL into column 'PRIMARY_ID'
Following are my schema details :
CREATE TABLE SPRING_SESSION (
PRIMARY_ID CHAR(36) NOT NULL,
SESSION_ID CHAR(36) NOT NULL,
CREATION_TIME BIGINT NOT NULL,
LAST_ACCESS_TIME BIGINT NOT NULL,
MAX_INACTIVE_INTERVAL INT NOT NULL,
EXPIRY_TIME BIGINT NOT NULL,
PRINCIPAL_NAME VARCHAR(100),
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
);
CREATE UNIQUE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (EXPIRY_TIME);
CREATE INDEX SPRING_SESSION_IX3 ON SPRING_SESSION (PRINCIPAL_NAME);
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
SESSION_PRIMARY_ID CHAR(36) NOT NULL,
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
ATTRIBUTE_BYTES IMAGE NOT NULL,
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY
(SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY
(SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
);
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1
ON SPRING_SESSION_ATTRIBUTES (SESSION_PRIMARY_ID);
The solution to this problem is simple , Inside of spring-session jar file , there is org/springframework/session/jdbc folder , you can view this in eclipse.
Under this folder you can get schema-sqlserver.sql file , you need to execute this file only for proper schema of spring session.
You are setting the Column PRIMARY_ID as Primary key
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
and since it is not a computed column or Auto Incremented one, you must specify a value for this column on each insert.
But wish not to populate the column for all Rows, then Change the design and Remove the PRIMARY KEY from that Column.
Then Probably you may add a New Column with IDENTITY so that it will be automatically assigned.
You can drop the Constraint Using this
ALTER TABLE SPRING_SESSION
DROP CONSTRAINT SPRING_SESSION_PK
Then add New Primary Key
ALTER TABLE SPRING_SESSION
ADD SeqNo INT IDENTITY(1,1) CONSTRAINT SPRING_SESSION_PK PRIMARY KEY

SQL Server Foreign Key references invalid Table 'employees'

I try to run this SQL Server query:
USE DB_UBB;
CREATE TABLE dept_emp (
emp_no INT NOT NULL,
dept_no CHAR(4) NOT NULL,
from_date DATE NOT NULL,
to_date DATE NOT NULL,
FOREIGN KEY (emp_no) REFERENCES employees(emp_no) ON DELETE CASCADE, -- Error here
FOREIGN KEY (dept_no) REFERENCES departments(dept_no) ON DELETE CASCADE, -- And here
PRIMARY KEY (emp_no, dept_no)
);
CREATE INDEX (emp_no);
CREATE INDEX (dept_no);
and I get these errors:
Foreign key 'FK__dept_emp__8bc6840bee39d6cef4bd' references invalid table 'employees'.
Foreign key 'fk__dept_emp__99bc0b2304d3f32059a9' references invalid table 'departments'.
even though I have these tables:
What do I do wrong?
EDIT:
Added Whole DB:
SQL ‘hides’ the columns from the Key of the Clustered Index in Nonclustered Indexes.
You have created a composite primary on both emp_no,dept_no
cluster index of primary will hide both columns from indexes in following queries and will generate error
CREATE INDEX (emp_no);
CREATE INDEX (dept_no);
If you are specifying the foreign key after the column specifications, try using the CONSTRAINT clause instead:
to_date DATE NOT NULL,
CONSTRAINT fk_dept_emp_dept FOREIGN KEY (emp_no) REFERENCES employees(emp_no) ON DELETE CASCADE,
CONSTRAINT fk_dept_emp_emp FOREIGN KEY (dept_no) REFERENCES departments(dept_no) ON DELETE CASCADE,
Aparently, I even though the tables were created, it didn't recognize them.
I added an <if not exist, create tables>
I also removed the CREATE INDEX (emp_no); and CREATE INDEX (dept_no); as #Muhammad Nasir said, but it didn't fix the referencing issue.
Solution:
USE DB_UBB;
IF NOT EXISTS (SELECT * FROM SYSOBJECTS WHERE name='employees' and xtype='U')
CREATE TABLE employees (
emp_no INT NOT NULL,
birth_date DATE NOT NULL,
first_name VARCHAR(14) NOT NULL,
last_name VARCHAR(16) NOT NULL,
gender VARCHAR(1) NOT NULL CHECK (gender IN('M', 'F')),
hire_date DATE NOT NULL,
PRIMARY KEY (emp_no)
);
GO
IF NOT EXISTS (SELECT * FROM SYSOBJECTS WHERE name='departments' and xtype='U')
CREATE TABLE departments (
dept_no CHAR(4) NOT NULL,
dept_name VARCHAR(40) NOT NULL,
PRIMARY KEY (dept_no),
UNIQUE (dept_name)
);
GO
IF NOT EXISTS (SELECT * FROM SYSOBJECTS WHERE name='dept_emp' and xtype='U')
CREATE TABLE dept_emp (
emp_no INT NOT NULL,
dept_no CHAR(4) NOT NULL,
from_date DATE NOT NULL,
to_date DATE NOT NULL,
FOREIGN KEY (emp_no) REFERENCES employees(emp_no) ON DELETE CASCADE,
FOREIGN KEY (dept_no) REFERENCES departments(dept_no) ON DELETE CASCADE,
PRIMARY KEY (emp_no, dept_no)
);
GO

Unique column definition in SQL

I've looked at a few SQL posts already but i'm unsure of their answers.. eg: SQL Unique Key Syntax
I want a Cities table... I want to define my country table whereby the Name column is unique... Using this as the base, how do I define a Unique column?
CREATE TABLE [dbo].[Cities]
(
[CityID] INT NOT NULL PRIMARY KEY,
[Name] NCHAR(100) NULL
)
You can create a constraint on the table to do this:
ALTER TABLE <tablename> ADD CONSTRAINT
<constraintname> UNIQUE NONCLUSTERED
(
<columnname>
)
You can add the unique keyword:
CREATE TABLE [dbo].[Cities]
(
[CityID] INT NOT NULL PRIMARY KEY,
[Name] NCHAR(100) NULL UNIQUE
);
There are alternative methods. You can add also add a unique index:
create unique index cities_name on dbo.Cities(Name);
Or do it with a unique constraint:
CREATE TABLE [dbo].[Cities]
(
[CityID] INT NOT NULL PRIMARY KEY,
[Name] NCHAR(100) NULL,
constraint unique_name unique(Name)
);

Resources