Create a column with an if condition in SQL server - sql

i am not sure if i could use conditional statement while creating new columns.
Code:
create table Employees(
Emp_ID int primary key identity (1,1),
Hours_worked int,
Rate int default '')
/*Now here in default value i want to set different rates depending upon hours worked. like if hour worked is greater than 8 then rate is 300, if hours worked is less than 8 hour the rate is 200.) How to write this as a Default value in sql server 2008.
My second question is:
Why i get error if i write like this,
create table tbl_1(
col_1 varchar(max) unique
)
The error is
Column 'col_1' in table 'tbl_1' is of a type that is invalid for use as a key column in an index.
Msg 1750, Level 16, State 0, Line 1
Regards
Waqar

you can use COMPUTED Column, http://msdn.microsoft.com/en-us/library/ms191250.aspx
create table Employees(
Emp_ID int primary key identity (1,1),
Hours_worked int,
Rate as (case when Hours_worked > 8 then 300 else 200 end) persisted )

The default value cannot refer to any other column names. So the "default" value of Rate won't know the value of Hours_worked. You could handle it with a trigger or whatever is doing the actual inserting could contain this logic.
http://msdn.microsoft.com/en-us/library/ms173565(v=sql.100).aspx
You cannot but a UNIQUE constraint on a VARCHAR(MAX) field.

Related

What data type to use for ratings in PostgreSQL

I am making a table right now, and I'm confused about what to use, because I used to use smallint(6) but it doesn't work in PostgreSQL.
If the column can only have integer values between 1 and 5 you can use a SMALLINT for it with a CHECK constraint.
For example:
create table review (
rating smallint not null check (rating between 1 and 5)
);
The NOT NULL constraint ensures the column always has values.
The CHECK constraint ensures values are always between 1 and 5, and that, for example, a value 6 won't be accepted.

Use user-defined function in CREATE TABLE statement

I'm trying to create the following table
CREATE TABLE Ingredient.Ingredient
(
GUID UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL,
Name NVARCHAR(MAX) NOT NULL UNIQUE
)
but I've come to realize that the max size of a NVARCHAR UNIQUE column is 450 (at least in the current version of SQL Server). In order to not use magic literals I've created a user-defined function that returns the current max size of a NVARCHAR UNIQUE column.
CREATE FUNCTION [Max NVARCHAR Index Size]()
RETURNS INTEGER
BEGIN
RETURN(450)
END
This function runs correctly when called as
SELECT dbo.[Max NVARCHAR Index Size]()
I was hoping to use this function in a CREATE TABLE statement, but it errors as shown below.
CREATE TABLE Ingredient.Ingredient
(
GUID UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL,
Name NVARCHAR(dbo.[Max NVARCHAR Index Size]()) NOT NULL UNIQUE
)
Error:
Msg 102, Level 15, State 1, Line 13
Incorrect syntax near '('
To try and circumvent this I made a variable with the value of the function, and then using the variable, but that didn't work either.
DECLARE
#NVARCHARIndexSize INTEGER = dbo.[MAX NVARCHAR Index Size]()
CREATE TABLE Ingredient.Ingredient
(
GUID UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL,
Name NVARCHAR(#NVARCHARIndexSize) NOT NULL UNIQUE
)
Error:
Msg 102, Level 15, State 1, Line 13
Incorrect syntax near '#NVARCHARIndexSize'
where line 13 is Name NVARCHAR(#NVARCHARIndexSize) NOT NULL UNIQUE.
Is there a way to use variables/functions instead of literals in a CREATE TABLE statement?
Thanks in advance.
You can create a custom type in SQL Server with following syntax
CREATE TYPE MyCustomType
FROM NVARCHAR(420);
And later on can use the custom type while creating tables
CREATE TABLE Ingredient
(
GUID UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL,
[Name] MyCustomType NOT NULL UNIQUE
)
DDL can't be parameterized. You'd have to use dynamic SQL for that. eg
DECLARE
#NVARCHARIndexSize INTEGER = dbo.[MAX NVARCHAR Index Size]()
declare #sql nvarchar(max) = concat('
CREATE TABLE Ingredient.Ingredient
(
GUID UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL,
Name NVARCHAR(',#NVARCHARIndexSize,') NOT NULL UNIQUE
)'
)
exec (#sql)
Prior to SQL Server 2016, the maximum key length was 900 bytes. MSDN Reference
Index Key Size
The maximum size for an index key is 900 bytes for a clustered index and 1,700 bytes for a nonclustered index. (Before
SQL Database and SQL Server 2016 (13.x) the limit was always 900
bytes.) Indexes on varchar columns that exceed the byte limit can be
created if the existing data in the columns do not exceed the limit at
the time the index is created; however, subsequent insert or update
actions on the columns that cause the total size to be greater than
the limit will fail. The index key of a clustered index cannot contain
varchar columns that have existing data in the ROW_OVERFLOW_DATA
allocation unit. If a clustered index is created on a varchar column
and the existing data is in the IN_ROW_DATA allocation unit,
subsequent insert or update actions on the column that would push the
data off-row will fail.
Nonclustered indexes can include non-key columns in the leaf level of
the index. These columns are not considered by the Database Engine
when calculating the index key size
You can define a NVARCHAR(450) column with check constraint, to ensure that your data does not go beyond 450 characters. I would suggest you to use DATALENGTH to ensure that column length is <= 900.
CREATE TABLE #test(id int identity(1,1) not null,
a NVARCHAR(500) CHECK (DATALENGTH(a) <= 900),
CONSTRAINT ak_a unique(a))
insert into #test
values('a') -- 1 row affected
insert into #test
values(REPLICATE('a',450)) -- 1 row affected
insert into #test
values(REPLICATE('a',451)) -- Error
Msg 547, Level 16, State 0, Line 12 The INSERT statement conflicted
with the CHECK constraint "CK__#test__________a__AC6651A7". The
conflict occurred in database "tempdb", table "#test", column 'a'.
In future, when you move to higher versions, you can increase length of NVARCHAR and CHECK constraint accordingly.

Two identity columns in SQL Server 2008

I am creating a table in SQL Server with three columns. I want the first two columns to increment counts one by one. I used the first column as identity column that automatically increments 1 when row is inserted. I tried to do the same with second column (but SQL Server does not allow two identity columns per table). I found another way i-e using Sequence but since I am using SQL Server 2008, it does not have this feature.
How can I achieve my task?
I am using the first identity column in reports and I reset it when some count is achieved; for example when it reaches 20, I reset it to 1 (Edited). The second incremental column will be used by me for sorting the data and i do not intend to reset it.
create table tblPersons
(
IDCol int primary key identity(1,1),
SortCol int primary key identity(1,1),
Name nvarchar(50)
)
PS : I cannot copy the values of IDCol to SortCol because when I reset the IDCol to 20 from my code, the SortCol will copy the same values (instead it should continue to 21,22,23 and so on)
If you plan on incrementing both columns always at the same time, then one workaround here might be to just use a single auto increment column, but use the remainder of that counter divided by 20 for the second value:
CREATE TABLE tblPersons (
IDCol int PRIMARY KEY IDENTITY(1,1),
Name nvarchar(50)
)
SELECT
IDCol,
IDCol % 20 AS SortCol -- this "resets" to zero upon reaching 20
FROM tblPersons;
As an alternative solution, you can use Computed Column
create table tblPersons
(
SortCol int primary key identity(1,1),
IDCol AS CASE WHEN (SortCol % 20) = 0 THEN 20 ELSE (SortCol % 20) END ,
Name nvarchar(50)
)

SQL true/false or either

I have a table in SQL server that accepts either a true or false value. Is there anyway to say that it can be true or false and not a fixed value. My table is for a container that can hold hot food or cold food. I want some of the containers to be able to carry hot or cold food depending on an order.
SQL Server has Bit type. Try Something like this:
CREATE TABLE yourtablename
(
ID int PRIMARY KEY,
IsHot bit not null default 1
)
Did you try check constraint?
Example code:
CREATE TABLE dbo.Vendors
(VendorID int PRIMARY KEY, VendorName nvarchar (50),
CreditRating tinyint)
GO
ALTER TABLE dbo.Vendors ADD CONSTRAINT CK_Vendor_CreditRating
CHECK (CreditRating >= 1 AND CreditRating <= 5)
This this example we're forcing column CreditRating to store values from 1 to 5. Hope this helps.

SQL Server Database unique number generation on any record insertion

I have like 11 columns in my database table and i am inserting data in 10 of them. i want to have a unique number like "1101 and so on" in the 11th column.
Any idea what should i do?? Thanks in advance.
SQL Server 2012 and above you can generate Sequence
Create SEQUENCE RandomSeq
start with 1001
increment by 1
Go
Insert into YourTable(Id,col1...)
Select NEXT VALUE FOR RandomSeq,col1....
or else you can use Identity
Identity(seed,increment)
You can start the seed from 1101 and increment the sequence by 1
Create table YourTable
(
id INT IDENTITY(1101,1),
Col varchar(10)
)
If you want to have that unique number in a different field then you can manipulate that field with primary key and insert that value.
If you want in primary key value, then open the table in design mode, go to 'Identity specification', set 'identity increment' and 'identity seed' as you want.
Alternatively you can use table script like,
CREATE TABLE Persons
(
ID int IDENTITY(12,1) PRIMARY KEY,
FName varchar(255) NOT NULL,
)
here the primary key will start seeding from 12 and seed value will be 1.
If you have your table definition already in place you can alter the column and add Computed column marked as persisted as:
ALTER TABLE tablename drop column column11;
ALTER TABLE tablename add column11 as '11'
+right('000000'+cast(ID as varchar(10)), 2) PERSISTED ;
--You can change the right operator value from 2 to any as per the requirements.
--Also replace ID with the identity column in your table.
create table inc
(
id int identity(1100,1),
somec char
)