Foreign key refers invalid column in referred table - sql

I have a table ClientsPurchases with the column BillNo. I would like to refer BillNo column into Payments table as a Foreign Key, but its showing error.
There are no primary or candidate keys in the referred table.
'ClientsPurchases' that match the referencing column list in the
foreign key 'FK__Payments__BillNo__286302EC'. Msg 1750, Level 16,
State 0, Line 1
CREATE Table ClientsPurchases
(
PurchasesId int IDENTITY(1,1) PRIMARY KEY NOT NULL,
PurchasesDetails VARCHAR(75),
[BillNo] varchar(75) NULL
)
--My Payments table as bellow
CREATE TABLE [dbo].[Payments]
(
[PaymentId] [int] IDENTITY(1,1) NOT NULL,
[PayAmount] [decimal](18, 0) NULL,
[PaymentDate] [datetime] NULL,
[ClinetId] [int] NULL,
FOREIGN KEY ([BillNo]) REFERENCES ClientsPurchases(BillNo)
)
Please advice.

The [BillNo] in your ClientsPurchases should be unique.
Also, I think your foreign key should be defined as a column in the Payments table as well:
CREATE TABLE [dbo].[Payments]
(
[PaymentId] [int] IDENTITY(1,1) NOT NULL,
[PayAmount] [decimal](18, 0) NULL,
[PaymentDate] [datetime] NULL,
[ClinetId] [int] NULL,
[BillNo] [int] NOT NULL,
FOREIGN KEY ([BillNo]) REFERENCES ClientsPurchases(BillNo)
)
More about creating foreign key constraints here.

You cannot refer to BillNo because it isn't a key. You should make it NOT NULL and UNIQUE.

Related

Filtering results between two dates with rdlc report in asp.net mvc

I am using RDLC for reports loaded into ASP.NET MVC.
I tried to filter the results between two dates, but when I type the following query below I get the following error:
"the new command text returns data with schema different from the schema of the main query. Check your query's command text if this is not desired."
Can you help me on how to do it?
SELECT
SiparisKalems.SiparisKalemId,
SiparisKalems.Siparisid,
SiparisKalems.SiparisKalemTarih,
SiparisKalems.SiparisKalemAdet,
SiparisKalems.SiparisKalemFiyat,
SiparisKalems.SiparisKalemToplam,
SiparisKalems.Urunid,
Uruns.Urunid AS Expr1,
Uruns.UrunAdi,
Uruns.UrunFiyat,
Uruns.UrunGorsel,
Uruns.Kategoriid,
Uruns.Durum
FROM
SiparisKalems
INNER JOIN Uruns ON SiparisKalems.Urunid = Uruns.Urunid
WHERE
(
SiparisKalems.SiparisKalemTarih >= #Param1
AND
SiparisKalems.SiparisKalemTarih <= #Param2
)
ORDER BY
SiparisKalems.SiparisKalemTarih DESC
CREATE TABLE [dbo].[SiparisKalems](
[SiparisKalemId] [int] NOT NULL IDENTITY(1,1),
[Siparisid] [int] NOT NULL,
[SiparisKalemTarih] [datetime] NOT NULL,
[SiparisKalemAdet] [int] NOT NULL,
[SiparisKalemFiyat] [decimal](18, 2) NOT NULL,
[SiparisKalemToplam] [decimal](18, 2) NOT NULL,
[Urunid] [int] NOT NULL,
CONSTRAINT PK_dbo.SiparisKalems PRIMARY KEY CLUSTERED ( [SiparisKalemId] ),
CONSTRAINT FK_dbo.SiparisKalems_dbo.Siparislers_Siparisid ([Siparisid]) REFERENCES [dbo].[Siparislers] ([Siparisid]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.SiparisKalems_dbo.Uruns_Urunid] FOREIGN KEY([Urunid]) REFERENCES [dbo].[Uruns] ([Urunid]) ON DELETE CASCADE
)
CREATE TABLE [dbo].[Uruns](
[Urunid] [int] NOT NULL IDENTITY(1,1),
[UrunAdi] [varchar](30) NOT NULL,
[UrunFiyat] [decimal](18, 2) NOT NULL,
[UrunGorsel] [varchar](250) NOT NULL,
[Kategoriid] [int] NOT NULL,
[Durum] [bit] NOT NULL,
CONSTRAINT [PK_dbo.Uruns] PRIMARY KEY ( [Urunid] ),
CONSTRAINT [FK_dbo.Uruns_dbo.Kategoris_Kategoriid] FOREIGN KEY([Kategoriid]) REFERENCES [dbo].[Kategoris] ([Kategoriid]) ON DELETE CASCADE
)

Audit history of sql child table

I'm recording all insert and update on TaskDetail table using a trigger,Now I want to assign multiple staff to a task, But if staff id stored in different child table how can I track audit history, I have considered storing staff id as comma separated values but child table is always a good option.
In TaskStaff table multiple staff will have same taskId
CREATE TRIGGER [dbo].[TaskDetail_History_Trigger]
ON [dbo].[TaskDetail]
FOR Insert,UPDATE
AS
INSERT INTO TaskHistory SELECT * FROM inserted
GO
ALTER TABLE [dbo].[ProductionDetail] ENABLE TRIGGER [Task_History_Trigger]
GO
CREATE TABLE [dbo].[TaskDetail](
[Id] [int] IDENTITY(1,1) NOT NULL,
[StaffId] [int] NULL,
CONSTRAINT [PK_ProductionDetail_1] PRIMARY KEY CLUSTERED
(
[Id] ASC
)
CREATE TABLE [dbo].[TaskHistory](
[HistoryId] [int] IDENTITY(1,1) NOT NULL,
[Id] [int] NOT NULL,
[StaffId] [int] NULL,
CONSTRAINT [PK_ProductionDetail_1] PRIMARY KEY CLUSTERED
(
[Id] ASC
)
CREATE TABLE [dbo].[TaskStaff](
[Id] [int] IDENTITY(1,1) NOT NULL,
[TaskId] [int] NOT NULL,
[StaffId] [int] NOT NULL,
CONSTRAINT [PK_ProductionDetailStaff] PRIMARY KEY CLUSTERED
(
[Id] ASC
)

Can a value be a primary and a foreign key?

I have the following tables in my SQL Server database.
Customer is a subtype of User thus I made a reference from Customer to User.
I also want to link my customer to my reservation. I'd like to use the Foreign key in the Customer table as a PK for this relation. When I write this out in SQL Server, I get this error under "(userid)":
Invalid column 'userid'
How can I make this relation?
Create table [dbo].[User]
(
[id] int PRIMARY KEY IDENTITY (1,1) NOT NULL,
[name] varchar(50) NOT NULL,
[password] nvarchar(100) NOT NULL,
)
Create table [dbo].[Customer]
(
[userid] int FOREIGN KEY REFERENCES [dbo].[User](id) NOT NULL,
[street] varchar(40) NOT NULL,
[housenumber] varchar(10) NOT NULL,
[postalcode] varchar(10) NOT NULL,
[phonenumber] varchar(20) NOT NULL,
[email] varchar(30) NOT NULL,
)
Create table [dbo].[Reservation]
(
[id] int PRIMARY KEY IDENTITY (1,1) NOT NULL,
[datum] date NOT NULL,
[prijs] decimal NOT NULL,
[levertijd] datetime NOT NULL,
[ophaaltijd] datetime NOT NULL,
[leverAdres] varchar(60) NOT NULL,
[klantId] int FOREIGN KEY REFERENCES [dbo].[Customer](userid) NOT NULL
)
yes this is possible, try it like this
Create table [dbo].[Customer]
(
[userid] int not null,
[street] varchar(40) NOT NULL,
[housenumber] varchar(10) NOT NULL,
[postalcode] varchar(10) NOT NULL,
[phonenumber] varchar(20) NOT NULL,
[email] varchar(30) NOT NULL,
constraint PK_UserID primary key ([userid]),
constraint FK_Customer_User foreign key (userid) references [User] (id)
)
But I have to say that userid seems like an odd primary key for a table called Customer
I would so something like this :
Create table [dbo].[Customer]
(
[CustomerID] int not null identity,
[userid] int not null,
[street] varchar(40) NOT NULL,
[housenumber] varchar(10) NOT NULL,
[postalcode] varchar(10) NOT NULL,
[phonenumber] varchar(20) NOT NULL,
[email] varchar(30) NOT NULL,
constraint PK_CustomerID primary key ([CustomerID]),
constraint FK_Customer_User foreign key (userid) references [User] (id)
)
Create table [dbo].[Reservation]
(
[id] int PRIMARY KEY IDENTITY (1,1) NOT NULL,
[datum] date NOT NULL,
[prijs] decimal NOT NULL,
[levertijd] datetime NOT NULL,
[ophaaltijd] datetime NOT NULL,
[leverAdres] varchar(60) NOT NULL,
[klantId] int FOREIGN KEY REFERENCES [dbo].[Customer](customerid) NOT NULL
)

How to assign 2 default values to SQL table column?

I am designing user registration table with below columns.
CREATE TABLE [dbo].[NCT_UserRegistration]
(
[User_Id] [int] IDENTITY(1,1) NOT NULL,
[User_EmailId] [varchar](255) NULL,
[User_Password] [varchar](512) NULL,
[User_Name] [varchar](255) NULL,
[User_MobileNum] [varchar](20) NULL,
[User_Status] [varchar](15) NULL,
[User_Role] [varchar](20) NULL,
[User_CreatedDate] [timestamp] NULL,
[User_UpdatedDate] [datetime] NULL,
[Name] [varchar](30) NULL
)
My requirement for the status and role as below.
status VARCHAR(15) Index, Enumeration of ENABLED, DISABLED.
role VARCHAR(20) Enumeration of SUPER_ADMIN and PROJECT_ADMIN
What I understood from above is status should take only Enabled or Disabled and same with role also. How can I design my table to make sure it takes only those two values? Also is there any way for example if I supply 1 then it is ENABLED and 0 for DISABLED.
May I get some ideas here? Any help would be appreciated. Thank you
You need to use CHECK CONSTRAINT to limit to specific values
CREATE TABLE [dbo].[NCT_UserRegistration](
[User_Id] [int] IDENTITY(1,1) NOT NULL,
[User_EmailId] [varchar](255) NULL,
[User_Password] [varchar](512) NULL,
[User_Name] [varchar](255) NULL,
[User_MobileNum] [varchar](20) NULL,
[User_Status] [varchar](15) NULL CONSTRAINT chk_Status CHECK ([User_Status] IN ('ENABLED', 'DISABLED')),
[User_Role] [varchar](20) NULL CONSTRAINT chk_Role CHECK ([User_Role] IN ('SUPER_ADMIN','DISABLED')),
[User_CreatedDate] [timestamp] NULL,
[User_UpdatedDate] [datetime] NULL,
[Name] [varchar](30) NULL
)
For enumeration you will have to handle at front end or while retriving values from table which is an extra step.
SELECT CASE WHEN [User_Status] = 1 THEN 'ENABLED' WHEN [User_Status] = 0 THEN 'DISABLED' END As UserStratus
FROM [dbo].[NCT_UserRegistration]
Can you try adding constraint as below for status field. If its working then apply the same to ROLE field.
alter table NCT_UserRegistration
add (STATUS VARCHAR(15) default 'ENABLED',
constraint conSTATUS check (STATUS in ('ENABLED', 'DISABLED')))
There are two possible approaches.
Check constraints - #mh2017 has explained this well in his answer.
Looking at the conversation that seems to fit your requirements better, but just for the sake of sharing idea, I will mention -
Foreign key constraint (FK)- If it is acceptable to modify the User_Status and User_Role columns to be of type tinyint (or similar number type), you can store just the ids in these and create enumeration (aka mapping tables) to store what the ids represent.
Create FK on User_Status and User_Role in NCT_UserRegistration to refer to the enumeration tables.
FKC ensures that the referring column (User_Status and User_Role in NCT_UserRegistration) cannot have value other than those listed in the referred to column (the respective id columns in the enumeration tables)
This Foreign key vs check constraint for integrity post also describes few benefits of using FK over check constraint
Here is a sample code showing foreign key approach
CREATE TABLE [dbo].[NCT_UserRegistration](
[User_Id] [int] IDENTITY(1,1) NOT NULL,
[User_EmailId] [varchar](255) NULL,
[User_Password] [varchar](512) NULL,
[User_Name] [varchar](255) NULL,
[User_MobileNum] [varchar](20) NULL,
[User_Status] tinyint NULL, -- I changed this from varchar to tinyint
[User_Role] tinyint NULL, -- I changed this from varchar to tinyint
[User_CreatedDate] [timestamp] NULL,
[User_UpdatedDate] [datetime] NULL,
[Name] [varchar](30) NULL
)
create table StatusEnumeration
(
StatusId tinyint,
Description varchar(10)
constraint pk_StatusEnumeration__StatusId primary key clustered (StatusId)
)
insert into StatusEnumeration(StatusId, Description)
values
(0, 'Disabled'),
(1, 'Enabled')
create table RoleEnumeration
(
RoleId tinyint,
Description varchar(20)
constraint pk_RoleEnumeration__RoleId primary key clustered (RoleId)
)
insert into RoleEnumeration(RoleId, Description)
values
(0, 'SUPER_ADMIN '),
(1, 'PROJECT_ADMIN')
alter table NCT_UserRegistration
add constraint fk_NCT_UserRegistration__StatusEnumeration_StatusId foreign key (User_Status)
references StatusEnumeration (StatusId)
go
alter table NCT_UserRegistration
add constraint fk_NCT_UserRegistration__RoleEnumeration_RoleId foreign key (User_Role)
references RoleEnumeration (RoleId)
go

SQL foreign key constraint with additional column value check

I have this situation
CREATE TABLE [dbo].[Customer]
(
Id INT IDENTITY(1,1) NOT NULL,
IsWholesaler BIT NOT NULL,
Name NVARCHAR(255) NOT NULL
)
CREATE TABLE [dbo].[WholesalerUser]
(
Id INT IDENTITY(1,1) NOT NULL,
CustomerId INT NOT NULL,
UserId INT NOT NULL
)
CREATE TABLE [dbo].[User]
(
Id INT IDENTITY(1,1) NOT NULL,
Name NVARCHAR(255)
)
One Customer which has IsWholesaler column set to true can have multiple users.
I have WholesalerUser table for this purpose but the Foreign key WholesalerUser.CustomerId is attached to Customer.Id but how to check the column IsWholesaler = 1 ?
Foreign key can be defined over several columns at once.
Add a column IsWholesaler to the WholesalerUser.
Add a check constraint to make sure that it is always 1.
Define foreign key over two columns (CustomerId, IsWholesaler).
To define such foreign key the Customer table should have either primary key as (ID, IsWholesaler), or a separate unique index on (ID, IsWholesaler).
Table Customer
CREATE TABLE [dbo].[Customer](
[Id] [int] IDENTITY(1,1) NOT NULL,
[IsWholesaler] [bit] NOT NULL,
[Name] [nvarchar](255) NOT NULL,
CONSTRAINT [PK_Customer] PRIMARY KEY CLUSTERED
(
[Id] ASC
))
Unique index to support foreign key constraint:
CREATE UNIQUE NONCLUSTERED INDEX [IX_ID_IsWholesaler] ON [dbo].[Customer]
(
[Id] ASC,
[IsWholesaler] ASC
)
Table WholesalerUser
CREATE TABLE [dbo].[WholesalerUser](
[Id] [int] IDENTITY(1,1) NOT NULL,
[CustomerId] [int] NOT NULL,
[IsWholesaler] [bit] NOT NULL,
[UserId] [int] NOT NULL,
CONSTRAINT [PK_WholesalerUser] PRIMARY KEY CLUSTERED
(
[Id] ASC
))
Foreign key
ALTER TABLE [dbo].[WholesalerUser] WITH CHECK
ADD CONSTRAINT [FK_WholesalerUser_Customer]
FOREIGN KEY([CustomerId], [IsWholesaler])
REFERENCES [dbo].[Customer] ([Id], [IsWholesaler])
GO
ALTER TABLE [dbo].[WholesalerUser]
CHECK CONSTRAINT [FK_WholesalerUser_Customer]
GO
Check constraint
ALTER TABLE [dbo].[WholesalerUser] WITH CHECK
ADD CONSTRAINT [CK_WholesalerUser]
CHECK (([IsWholesaler]=(1)))
GO
ALTER TABLE [dbo].[WholesalerUser]
CHECK CONSTRAINT [CK_WholesalerUser]
GO
ALTER TABLE [dbo].[WholesalerUser]
ADD CONSTRAINT [DF_WholesalerUser_IsWholesaler]
DEFAULT ((1)) FOR [IsWholesaler]
GO