ABS as constraint in SQL - sql

Is it possible to have absolute value as a constraint in sql 2008. Something like this:
ALTER TABLE [dbo].[myTable] WITH NOCHECK ADD
CONSTRAINT [IX_Blah] UNIQUE NONCLUSTERED
(
ABS([ID_1]),
[ID_2]
) ON [PRIMARY]
In my table ID_1 can be negative. So I need make sure I don't have records with
ID_1 ID_2
1 1
-1 1
They should be considered the same and not be allowed.
Thank you.

I'm assuming you've tried it and got an error.
No, unique constraints cannot include formulas. You can however, have a unique constraint on a computed column:
ALTER TABLE myTable
ADD ID_3 AS ABS(ID_1)
ALTER TABLE [myTable]ADD
CONSTRAINT [IX_Blah] UNIQUE NONCLUSTERED
(
[ID_3],
[ID_2]
)

Related

SQL indexes How to ensure insert of value

If I have the following index:
CREATE UNIQUE NONCLUSTERED INDEX IX_Contacts ON Contacts (User_ID) WHERE (IsDefault=1)
To make sure IsDefault is set.
How can I simultaneously ensure/require that IsDefault is always set?
Could you do something like this?
CREATE UNIQUE NONCLUSTERED INDEX IX_Contacts ON Contacts (User_ID) WHERE (IsDefault>1)
Make sure the IsDefault column does not allow NULL and create a default constraint with the desired default value, which will be used when the column is not explicitly specified on INSERT statements.
Example DDL, guessing at the column data type and desired default value:
ALTER TABLE dbo.Contacts
ALTER COLUMN IsDefault bit NOT NULL;
ALTER TABLE dbo.Contacts
ADD CONSTRAINT DF_Contacts_IsDefault DEFAULT (1) FOR IsDefault;

Ignoring duplicate keys on Insert in SQL Server

I have a table called CustomerMemo:
CustomerMemo
CustomerID
MemoID
Both of these are foreign keys. The columns are not unique because there could be something like this:
CustomerID MemoID
----------- -------
1 1
1 2
1 3
However, what I want to avoid is something like this:
CustomerID MemoID
----------- -------
1 1
1 1
Anyone have a clue how to do this in SQL Server?
If you actually want to ignore duplicate keys upon insert, then you'll need to use the IGNORE_DUP_KEY index option in your index or unique constraint definition.
Here is the documentation on MSDN:
CREATE INDEX (Transact-SQL)
Example from that article (in section D. Using the IGNORE_DUP_KEY option):
CREATE TABLE #Test (C1 nvarchar(10), C2 nvarchar(50), C3 datetime);
GO
CREATE UNIQUE INDEX AK_Index ON #Test (C2)
WITH (IGNORE_DUP_KEY = ON);
GO
INSERT INTO #Test VALUES (N'OC', N'Ounces', GETDATE());
INSERT INTO #Test SELECT * FROM Production.UnitMeasure;
GO
SELECT COUNT(*)AS [Number of rows] FROM #Test;
GO
DROP TABLE #Test;
GO
For your table, this would be the command:
CREATE UNIQUE INDEX UNQ_CustomerMemo ON CustomerMemo (MemoID, CustomerID)
WITH (IGNORE_DUP_KEY = ON);
The disadvantage to using IGNORE_DUP_KEY is that you lose visibility on what data is violating the unique constraint. Generally it is better to ensure the data is unique before inserting and then when you do have something fall through the cracks, you will get the error, along with the values that violated the unique constraint. This will allow for much easier troubleshooting of your insert statement. That being said, I make liberal use of this option when defining table variables because the scope is limited.
As for whether or not you should use a unique key or a unique index, see the following question on stack overflow:
Unique key vs. unique index on SQL Server 2008
You want to use the DISTINCT keyword in your select.
Or, if you want to prevent there ever being a record with those same keys, you want a UNIQUE constraint on the CustomerID and MemoID
ALTER TABLE CustomerMemo
ADD CONSTRAINT [uc_CustomerMemo] UNIQUE(CustomerID, MemoID)
Another alternative is to make the primary key on the CustomerMemo a composite primary key on the CustomerID and MemoID
ALTER TABLE CustomerMemo
ADD CONSTRAINT pk_CustomerMemo PRIMARY KEY(CustomerID, MemoID)
Either set up a unique composite key that includes both CustomerID and MemoID, or make your primary key a composite of both CustomerID and MemoID. This will ensure you cannot insert duplicates like that.
Please check out this thread:
How can I create a SQL unique constraint based on 2 columns?
f.e. in sql server 2005 you should use:SQL Server 2005 Unique constraint on two columns
You should look for a phrase: UNIQUE CLUSTERED connected with your db implementation.

SQL multiple unique columns

Is it possible to use unique on multiple columns?
like:
user_vote user_id
------------------
1 1
1 2
2 1
both unique
This must be possible
But:
user_vote user_id
1 2
1 2
This must not be possible
You can add a unique constraint on the column's combination:
ALTER TABLE my_table
ADD CONSTRAINT my_table_uq UNIQUE (user_vote, user_id)
MySQL / SQL Server / Oracle / MS Access:
CREATE TABLE uservotetable
(
user_vote int NOT NULL,
user_id int NOT NULL,
CONSTRAINT uservote UNIQUE (user_vote ,user_id)
);
and if you created your table before ..then you can use ALTER
ALTER TABLE uservotetable
ADD CONSTRAINT uservote UNIQUE (user_vote ,user_id)
this can be useful for you sql_unique
You need to define a composite unique constraint.
SQL Server,
One way to do that in SQL Server is by adding UNIQUE INDEX
ALTER TABLE table_name ADD UNIQUE INDEX (User_Vote, User_Id);
In Oracle,
ALTER TABLE table_name
ADD CONSTRAINT uc_1 UNIQUE (User_Vote, User_Id)

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?

sql - How do I enforce a two-column constraint?

I have a CustomerID column and an EffectiveDate column in a table.
I need the combination of these two to be unique.
However, I already have a primary key on an auto-numbered integer column.
What is a good way to accomplish my goal?
Thanks
Simply add a unique constraint:
Alter Table TableName
Add Constraint UC_TableName_Col1Col2 Unique ( Col1, Col2 )
SQL Server creates a unique index when you create a unique constraint. If there is already a clustered index, then the above will create that index as nonclustered. However, you can be explicit like so:
Alter Table TableName
Add Constraint UC_TableName_Col1Col2 Unique Nonclustered ( Col1, Col2 )
CREATE UNIQUE INDEX Some_Index_Name ON My_Table (CustomerID, EffectiveDate)
Try creating a UNIQUE index on the two columns.
CREATE TABLE Example
(Col1 int NOT NULL,
Col2 int NOT NULL,
UNIQUE (Col1, Col2)
)
Example taken from this thread.
CREATE TABLE MyTable
(
<columns here>
CONSTRAINT U_ConstraintName UNIQUE (CustomerID, EffectiveDate)
)