SQL - When creating a table, how can I make it so a column is required when another column meets a certain requirement? - sql

I am using Microsoft SQL Server Management Studio. So this is what I have right now:
CREATE TABLE Product
(
product_id INT NOT NULL PRIMARY KEY IDENTITY,
product_code CHAR(4) NOT NULL, --For a book use 'BOOK'
product_name VARCHAR(40) NOT NULL,
product_desc VARCHAR(5000),
book_author INT,
book_publisher INT,
product_price SMALLMONEY NOT NULL CHECK (product_price >= 0),
FOREIGN KEY (book_author) REFERENCES Author
);
So I would like to make it so that book_author and book_publisher cannot be null if product_code == 'BOOK'.
Is this possible and how?

This is how I would do it:
CREATE TABLE Product (
product_id INT NOT NULL PRIMARY KEY IDENTITY
, product_code CHAR(4) NOT NULL
, product_name VARCHAR(40) NOT NULL
, product_desc VARCHAR(5000)
, book_author INT
, book_publisher INT
, product_price SMALLMONEY NOT NULL CHECK (product_price >= 0)
, CONSTRAINT CHK_author CHECK (
CASE
WHEN product_code = 'BOOK' AND (book_author IS NULL OR book_publisher IS NULL) THEN 0
ELSE 1
END = 1
)
);
CHK_author constraint will check if your product_code is BOOK, and if it is, then it will check whether book_author OR book_publisher are NULL values. If one of them is - it will restrict statement.
Here's a SQL Fiddle

CREATE TABLE [dbo].[Product](
[product_id] [int] IDENTITY(1,1) NOT NULL,
[product_code] [char](4) NOT NULL,
[product_name] [varchar](40) NOT NULL,
[product_desc] [varchar](5000) NULL,
[book_author] [int] NULL,
[book_publisher] [int] NULL,
[product_price] [smallmoney] NOT NULL,
PRIMARY KEY CLUSTERED ( [product_id] ASC )
)
Go
ALTER TABLE [dbo].[Product] WITH CHECK ADD CONSTRAINT [CK_Product] CHECK (
(
( [product_code] <> 'BOOK' )
OR
(
( [book_author] IS NOT NULL )
AND ( [book_publisher] IS NOT NULL )
)
)
AND
( [product_price] >= 0 )
)
Go
ALTER TABLE [dbo].[Product] CHECK CONSTRAINT [CK_Product]
Go
One constraint pair row.

Related

there is already an object named '' in the database

This is my code:
CREATE TABLE supplier -- creating table supplier
(
supplierID INT NOT NULL IDENTITY,
supplierName VARCHAR(30) NOT NULL,
suppplierNo VARCHAR(10) NOT NULL,
supplierEmail VARCHAR(30) NOT NULL,
CONSTRAINT PK_supplierID PRIMARY KEY(supplierID)
)
GO
I get the the error:
Msg 2714, Level 16, State 6, Line 34
There is already an object named 'supplier' in the database.
Any help? Thanks!
Please try this code.
IF EXISTS(SELECT 1 FROM sys.tables WHERE name = 'supplier')
DROP TABLE dbo.supplier;
CREATE TABLE dbo.supplier
(
supplierID INT NOT NULL IDENTITY,
supplierName VARCHAR(30) NOT NULL,
suppplierNo VARCHAR(10) NOT NULL,
supplierEmail VARCHAR(30) NOT NULL,
CONSTRAINT PK_supplierID PRIMARY KEY(supplierID)
)
GO
You need to check if the table exists first
IF OBJECT_ID('dbo.supplier', 'U') IS NOT NULL
DROP TABLE dbo.supplier;
CREATE TABLE dbo.supplier
(
supplierID INT NOT NULL IDENTITY,
supplierName VARCHAR(30) NOT NULL,
suppplierNo VARCHAR(10) NOT NULL,
supplierEmail VARCHAR(30) NOT NULL,
CONSTRAINT PK_supplierID PRIMARY KEY(supplierID)
)
GO
If you are using 2016+ you can use
DROP TABLE IF EXISTS dbo.supplier;
CREATE TABLE dbo.supplier
(
supplierID INT NOT NULL IDENTITY,
supplierName VARCHAR(30) NOT NULL,
suppplierNo VARCHAR(10) NOT NULL,
supplierEmail VARCHAR(30) NOT NULL,
CONSTRAINT PK_supplierID PRIMARY KEY(supplierID)
)
GO

SqlServer - Insert multiple records and get new and old ID

I have this query:
CREATE TABLE [factOffertDetail](
[idOffertRow] [INT] IDENTITY(1,1) NOT NULL,
[idOffertRegion] [INT] NOT NULL,
[idProduct] [INT] NOT NULL,
[Qty] [DECIMAL](12, 2) NULL,
[idUnitPrice] [TINYINT] NULL
)
DECLARE #TMP2 TABLE (
idOffertRowNEW INT,
idOffertRow INT
)
INSERT INTO factOffertDetail
( idOffertRegion ,
idProduct ,
Qty ,
idUnitPrice
)
OUTPUT inserted.idOffertRow INTO #TMP2(d.idOffertRowNEW)
SELECT
d.idOffertRegion,
d.idProduct ,
d.Qty ,
d.idUnitPrice
FROM factOffertDetail d
I need to get the keys of the old and the new idOffertRow generated by identity.
idOffertRow is the identity (1,1) key of the factOffertDetail table.
How can I do this with an insert ?
Is it possible or I have to switch to merge command ?
Thanks to support
I would recommend to doing this:
Alter your table with new coloum,
ALTER TABLE [factOffertDetail]
ADD [ParentId] [INT] NULL
then,
INSERT INTO factOffertDetail
( ParentId,
idOffertRegion ,
idProduct ,
Qty ,
idUnitPrice
)
OUTPUT inserted.idOffertRow,inserted.ParentId INTO #TMP2(idOffertRowNEW,idOffertRow)
SELECT
d.idOffertRow,
d.idOffertRegion,
d.idProduct ,
d.Qty ,
d.idUnitPrice
FROM factOffertDetail d
Thank You!

SQL Server 2012 : Create Table

CREATE TABLE Schedule
(
Section DATETIME NOT NULL PRIMARY KEY(CourseID, Section, EmployeeID),
CourseID VARCHAR(10) REFERENCES Course(CourseID) NOT NULL,
EmployeeID VARCHAR(20) NOT NULL REFERENCES Employee(EmployeeID),
StartTime TIME NULL,
Days DATE NULL,
Length TIME NULL
)
CREATE TABLE Enrollment
(
StudentID INT Primary key (StudentID, CourseID, Section) NOT NULL,
CourseID VARCHAR(10) REFERENCES Course(CourseID) NOT NULL,
Section DATETIME NOT NULL REFERENCES Schedule(Section)
)
2nd table did not get created, where did I go wrong?
Its because you made the primary key in the Schedule table a natural/combined key.
Try creating a stand alone column for this purpose instead. I've included an example below that shows the differences.
CREATE TABLE DBO.PK_TEST (
Col_A INT NOT NULL
,Col_B INT NOT NULL
,Primary Key(Col_A,Col_B)
)
Create table DBO.PK_TEST_2 (
Col_A int NOT NULL
,Col_B int NOT NULL
,Col_C as (cast(Col_A as nvarchar)
+ cast(Col_B as nvarchar)) PERSISTED NOT NULL
,primary key(Col_C)
)

Retrieve Data from Different Tables (SQL Server)

I have 4 tables in a SQL Server database with following schema:
Attendance
CREATE TABLE [dbo].[Attendance] (
[AttendanceId] UNIQUEIDENTIFIER DEFAULT (newid()) NOT NULL,
[CourseId] UNIQUEIDENTIFIER NOT NULL,
[StudentId] UNIQUEIDENTIFIER NOT NULL,
[SubjectId] UNIQUEIDENTIFIER NOT NULL,
[Semester] INT NOT NULL,
[Month] NVARCHAR (50) NOT NULL,
[Count] INT NOT NULL,
CONSTRAINT [PK_Attendance] PRIMARY KEY NONCLUSTERED ([AttendanceId] ASC),
CONSTRAINT [FK_Attendance_Student] FOREIGN KEY ([StudentId]) REFERENCES [dbo].[Student] ([StudentId]) );
Course
CREATE TABLE [dbo].[Course] (
[CourseId] UNIQUEIDENTIFIER DEFAULT (newid()) NOT NULL,
[Name] NVARCHAR (50) NOT NULL,
CONSTRAINT [PK_Course] PRIMARY KEY NONCLUSTERED ([CourseId] ASC)
);
Student
CREATE TABLE [dbo].[Student] (
[StudentId] UNIQUEIDENTIFIER DEFAULT (newid()) NOT NULL,
[CourseId] UNIQUEIDENTIFIER NOT NULL,
[Name] NVARCHAR (100) NOT NULL,
[RollNo] INT NOT NULL,
[Semester] INT NOT NULL,
CONSTRAINT [PK_Student] PRIMARY KEY NONCLUSTERED ([StudentId] ASC),
CONSTRAINT [FK_Student_Course] FOREIGN KEY ([CourseId]) REFERENCES [dbo].[Course] ([CourseId])
);
Subject
CREATE TABLE [dbo].[Subject] (
[SubjectId] UNIQUEIDENTIFIER DEFAULT (newid()) NOT NULL,
[CourseId] UNIQUEIDENTIFIER NOT NULL,
[Name] NVARCHAR (100) NOT NULL,
[Semester] INT NOT NULL,
CONSTRAINT [PK_Subject] PRIMARY KEY NONCLUSTERED ([SubjectId] ASC),
CONSTRAINT [FK_Subject_Course] FOREIGN KEY ([CourseId]) REFERENCES [dbo].[Course] ([CourseId])
);
I need to create a attendance report in the following format:
Course Name | Student Name | Subject Name | Semester | Month | Count
Please tell me what SQL Query I need to use and if there's any change in schema required then suggest the same.
I'm looking forward to have your replies.
Thanks,
You need to use a JOIN in your query so that it only returns rows which match a [StudentId] from the Attendance table.
e.g.
SELECT c.CourseName, s.StudentName, u.SubjectName, u.Semester, a.Month, a.Count
FROM Student s
JOIN Attendance a ON s.StudentId = a.StudentId
JOIN Course c ON a.CourseId = c.CourseId
JOIN Subject u ON c.CourseId = u.CourseId
Something along these lines will only return rows which specifically match

INSERT statements gives me different errors

I'm trying to run a file which contains INSERT statements. The statements will either give me an not enough values error or unique constraint error.
Below is my create table statement:
CREATE TABLE PART
(PNum VARCHAR(25) NOT NULL,
PName VARCHAR(75) NOT NULL,
PUnitPrice NUMBER(7,2) NOT NULL,
ComponentOf VARCHAR(25),
CONSTRAINT PART_PKEY PRIMARY KEY(PNum),
CONSTRAINT PART_FKEY FOREIGN KEY(ComponentOf)
REFERENCES PART(PNum)
};
CREATE TABLE MANUFACTURER
(MName VARCHAR(50) NOT NULL,
MAddress VARCHAR(100) NOT NULL,
MPhone VARCHAR(25) NOT NULL,
CONSTRAINT MANUFACTURER_PKEY PRIMARY KEY(MName),
);
CREATE TABLE PART-MANUFACTURED
(MDate DATE,not null
PNum VARCHAR(25) NOT NULL,
MName VARCHAR(50) NOT NULL,
Quantity NUMBER(10) NOT NULL,
CONSTRAINT PART-MANUFACTURED_PKEY PRIMARY KEY(MName,PNum,MDate),
CONSTRAINT PART-MANUFACTURED_FKEY1 FOREIGN KEY(PNum)
REFERENCES PART(PNum),
CONSTRAINT PART-MANUFACTURED_FKEY2 FOREIGN KEY(MName)
REFERENCES MANUFACTURER(MName)
);
CREATE TABLE CUSTOMER
(CNum VARCHAR(25) NOT NULL,
CName VARCHAR(75) NOT NULL,
CType VARCHAR(20) NOT NULL,
CONSTRAINT CUSTOMER_PKEY PRIMARY KEY(CNum),
CONSTRAINT CHECK_CType
CHECK(CType IN (‘INDIVIDUAL,’INSTITUITION’))
);
CREATE TABLE ORDERS
(CNum VARCHAR(25) NOT NULL,
PNum VARCHAR(25) NOT NULL,
OrderDate DATE NOT NULL,
OrderQuantity NUMBER(7,2) NOT NULL,
CONSTRAINT ORDERS_PKEY PRIMARY KEY(CNum,PNum,OrderDate),
CONSTRAINT ORDERS_FKEY1 FOREIGN KEY(CNum)
REFERENCES CUSTOMER(CNum),
CONSTRAINT ORDERS_FKEY2 FOREIGN KEY(PNum)
REFERENCES PART(PNum)
);
Below is the statement that gives me the not enough values error:
INSERT INTO PART
VALUES('S001','System-Economy',1100,null);
INSERT INTO PART
VALUES('M001','Monitor-17 inch',250,'S001');
For the unique constraints error, I believe i have to insert the data in order of their primary and referencing keys right?
So what do I need to change in order for the the insert statements to work?
I dont see any error on Insert. The problem is with your create table. Plenty to correct. Try this
CREATE TABLE PART ( PNUM VARCHAR ( 25 ) NOT NULL,
PNAME VARCHAR ( 75 ) NOT NULL,
PUNITPRICE NUMBER ( 7, 2 ) NOT NULL,
COMPONENTOF VARCHAR ( 25 ),
CONSTRAINT PART_PKEY PRIMARY KEY ( PNUM ),
CONSTRAINT PART_FKEY FOREIGN KEY
( COMPONENTOF )
REFERENCES PART ( PNUM ) );
CREATE TABLE MANUFACTURER ( MNAME VARCHAR ( 50 ) NOT NULL,
MADDRESS VARCHAR ( 100 ) NOT NULL,
MPHONE VARCHAR ( 25 ) NOT NULL,
CONSTRAINT MANUFACTURER_PKEY PRIMARY KEY ( MNAME ) );
CREATE TABLE PART_MANUFACTURED ( MDATE DATE NOT NULL,
PNUM VARCHAR ( 25 ) NOT NULL,
MNAME VARCHAR ( 50 ) NOT NULL,
QUANTITY NUMBER ( 10 ) NOT NULL,
CONSTRAINT PART_MANUFACTURED_PKEY PRIMARY KEY
( MNAME, PNUM, MDATE ),
CONSTRAINT PART_MANUFACTURED_FKEY1 FOREIGN KEY
( PNUM )
REFERENCES PART ( PNUM ),
CONSTRAINT PART_MANUFACTURED_FKEY2 FOREIGN KEY
( MNAME )
REFERENCES MANUFACTURER ( MNAME ) );
CREATE TABLE CUSTOMER ( CNUM VARCHAR ( 25 ) NOT NULL,
CNAME VARCHAR ( 75 ) NOT NULL,
CTYPE VARCHAR ( 20 ) NOT NULL,
CONSTRAINT CUSTOMER_PKEY PRIMARY KEY ( CNUM ),
CONSTRAINT CHECK_CTYPE CHECK
( CTYPE IN ('INDIVIDUAL', 'INSTITUITION') ) );
CREATE TABLE ORDERS ( CNUM VARCHAR ( 25 ) NOT NULL,
PNUM VARCHAR ( 25 ) NOT NULL,
ORDERDATE DATE NOT NULL,
ORDERQUANTITY NUMBER ( 7, 2 ) NOT NULL,
CONSTRAINT ORDERS_PKEY PRIMARY KEY
( CNUM, PNUM, ORDERDATE ),
CONSTRAINT ORDERS_FKEY1 FOREIGN KEY
( CNUM )
REFERENCES CUSTOMER ( CNUM ),
CONSTRAINT ORDERS_FKEY2 FOREIGN KEY
( PNUM )
REFERENCES PART ( PNUM ) );
INSERT INTO
PART
VALUES
( 'S001',
'System-Economy',
1100,
NULL );
INSERT INTO
PART
VALUES
( 'M001',
'Monitor-17 inch',
250,
'S001' );