Adding in a primary key to an SQL view - sql

I have created a view in a SQL Server database which is just a join of two tables.
Is there any way I can insert a unique primary key into the rows of this view ...or I'm not sure how I can specify one of the column names to be a primary key...any ideas?
Thanks

You would have to create materialized (indexed) view in order to be able to add unique index. But you can't create PK constraint.
CREATE VIEW v_test
WITH SCHEMABINDING --optional
AS
SELECT id from table
GO
CREATE UNIQUE CLUSTERED INDEX idx_id
ON v_test (id)
GO

Related

How to add unique index and delete duplicates

I want to add a unique index in my DB, but some data has already been duplicated.
I am trying out this using a test table before applying to the actual one.
It seems that if there are duplicated rows then we wouldn't be able to add the unique constraint.
I want to add the unique constraint and do not care which row gets deleted.
When I run the following
ALTER TABLE test_user ADD CONSTRAINT test_constraint UNIQUE (personid);
I am getting this error
ERROR: could not create unique index "test_constraint"
DETAIL: Key (personid)=(1) is duplicated.
SQL state: 23505
What would be the best way to achieve this? I am using Postgres as the DB
Create a copy of the table eliminating duplicates:
CREATE TABLE test_user_new (LIKE test_user);
INSERT INTO test_user_new
SELECT DISTINCT ON (id) *
FROM test_user;
ALTER TABLE test_user_new PRIMARY KEY (personid);
Then replace the original table:
DROP TABLE test_user;
ALTER TABLE test_user_new RENAME TO test_user;

Drop one to one relationship tables

I created two tables which are 1 to 1.
So one table has foreign key from another.
How can I drop the tables? I did not use on delete cascade while creating tables.
So I either have to somehow change it, or IDK..
I have done this.
CREATE TABLE hotel(
id_hotel
...
)
CREATE TABLE Manager(
ID_Manager
...
id_hotel FOREIGN KEY ...
)
and then I added
ALTER TABLE Hotel ADD id_manager INT NOT NULL;
ALTER TABLE Hotel ADD FOREIGN KEY (id_manager) REFERENCES Manager(id_manager);
You first have to drop the table with the foreign key in the column, eg: If you have 2 entities one named driving_license and the other person, and you store the id from person in the table driving_license, you have to first drop the table driving_license
Or if you are using MySQL: You can write:
SET_FOREIGN_KEY_CHECKS=0;
//Drop however you want
SET_FOREIGN_KEY_CHECKS=1
For MSSQL you can use:
ALTER TABLE <yourtablename> NOCHECK CONSTRAINT ALL
And then drop your table

Set identity off in azure sql table

I have a table which includes an identity column but i cant remove the identity property.
Is there a way to disable it? Or a way to make a copy of the entire table without identity property?
Note that you may not be able to drop the column if it referenced by a clustered index, and you can't drop all clustered indexes for a table because SqlAzure tables must always have a clustered index.
This means that you may have to jump through the following hoops (for at least your last clustered index, which may well be your primary key):
rename your clustered index
create a temp version of the table (with a new clustered index)
copy the data from the current table
drop the current table
rename the temp table to the current name
This roughly looks like this:
-- Rename clustered index
EXECUTE sp_rename N'PK_My_Current_PK', N'PK_My_Current_PK_OLD', 'OBJECT'
-- If you have any FK constraints on the table, then drop them
ALTER TABLE dbo.MyTable DROP CONSTRAINT FK_My_Foreign_Key
-- Create the new version of your table - because this is SQLAzure it must have a clustered index
CREATE TABLE dbo.tmp_MyTable (
MyID int NOT NULL,
CONSTRAINT PK_My_Current_PK PRIMARY KEY CLUSTERED (MyID)
)
-- Copy the data into the temp table from the old table
INSERT INTO dbo.tmp_MyTable (MyID)
SELECT MyID FROM dbo.MyTable
-- Drop the old table
DROP TABLE dbo.MyTable
-- Rename the new table
EXECUTE sp_rename N'tmp_MyTable', N'MyTable', 'OBJECT'
-- Recreate any foreign key constraints
ALTER TABLE dbo.MyTable WITH CHECK ADD FK_My_Foreign_Key FOREIGN KEY (MyID)
REFERENCES dbo.MyForeignTable (MyID)
Hope that helps
A
Edit: As #PhilBolduc pointed out SqlAzure tables require a clustered index, not a primary key. I've amended the terminology above accordingly - the principle of the answer still remains.
You can not remove an Identity column without dropping it unfortunately. Alternetivly add a new column with a temp name, update the new column value and then drop the previous column.
ALTER TABLE dbo.tablename ADD newcolumnname INT
UPDATE dbo.tablename SET newcolumnname = oldcolumnname FROM dbo.tablename
ALTER TABLE dbo.tablename DROP COLUMN oldcolumnname
that should do it. unless i have misunderstood your questions?

Drop Default Clustered Index Without Knowing it's Name

I wrote a script that creates some tables (it previously drops them if they exist) and then tries to create two indexes on each table.
The first index uses the Primary Key column to create a non-clustered index, and the second uses another column to create the clustered indexed. This is because the primary key column is a GUID instead of an int.
How can I drop the default index if I don't know it's name? or how can I specify a name for the primary key column index so I can drop it? Or better yet, how can I specify the 2 index i need right in the Create Table statement?
SELECT * FROM sys.indexes
However, I'm not understanding where in your process you actually have to drop an index.
You said you are creating some tables and then creating two indexes on each table.
If you are DROPping existing tables at the beginning, any indexes are automatically dropped.
There is no such thing as a default index.
Tables can either be heaps or clustered indexes. If you drop the clustered index, the table will be converted to a heap and any non-clustered indexes will have to be updated to point to the data in the unordered heap.
You can create like this all at once:
CREATE TABLE dbo.tbl
(
Id int NOT NULL IDENTITY (1, 1) CONSTRAINT UK_ID UNIQUE CLUSTERED,
SomeUUID UNIQUEIDENTIFIER NOT NULL CONSTRAINT PK_SomeUUID PRIMARY KEY NONCLUSTERED
)
Here's a SQLFiddle: http://sqlfiddle.com/#!6/d759e/12
You can define the two indices right after you create the table:
CREATE TABLE dbo.YourTable ( ...... )
GO
ALTER TABLE dbo.YourTable
ADD CONSTRAINT PK_YourTable PRIMARY KEY NONCLUSTERED (YourGuidColumn)
****************
this is crucial ! Otherwise, your PK will be clustered!
CREATE CLUSTERED INDEX IX01_YourTable ON dbo.YourTable(YourOtherColumn)
or even better:
CREATE UNIQUE CLUSTERED INDEX IX01_YourTable ON dbo.YourTable(YourOtherColumn)
That should create a non-clustered primary key and a separate (preferably unique) clustered index on a separate column.

Can you create a table with indexes at the same time?

I'd like to create a table:
CREATE TABLE sfc.OpenId (
Url VARCHAR(255) PRIMARY KEY,
UserGuid uniqueidentifier NOT NULL references dbo.aspnet_users(userId),
)
...with an index on UserGuid.
Is it possible to create that index in the create table statement?
You can do that if the index on UserGuid is a unique index, via UNIQUE constraint. Otherwise, no.
Is it possible to create that index in the create table statement?
No, only constraints can be created within the CREATE TABLE syntax.
f not defined otherwise, the primary key will automatically be a CLUSTERED index - but that doesn't cover the userguid column. The CREATE INDEX syntax needs to be a separate statement otherwise.
Can you clarify why?
You can use transactions with DDL in SQL server and for most purposes this is equivalent to doing it at the same time.