how to alter table Composite primary key - sql-server

CREATE TABLE [dbo].[INVS_ITEM_LOCATIONS]
([DEPARTMENT_CODE] [varchar](3) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[IM_INV_NO] [numeric](10, 0) NOT NULL,
[LOCATION_CODE] [varchar](2) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[CURR_QTY] [numeric](10, 0) NOT NULL CONSTRAINT [DF__INVS_ITEM__CURR___1352D76D] DEFAULT ((0)),
[DO_QTY] [numeric](10, 0) NOT NULL CONSTRAINT [DF__INVS_ITEM__DO_QT__1446FBA6] DEFAULT ((0)),
[ALLOC_QTY] [numeric](10, 0) NOT NULL CONSTRAINT [DF__INVS_ITEM__ALLOC__153B1FDF] DEFAULT ((0)),
[YOB_QTY] [numeric](10, 0) NOT NULL CONSTRAINT [DF__INVS_ITEM__YOB_Q__162F4418] DEFAULT ((0)),
[FOC_QTY] [numeric](10, 0) NULL CONSTRAINT [DF__INVS_ITEM__FOC_Q__17236851] DEFAULT ((0)),
[USER_CREATED] [varchar](25) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[DATE_CREATED] [datetime] NOT NULL,
[USER_MODIFIED] [varchar](25) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[DATE_MODIFIED] [datetime] NULL,
CONSTRAINT [INVS_ITEM_LOCATIONS_PK]
PRIMARY KEY CLUSTERED ([DEPARTMENT_CODE] ASC,
[IM_INV_NO] ASC, [LOCATION_CODE] ASC)
WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
This is my table structure ......how can I remove the composite primary key in table and also I should add foreign key to im_inv_no reference table is invs_location which contain im_inv_no and the department_code should be same primary key .pls help

To remove your composite primary key, use:
ALTER TABLE dbo.INVS_ITEM_LOCATIONS
DROP CONSTRAINT INVS_ITEM_LOCATIONS_PK
To add a foreign key, use this:
ALTER TABLE dbo.INVS_ITEM_LOCATIONS
ADD CONSTRAINT FK_INV_NO_REFERENCE
FOREIGN KEY(IM_INV_NO, DEPARTMENT_CODE)
REFERENCES dbo.invs_location(IM_INV_NO, DEPARTMENT_CODE)
These are all really basic beginner SQL questions - I would strongly recommend you read one of the various good SQL tutorials out there to get used to SQL first, before posting each and every single little question here....
W3Schools SQL Tutorial
Marc

You can create new tables with modifications you need, copy your data then renaming new talbes to the same names as old tables and deleting old ones. It is probably the most efficient way as well.

Related

I do not know what's wrong with my database. Displays errors

I created two tables. And I need to have two Ids in the second table of Friends. UserId is Id from the UserInformation table. FriendId is Id already in this table. I need to make a relationship between these two tables and correctly make FK and PK. I tried to do it myself but it screams what I did not do right here - REFERENCES [UserInformation] (UserId)
I need your help to do the job correctly
CREATE TABLE [dbo].[UserInformation]
(
[Id] [INT] IDENTITY(1,1) NOT NULL,
[Login] [VARCHAR](50) NOT NULL,
[Password] [VARCHAR](50) NOT NULL,
[FirstName] [NCHAR](10) NOT NULL,
[LastName] [NCHAR](10) NOT NULL,
[Email] [VARCHAR](50) NOT NULL,
[RegistrationDate] [DATETIME] NOT NULL,
[Groups] [VARCHAR](50) NOT NULL
)
GO
CREATE TABLE [dbo].[Friends]
(
[UserId] [INT] NOT NULL,
[FriendId] [INT] NOT NULL,
PRIMARY KEY (FriendId),
CONSTRAINT FK_UserInformationFriend
FOREIGN KEY (UserId) REFERENCES [UserInformation](UserId)
)
GO
ALTER TABLE [dbo].[UserInformation]
ADD CONSTRAINT [DF_UserInformation_RegistrationDate]
DEFAULT (GETDATE()) FOR [RegistrationDate]
GO
ALTER TABLE UserInformation
ADD CONSTRAINT DF_UserInformation_Login_Unique UNIQUE(Login)
GO
ALTER TABLE UserInformation
ADD CONSTRAINT DF_UserInformation_Email_Unique UNIQUE(Email)
GO
ALTER TABLE UserInformation
ADD CONSTRAINT [PK_UserInformation] PRIMARY KEY ([Id])
GO
ALTER TABLE Friends
ADD CONSTRAINT [PK_Friends] PRIMARY KEY ([UserId])
GO
First Change it as:
CREATE TABLE [dbo].[UserInformation](
[Id] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
[Login] [varchar](50) NOT NULL,
[Password] [varchar](50) NOT NULL,
[FirstName] [nchar](10) NOT NULL,
[LastName] [nchar](10) NOT NULL,
[Email] [varchar](50) NOT NULL,
[RegistrationDate] [datetime] NOT NULL,
[Groups] [varchar](50) NOT NULL
)
then:
CREATE TABLE [dbo].[Friends](
[UserId] [int] NOT NULL,
[FriendId] [int] NOT NULL,
PRIMARY KEY (FriendId),
CONSTRAINT FK_UserInformationFriend FOREIGN KEY (UserId)
REFERENCES [UserInformation](Id)
)
and Last:
ALTER TABLE [dbo].[UserInformation]
ADD CONSTRAINT [DF_UserInformation_RegistrationDate] DEFAULT
(getdate()) FOR [RegistrationDate]
GO
ALTER TABLE UserInformation
ADD CONSTRAINT DF_UserInformation_Login_Unique UNIQUE (Login)
GO
ALTER TABLE UserInformation
ADD CONSTRAINT DF_UserInformation_Email_Unique UNIQUE (Email)
No need these as primary is already set for both tables:
ALTER TABLE UserInformation
ADD CONSTRAINT [PK_UserInformation] PRIMARY KEY ([Id])
GO
ALTER TABLE Friends
ADD CONSTRAINT [PK_Friends] PRIMARY KEY ([UserId])
GO
Note: if you need multiple primary keys then go for composite primarys:
primary key (FriendId, UserId)

GUID_PK in SQL Server

When I execute this query, I am getting an error
Cannot find data type dbo.GUID_PK
For this should I create table for CandidateRoleID or what else should I do here?
But, when I googled it I found it saying SQL Server stores GUID. How could I access it or what is the correct way of declaring this table? I searched in google about GUID_PK.
But didn't find any syntax or explanation. Thanks in advance.
CREATE TABLE [dbo].[tbl]
(
[CandidateRoleID] [dbo].[GUID_PK] NOT NULL,
[CandidateID] [uniqueidentifier] NOT NULL,
[RoleID] [int] NOT NULL
);
The SQL server data type for a GUID is UNIQUEIDENTIFIER.
Your script should be:
CREATE TABLE [dbo].[tbl](
[CandidateRoleID] [uniqueidentifier] NOT NULL,
[CandidateID] [uniqueidentifier] NOT NULL,
[RoleID] [int] NOT NULL,
CONSTRAINT PK_Tbl PRIMARY KEY (CandidateRoleID));
If you want it to be 'automatically' created, similar to an integer identity column, give it a default:
CREATE TABLE [dbo].[tbl](
[CandidateRoleID] [uniqueidentifier] NOT NULL DEFAULT NEWID(),
[CandidateID] [uniqueidentifier] NOT NULL,
[RoleID] [int] NOT NULL,
CONSTRAINT PK_Tbl PRIMARY KEY (CandidateRoleID));
CREATE TABLE [dbo].[tbl](
[CandidateRoleID] [uniqueidentifier] primary key NOT NULL,
[CandidateID] [uniqueidentifier] NOT NULL,
[RoleID] [int] NOT NULL,
);
In SQL server GUID is uniqueidentifier data type.
There is no data type 'GUID_PK' in sql server.
GUID is an acronym for Global Unique ID(entifier) and is a unique 16
byte number. The term GUID and UNIQUEIDENTIFIER are often
interchangeable within the SQL Server community.
If you need to auto-generate uniqueidentifier value in your table during data insert, the consider adding default value to the uniqueidentifier data-type.
CREATE TABLE #tbl(
[CandidateRoleID] [uniqueidentifier] NOT NULL DEFAULT NEWID(),
[CandidateID] [uniqueidentifier] NOT NULL DEFAULT NEWID(),
[RoleID] [int] NOT NULL);
GO
INSERT INTO #tbl (ROLEID) SELECT (1)
CandidateRoleID CandidateID RoleID
F20AE15E-8D97-4042-8AA8-DD7BCB0EB6D6 FAE29358-BD34-4BFE-800B-E332375E020E 1

Foreign Key Relationship possible performance issues

We have a User table with a GUID aka uniqueidentifier as the PK. Nearly every other table in the database ties back to this table with 4 FK references. When I look at the DB diagram it looks like a 100 lane highway coming out of the User table because of the CreatedBy, CreatedByProxy, UpdatedBy, UpdatedByProxy foreign keys.
I was brought onto this project after it was already past inception and in production already, and with performance issues.
I was wondering if this DB pattern will cause major growing pains when the user list starts to grow. Are we going to run into more performance issues in the future because of this, or if we create an index will keeping the foreign keys cause the indexes to be huge. I just don't remember a website that I've worked on before that had the foreign keys to this extent before, and I'm worried about future proofing/fixing it. I'm really just trying to justify whether or not to keep or remove the foreign keys or modify the structure so that
User Table:
CREATE TABLE [dbo].[aspnet_Users](
[ApplicationId] [uniqueidentifier] NOT NULL,
[UserId] [uniqueidentifier] NOT NULL, -- ***** Here is the PK
[UserName] [nvarchar](256) NOT NULL,
[LoweredUserName] [nvarchar](256) NOT NULL,
[MobileAlias] [nvarchar](16) NULL,
[IsAnonymous] [bit] NOT NULL,
[LastActivityDate] [datetime] NOT NULL,
PRIMARY KEY NONCLUSTERED
(
[UserId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
One other Table that references User:
CREATE TABLE [dbo].[Email](
[EmailId] [int] IDENTITY(1,1) NOT NULL,
[PersonId] [int] NULL,
[InstitutionId] [int] NULL,
[EmailTypeId] [int] NOT NULL,
[EmailAddress] [varchar](254) NOT NULL,
[IsFlaggedImportant] [bit] NOT NULL,
[IsDistrictRecord] [bit] NOT NULL,
[IsActive] [bit] NOT NULL,
[Created] [datetime] NOT NULL,
[CreatedBy] [uniqueidentifier] NOT NULL, -- ***** FK 1
[Proxy] [uniqueidentifier] NULL, -- ***** FK 2
[Updated] [datetime] NULL,
[UpdatedBy] [uniqueidentifier] NULL, -- ***** FK 3
[UpdateProxy] [uniqueidentifier] NULL, -- ***** FK 4
CONSTRAINT [PK_Email] PRIMARY KEY CLUSTERED
(
[EmailId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Email] ADD CONSTRAINT [DF_Email_IsPrimary] DEFAULT ((0)) FOR [IsFlaggedImportant]
GO
ALTER TABLE [dbo].[Email] ADD CONSTRAINT [DF_Email_IsDistrictRecord] DEFAULT ((0)) FOR [IsDistrictRecord]
GO
ALTER TABLE [dbo].[Email] ADD CONSTRAINT [DF_Email_IsActive] DEFAULT ((0)) FOR [IsActive]
GO
ALTER TABLE [dbo].[Email] ADD CONSTRAINT [DF_Email_Created] DEFAULT (getdate()) FOR [Created]
GO
ALTER TABLE [dbo].[Email] WITH CHECK ADD CONSTRAINT [FK_Email_CreatedByUser] FOREIGN KEY([CreatedBy])
REFERENCES [dbo].[aspnet_Users] ([UserId])
GO
ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_CreatedByUser]
GO
ALTER TABLE [dbo].[Email] WITH CHECK ADD CONSTRAINT [FK_Email_EmailType] FOREIGN KEY([EmailTypeId])
REFERENCES [dbo].[EmailType] ([EmailTypeId])
GO
ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_EmailType]
GO
ALTER TABLE [dbo].[Email] WITH CHECK ADD CONSTRAINT [FK_Email_Institution] FOREIGN KEY([InstitutionId])
REFERENCES [dbo].[Institution] ([InstitutionId])
GO
ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_Institution]
GO
ALTER TABLE [dbo].[Email] WITH CHECK ADD CONSTRAINT [FK_Email_Person] FOREIGN KEY([PersonId])
REFERENCES [dbo].[Person] ([PersonId])
GO
ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_Person]
GO
ALTER TABLE [dbo].[Email] WITH CHECK ADD CONSTRAINT [FK_Email_ProxyByUser] FOREIGN KEY([Proxy])
REFERENCES [dbo].[aspnet_Users] ([UserId])
GO
ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_ProxyByUser]
GO
ALTER TABLE [dbo].[Email] WITH CHECK ADD CONSTRAINT [FK_Email_ProxyUpdateByUser] FOREIGN KEY([UpdateProxy])
REFERENCES [dbo].[aspnet_Users] ([UserId])
GO
ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_ProxyUpdateByUser]
GO
ALTER TABLE [dbo].[Email] WITH CHECK ADD CONSTRAINT [FK_Email_UpdatedByUser] FOREIGN KEY([UpdatedBy])
REFERENCES [dbo].[aspnet_Users] ([UserId])
GO
ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_UpdatedByUser]
GO
ALTER TABLE [dbo].[Email] WITH CHECK ADD CONSTRAINT [CK_Email_Person_Or_Institution] CHECK (([PersonId] IS NOT NULL AND [InstitutionId] IS NULL OR [PersonId] IS NULL AND [InstitutionId] IS NOT NULL))
GO
ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [CK_Email_Person_Or_Institution]
GO
I was brought onto this project after it was already past inception
and in production already, and with performance issues.
You don't say what those performance issues are, so I'll confine my remarks to the foreign keys.
When I look at the DB diagram it looks like a 100 lane highway coming
out of the User table because of the CreatedBy, CreatedByProxy,
UpdatedBy, UpdatedByProxy foreign keys.
When I see columns like that, I have to ask whether they contain information about the business entity--a person's email address in this case--or information about the row that entity happens to inhabit.
It looks like they contain information about the row. (But I could be wrong.)
If they do contain information about the row, and they're not needed in most queries, you can move them to another table. If you move them, you have to be more careful about inserting rows into dbo.Email.
CREATE TABLE [dbo].[Email](
[EmailId] [int] IDENTITY(1,1) NOT NULL,
[PersonId] [int] NULL,
[InstitutionId] [int] NULL,
[EmailTypeId] [int] NOT NULL,
[EmailAddress] [varchar](254) NOT NULL,
[IsFlaggedImportant] [bit] NOT NULL,
[IsDistrictRecord] [bit] NOT NULL,
[IsActive] [bit] NOT NULL,
CONSTRAINT [PK_Email] PRIMARY KEY CLUSTERED ([EmailID])
);
CREATE TABLE [dbo].[Email_audit](
[EmailID] [int] PRIMARY KEY REFERENCES [Email] ([EmailID]),
[Created] [datetime] NOT NULL,
[CreatedBy] [uniqueidentifier] NOT NULL, -- ***** FK 1
[Proxy] [uniqueidentifier] NULL, -- ***** FK 2
[Updated] [datetime] NULL,
[UpdatedBy] [uniqueidentifier] NULL, -- ***** FK 3
[UpdateProxy] [uniqueidentifier] NULL -- ***** FK 4
);
These kinds of tables are commonly used to provide some kind of audit trail. Whether you can cascade deletes is application-dependent. In some apps, you need to store the email address here instead of the email id number, and use no foreign key references. (This allows deleting rows from dbo.Email while retaining some information about what's happened to the row.)
Moving these columns reduces the width of a row in dbo.Email by about 80 bytes, not counting overhead. That usually improves performance of SELECT statements in the tables they're moved from. (Narrower rows; more rows per page.)
Moving these columns complicates inserting and updating rows, though. All inserts and updates have to hit two tables.

Unique row constraint in SQL Server

I have the following table
CREATE TABLE [dbo].[LogFiles_Warehouse](
[id] [int] IDENTITY(1,1) NOT NULL,
[timestamp] [datetime] NOT NULL,
[clientNr] [int] NOT NULL,
[server] [nvarchar](150) COLLATE Latin1_General_CI_AS NOT NULL,
[storeNr] [int] NOT NULL,
[account] [nvarchar](50) COLLATE Latin1_General_CI_AS NOT NULL,
[software] [nvarchar](300) COLLATE Latin1_General_CI_AS NOT NULL,
CONSTRAINT [PK_Astoria_LogFiles_Warehouse] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
And want to avoid having duplicate rows in my table. I thought about creating a UNIQUE index on the complete table, but then SQL Manager Studio tells me that this is not possible because the key would be too large.
Is there another way I could enforce unique rows over all columns, apart from indexes?
Create a UNIQUE index on hashed values:
CREATE TABLE [dbo].[LogFiles_Warehouse]
(
[id] [int] IDENTITY(1,1) NOT NULL,
[timestamp] [datetime] NOT NULL,
[clientNr] [int] NOT NULL,
[server] [nvarchar](150) COLLATE Latin1_General_CI_AS NOT NULL,
[storeNr] [int] NOT NULL,
[account] [nvarchar](50) COLLATE Latin1_General_CI_AS NOT NULL,
[software] [nvarchar](300) COLLATE Latin1_General_CI_AS NOT NULL,
serverHash AS CAST(HASHBYTES('MD4', server) AS BINARY(16)),
accountHash AS CAST(HASHBYTES('MD4', account) AS BINARY(16)),
softwareHash AS CAST(HASHBYTES('MD4', software) AS BINARY(16))
)
CREATE UNIQUE INDEX
UX_LogFilesWarehouse_Server_Account_Software
ON LogFiles_Warehouse (serverHash, accountHash, softwareHash)
Use triggers + a smaller non unique index over the most distinguishing ields to helop aleviate the table s can problem.
This goes down a lot into a bad database design to start with. Fields like Software, Account do not belong into that table to start with (or if account, then not client nr). Your table is only so wisde because you arelady violate database design basics to start with.
Also, to abvoid non unique fields, you have NT to have the Id field in the unique testing otherwise you ont ever have doubles to start with.

How can I force one to one relationship on SQL Server 2008 or 2008 R2

Here is my scenario on SQL Server 2008 R2:
This is my first table:
CREATE TABLE [dbo].[Foos](
[FooId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NULL,
CONSTRAINT [PK_Foos] PRIMARY KEY CLUSTERED
(
[FooId] ASC
)
) ON [PRIMARY]
This is the second table which has a relationship to Foos table:
CREATE TABLE [dbo].[Bars](
[BarId] [int] IDENTITY(1,1) NOT NULL,
[FooId] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
CONSTRAINT [PK_Bars] PRIMARY KEY CLUSTERED
(
[BarId] ASC
)
) ON [PRIMARY]
Go
ALTER TABLE [dbo].[Bars] WITH CHECK ADD CONSTRAINT [FK_Bars_Foos] FOREIGN KEY([FooId])
REFERENCES [dbo].[Foos] ([FooId])
ON DELETE CASCADE
GO
But it is not one to one. What should I do to force this to be one to one relationship? Should I use check constraints?
Add a unique constraint to FooId in Bars.
However, you don't need BarID then because they have the same key. So it looks like this
CREATE TABLE [dbo].[Bars] (
[FooId] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
CONSTRAINT [PK_Bars] PRIMARY KEY CLUSTERED (FooId),
CONSTRAINT [FK_Bars_Foos] FOREIGN KEY([FooId])
REFERENCES [dbo].[Foos] ([FooId])
ON DELETE CASCADE
)
GO
However again, you don't need Bars at all: it is one table...
You can keep Identity column(BarID) also. Then Unique key will help you out from this problem.
IF NOT EXISTS(SELECT OBJECT_ID from sys.objects WHERE name ='foo_bars')
alter table bars add constraint foo_bars unique(fooid)

Resources