You are on page 1of 178

System Databases in SQL Server

System databases are an integral part of the SQL Server product as it depends on the System
Databases to function. Having a good knowledge of System Databases will help the Database
Administrator to perform day-to-day tasks effectively.
System Database in SQL Server 2005 & 2008 Versions
Master Database
The Master database basically consists of two physical files, namely master.mdf (data file) and
mastlog.ldf (log file). By default when you are installing SQL Server 2008 the master database
related data and log file are installed in the following folder location Drive:\Program
Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\. If master database is
corrupted or if it is not available then the SQL Server Service will not start.
Model Database
The Model database basically consists of two physical files namely Model.mdf (data file) and
ModelLog.ldf (log file).
Physical Path---- Drive:\Program Files\Microsoft SQL
Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\. If the Model database is damaged or
corrupted then SQL Server Service will not start up as it will not be able to create the tempdb
database.
MSDB Database
The MSDB database basically consists of two physical files namely MSDBData.mdf (data file)
and MSDBLog.ldf (log file). By default when you are installing SQL Server 2008 the MSDB
database related data and log file are created in the following folder location Drive:\Program
Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\. If the MSDB
database is corrupted or damaged then scheduling information used by SQL Server Agent will be
lost.
TempDB Database
The TempDB database basically consists of two physical files namely tempdb.mdf (data file)
and templog.ldf (log file). By default when you are installing SQL Server 2008 the TempDB
database related data and log file are created in the following folder location Drive:\Program
Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\.

Create Database Command:


Creates a new database and the files used to store the database, or attaches a database from the
files of a previously created database.
There are three types of files used to store a database:
The primary file contains the startup information for the database. The primary file is also
used to store data. Every database has one primary file.
Secondary files hold all of the data that does not fit in the primary data file. Databases
need not have any secondary data files if the primary file is large enough to hold all of the
data in the database. Other databases may be large enough to need multiple secondary
data files, or they may use secondary files on separate disk drives to spread the data
across multiple disks.
Transaction log files hold the log information used to recover the database. There must be
at least one transaction log file for each database, although there may be more than one.
The minimum size for a transaction log file is 512 KB.
Every database has at least two files, a primary file and a transaction log file.
File type
Primary data file
Secondary data file
Transaction log file

File name extension


.mdf
.ndf
.ldf

Note The master database should be backed up when a user database is created.
Fractions cannot be specified in the SIZE, MAXSIZE, and FILEGROWTH parameters. To
specify a fraction of a megabyte in SIZE parameters, convert to kilobytes by multiplying the
number by 1,024. For example, specify 1,536 KB instead of 1.5 MB (1.5 multiplied by 1,024
equals 1,536).
When a simple CREATE DATABASE database_name statement is specified with no additional
parameters, the database is made the same size as the model database.

A. Create a database that specifies the data and transaction log files
This example creates a database called Sales. Because the keyword PRIMARY is not used, the
first file (Sales_dat) becomes the primary file. Because neither MB or KB is specified in the
SIZE parameter for the Sales_dat file, it defaults to MB and is allocated in megabytes. The
Sales_log file is allocated in megabytes because the MB suffix is explicitly stated in the SIZE
parameter.
USE master
GO
CREATE DATABASE Sales

ON
( NAME = Sales_dat,
FILENAME = 'c:\program files\microsoft sql server\mssql\data\saledat.mdf',
SIZE = 10,
MAXSIZE = 50,
FILEGROWTH = 5 )

LOG ON
( NAME = 'Sales_log',
FILENAME = 'c:\program files\microsoft sql server\mssql\data\salelog.ldf',
SIZE = 5MB,
MAXSIZE = 25MB,
FILEGROWTH = 5MB )

GO

B. Create a database specifying multiple data and transaction log files


This example creates a database called Archive with three 100-MB data files and two 100-MB
transaction log files. The primary file is the first file in the list and is explicitly specified with the
PRIMARY keyword. The transaction log files are specified following the LOG ON keywords.
Note the extensions used for the files in the FILENAME option: .mdf is used for primary data
files, .ndf is used for the secondary data files, and .ldf is used for transaction log files.
USE master
GO
CREATE DATABASE Archive
ON
PRIMARY ( NAME = Arch1,
FILENAME = 'c:\program files\microsoft sql
server\mssql\data\archdat1.mdf',
SIZE = 100MB,
MAXSIZE = 200,
FILEGROWTH = 20),

( NAME = Arch2,

FILENAME = 'c:\program files\microsoft sql server\mssql\data\archdat2.ndf',


SIZE = 100MB,
MAXSIZE = 200,
FILEGROWTH = 20),

( NAME = Arch3,

FILENAME = 'c:\program files\microsoft sql server\mssql\data\archdat3.ndf',


SIZE = 100MB,
MAXSIZE = 200,
FILEGROWTH = 20)

LOG ON
( NAME = Archlog1,

FILENAME = 'c:\program files\microsoft sql server\mssql\data\archlog1.ldf',


SIZE = 100MB,
MAXSIZE = 200,
FILEGROWTH = 20),

( NAME = Archlog2,

FILENAME = 'c:\program files\microsoft sql server\mssql\data\archlog2.ldf',


SIZE = 100MB,
MAXSIZE = 200,
FILEGROWTH = 20)

GO

C. Create a simple database


This example creates a database called Products and specifies a single file. The file specified
becomes the primary file, and a 1-MB transaction log file is automatically created. Because
neither MB or KB is specified in the SIZE parameter for the primary file, the primary file is
allocated in megabytes. Because there is no <filespec> for the transaction log file, the transaction
log file has no MAXSIZE and can grow to fill all available disk space.

USE master
GO
CREATE DATABASE Products
ON
( NAME = prods_dat,
FILENAME = 'c:\program files\microsoft sql server\mssql\data\prods.mdf',
SIZE = 4,
MAXSIZE = 10,
FILEGROWTH = 1 )

GO

D. Create a database without specifying files


This example creates a database named mytest and creates a corresponding primary and
transaction log file. Because the statement has no <filespec> items, the primary database file is
the size of the model database primary file. The size of the transaction log is the larger of these
values:.5 MB or 25 percent of the sum of the sizes of all the data files for the database. Because
MAXSIZE is not specified, the files can grow to fill all available disk space.
CREATE DATABASE VideoRentalSystem

E. Create a database without specifying SIZE


This example creates a database named products2. The file prods2_dat becomes the primary
file with a size equal to the size of the primary file in the model database. The transaction log file
is created automatically and is 25 percent of the size of the primary file, or 512 KB, whichever is
larger. Because MAXSIZE is not specified, the files can grow to fill all available disk space.

USE master
GO
CREATE DATABASE Products2
ON
( NAME = prods2_dat,
FILENAME = 'c:\program files\microsoft sql server\mssql\data\prods2.mdf' )

GO

All databases have at least a primary filegroup. All system tables are allocated in
the primary filegroup. A database can also have user-defined filegroups. If an
object is created with an ON filegroup clause specifying a user-defined filegroup,
then all the pages for the object are allocated from the specified filegroup.
F. Create a database with filegroups
This example creates a database named sales with three filegroups:
The primary filegroup with the files Spri1_dat and Spri2_dat. The FILEGROWTH
increments for these files is specified as 15 percent.
A filegroup named SalesGroup1 with the files SGrp1Fi1 and SGrp1Fi2.
A filegroup named SalesGroup2 with the files SGrp2Fi1 and SGrp2Fi2.
CREATE DATABASE Sales
ON PRIMARY
( NAME = SPri1_dat,
FILENAME = 'c:\program files\microsoft sql server\mssql\data\SPri1dat.mdf',
SIZE = 10,
MAXSIZE = 50,
FILEGROWTH = 15% ),

( NAME = SPri2_dat,
FILENAME = 'c:\program files\microsoft sql server\mssql\data\SPri2dt.ndf',
SIZE = 10,
MAXSIZE = 50,
FILEGROWTH = 15% ),

FILEGROUP SalesGroup1
( NAME = SGrp1Fi1_dat,
FILENAME = 'c:\program files\microsoft sql server\mssql\data\SG1Fi1dt.ndf',
SIZE = 10,
MAXSIZE = 50,
FILEGROWTH = 5 ),

( NAME = SGrp1Fi2_dat,
FILENAME = 'c:\program files\microsoft sql server\mssql\data\SG1Fi2dt.ndf',
SIZE = 10,
MAXSIZE = 50,
FILEGROWTH = 5 ),

FILEGROUP SalesGroup2

( NAME = SGrp2Fi1_dat,
FILENAME = 'c:\program files\microsoft sql server\mssql\data\SG2Fi1dt.ndf',
SIZE = 10,
MAXSIZE = 50,
FILEGROWTH = 5 ),

( NAME = SGrp2Fi2_dat,
FILENAME = 'c:\program files\microsoft sql server\mssql\data\SG2Fi2dt.ndf',
SIZE = 10,
MAXSIZE = 50,
FILEGROWTH = 5 )

LOG ON
( NAME = 'Sales_log',
FILENAME = 'c:\program files\microsoft sql server\mssql\data\salelog.ldf',
SIZE = 5MB,
MAXSIZE = 25MB,
FILEGROWTH = 5MB )

GO

SQL Server Datatypes


Data types in SQL Server are organized into the following categories:
Exact numerics

Unicode character strings

Approximate numerics

Binary strings

Date and time

Other data types

Character strings
In SQL Server, based on their storage characteristics, some data types are
designated as belonging to the following groups:
Large value data types: varchar(max), nvarchar(max), and varbinary(max)
Large object data types: text, ntext, image, varchar(max), nvarchar(max),
varbinary(max), and xml

Exact Numerics
Integers
bigint

Integer (whole number) data from -2^63 (-9,223,372,036,854,775,808) through


2^63-1 (9,223,372,036,854,775,807).
int

Integer (whole number) data from -2^31 (-2,147,483,648) through 2^31 - 1


(2,147,483,647).
smallint

Integer data from -2^15 (-32,768) through 2^15 - 1 (32,767).


tinyint

Integer data from 0 through 255.


bit

Integer data with either a 1 or 0 value.

decimal

Fixed precision and scale numeric data from -10^38 +1 through 10^38 1.
numeric

Functionally equivalent to decimal.


money

Monetary data values from -2^63 (-922,337,203,685,477.5808) through 2^63 - 1


(+922,337,203,685,477.5807), with accuracy to a ten-thousandth of a monetary
unit.
smallmoney

Monetary data values from -214,748.3648 through +214,748.3647, with accuracy


to a ten-thousandth of a monetary unit.
Approximate Numerics
float

Floating precision number data with the following valid values: -1.79E + 308
through -2.23E - 308, 0 and 2.23E + 308 through 1.79E + 308.
real

Floating precision number data with the following valid values: -3.40E + 38
through -1.18E - 38, 0 and 1.18E - 38 through 3.40E + 38.
datetime and smalldatetime
datetime

Date and time data from January 1, 1753, through December 31, 9999, with an
accuracy of three-hundredths of a second, or 3.33 milliseconds.
smalldatetime

Date and time data from January 1, 1900, through June 6, 2079, with an accuracy
of one minute.
Character Strings
char

Fixed-length non-Unicode character data with a maximum length of 8,000


characters.
varchar

Variable-length non-Unicode data with a maximum of 8,000 characters.


text

Variable-length non-Unicode data with a maximum length of 2^31 - 1


(2,147,483,647) characters.
Unicode Character Strings
nchar

Fixed-length Unicode data with a maximum length of 4,000 characters.


nvarchar

Variable-length Unicode data with a maximum length of 4,000 characters.


sysname is a system-supplied user-defined data type that is functionally equivalent
to nvarchar(128) and is used to reference database object names.
ntext

Variable-length Unicode data with a maximum length of 2^30 - 1 (1,073,741,823)


characters.

Binary Strings
binary

Fixed-length binary data with a maximum length of 8,000 bytes.


varbinary

Variable-length binary data with a maximum length of 8,000 bytes.


image

Variable-length binary data with a maximum length of 2^31 - 1 (2,147,483,647)


bytes.
Other Data Types
cursor

A reference to a cursor.
sql_variant

A data type that stores values of various SQL Server-supported data types, except
text, ntext, timestamp, and sql_variant.
table

A special data type used to store a result set for later processing .
timestamp

A database-wide unique number that gets updated every time a row gets updated.
uniqueidentifier

A globally unique identifier (GUID).

Data type precedences:


When an operator combines two expressions of different data types, the rules for
data type precedence specify that the data type with the lower precedence is
converted to the data type with the higher precedence. If the conversion is not a
supported implicit conversion, an error is returned. When both operand expressions
have the same data type, the result of the operation has that data type.
SQL Server uses the following precedence order for data types:
1. user-defined data types (highest)
2. sql_variant
3. xml

4. datetimeoffset
5. datetime2
6. datetime
7. smalldatetime
8. date
9. time
10.

float

11.real
12.

decimal

13.

money

14.

smallmoney

15.

bigint

16.

int

17.

smallint

18.

tinyint

19.

bit

20.

ntext

21.

text

22.

image

23.

timestamp

24.

uniqueidentifier

25.

nvarchar (including nvarchar(max) )

26.

nchar

27.

varchar (including varchar(max) )

28.

char

29.

varbinary (including varbinary(max) )

30.

binary (lowest)

Type
bigint
Int
Smallint
Tinyint
Bit
Decimal and numeric precision 1-9
Decimal and numeric precision 10-19
Decimal and numeric precision 20-28
Decimal and numeric precision 29-38
Money
Smallmoney
Float 7 digit precision
Float 15 digit precision
Real
Datetime
Smalldatetime
Char
Nchar

Storage in bytes
8
4
2
1
1 bit
5
9
13
17
8
4
4
8
4
Two 4 byte integers
Two 2 byte integers
Each char occupies 1 byte
Each nchar occupies 2 bytes

Create Table Command:


Syntax:

CREATE TABLE table_name (col1-name data-type(width if any)


CONSTRAINT constraint-name <a constraint like PRIMARY
KEY,UNIQUE, NOT NULL, CHECK etc>, col2-name data-type(width if any)
CONSTRAINT constraint-name ..........)
CREATE TABLE Customer(
CustomerId int PRIMARY KEY,
FName nvarchar(30),
LName nvarchar(30),
Phone char(13) UNIQUE,
Street nvarchar(30),
City nvarchar(20) NOT NULL,
ZipCode char(10) NOT NULL)
GO

Inserting Records into a Table:


Syntax:
INSERT INTO table-name (col1,col2,col3,...)VALUES(val1,val2,val3,......)
insert into Customer values
(200112,'Jake','Kline','(814)237-6871','2352 8th Avenue','LA','16444-0256'),
(200334,'Abigail','Brown','(814)237-2310','124 North Land','LA','16444-0312'),
(200123,'Reginald','Smyth',null,'P.O.Box 200','NY','15432-0021'),
(210222,'Steve','Haag','(410)416-7799','1372 Ivanhoe','Chicago','22100-2555')
go
Create Table Rental
(CustomerId int references Customer,

VideoNumber char(6) references Video(VideoNum),


DateRented datetime not null,
DateReturned datetime)
go

Insert into Rental values(


200334,'4371-1','09/22/06',null)
go
Create Table Video
(VideoNum char(6) primary key,
VTitle nvarchar(30) not null,
VType nvarchar(20) not null,
DistNum int references Distributor(DistributorNum),
Price decimal(5,2) not null check(Price between 1 and 5)
)
go
insert into Video values
('1111-1','Gone with the breeze','Drama',986,3),
('1111-2','Gone with the breeze','Drama',986,3),
('2351-6','Attack of killer tomatoes','Horror',381,1.5),
('4371-1','Alien Surfer','Sci-Fi',457,2),
('4780-1','Three Stooges in Las Vegas','Comedy',235,2),
('4777-1','Gods Must be crazy','Comedy',235,5)
go
Create Table Distributor
(DistributorNum int primary key,
DistributorName nvarchar(30) not null,
Phone char(13) not null)
go

insert into Distributor values

(235,'Disney Studios','(800)243-0000'),
(986,'Universal Studios','(800)565-0000'),
(457,'Paramount Pictures','(800)322-5555'),
(381,'Tri-Star Productions','(800)665-8998')
go

INTEGRITY CONSTRAINTS
Nullability Rules Within a Table Definition
The nullability of a column determines whether or not that column can allow a null value
(NULL) as the data in that column. NULL is not zero or blank: it means no entry was made or an
explicit NULL was supplied, and it usually implies that the value is either unknown or not
applicable.

PRIMARY KEY Constraints


A table can contain only one PRIMARY KEY constraint.
The index generated by a PRIMARY KEY constraint cannot cause the number of indexes
on the table to exceed 249 nonclustered indexes and 1 clustered index.
If CLUSTERED or NONCLUSTERED is not specified for a PRIMARY KEY constraint,
CLUSTERED is used if there are no clustered indexes specified for UNIQUE constraints.
All columns defined within a PRIMARY KEY constraint must be defined as NOT NULL.
If nullability is not specified, all columns participating in a PRIMARY KEY constraint
have their nullability set to NOT NULL.

UNIQUE Constraints
If CLUSTERED or NONCLUSTERED is not specified for a UNIQUE constraint,
NONCLUSTERED is used by default.
Each UNIQUE constraint generates an index. The number of UNIQUE constraints cannot
cause the number of indexes on the table to exceed 249 nonclustered indexes and 1
clustered index.

FOREIGN KEY Constraints


When a value other than NULL is entered into the column of a FOREIGN KEY
constraint, the value must exist in the referenced column; otherwise, a foreign key
violation error message is returned.
FOREIGN KEY constraints are applied to the preceding column unless source columns

are specified.
FOREIGN KEY constraints can reference only tables within the same database on the
same server. Cross-database referential integrity must be implemented through triggers.
FOREIGN KEY constraints can reference another column in the same table (a selfreference).
The REFERENCES clause of a column-level FOREIGN KEY constraint can list only one
reference column, which must have the same data type as the column on which the
constraint is defined.
The REFERENCES clause of a table-level FOREIGN KEY constraint must have the
same number of reference columns as the number of columns in the constraint column
list. The data type of each reference column must also be the same as the corresponding
column in the column list.

A table can contain a maximum of 253 FOREIGN KEY constraints.


FOREIGN KEY constraints are not enforced on temporary tables.
A table can reference a maximum of 253 different tables in its FOREIGN KEY
constraints.
FOREIGN KEY constraints can reference only columns in PRIMARY KEY or UNIQUE
constraints in the referenced table or in a UNIQUE INDEX on the referenced table.

use videorentalsystem
go
CREATE TABLE Dept(
deptno int primary key,
dname nvarchar(20) not null,
loc nvarchar(20) not null)
go
CREATE TABLE Emp(
empid int primary key,
ename nvarchar(20) not null,
job nvarchar(20) not null,
salary int not null,
deptno int references Dept(deptno))
go

-------------------------------------*
CREATE TABLE Emp2(
empid int primary key,
ename nvarchar(20) not null,
job nvarchar(20) not null,
salary int not null,
deptno int,
foreign key(deptno)references Dept(deptno))
go
-------------------------------------*
Create table TX
(col1x int,
col2x int,
col3x nvarchar(10),
primary key(col1x,col2x))
go
Create table TY
(
col1y int,
col2y int,
col3y int,
Constraint TY_fk Foreign Key (col1y,col2y)
references TX(col1x,col2x))
go
-------------------------------------*
Create table AA(
col1 int primary key,
col2 nvarchar(10),
col3 int unique)
go

Create table BB(


col1 nvarchar(20),
col2 int references AA)
go
----------------------------------------*
Create table CC(
col1 nvarchar(20),
col2 int references AA(col3))
go
------------------*

DEFAULT Definitions
A column can have only one DEFAULT definition.
A DEFAULT definition can contain constant values, functions, SQL-92 niladic functions,
or NULL. The table shows the niladic functions and the values they return for the default
during an INSERT statement.
SQL-92 niladic function
Value returned
CURRENT_TIMESTAMP
Current date and time.
CURRENT_USER
Name of user performing insert.
SESSION_USER
Name of user performing insert.
SYSTEM_USER
Name of user performing insert.
USER
Name of user performing insert.

constant_expression in a DEFAULT definition cannot refer to another column in the


table, or to other tables, views, or stored procedures.
DEFAULT definitions cannot be created on columns with a timestamp data type or
columns with an IDENTITY property.
DEFAULT definitions cannot be created for columns with user-defined data types if the
user-defined data type is bound to a default object.

Defaults supply a value (with the INSERT and UPDATE statements) when no
value is supplied. For example, the AdventureWorks2008R2 database could
include a lookup table listing the different jobs employees can fill in the company.
Under a column that describes each job, a character string default could supply a
description when an actual description is not entered explicitly.
DEFAULT 'New Position - title not formalized yet'

In addition to constants, DEFAULT definitions can include functions. Use the following example
to get the current date for an entry.
DEFAULT (getdate())

A niladic-function scan can also improve data integrity. To keep track of the user that inserted a
row, use the niladic-function for USER. Do not enclose the niladic-functions with parentheses.
DEFAULT USER

CHECK Constraints
A column can have any number of CHECK constraints, and the condition can include
multiple logical expressions combined with AND and OR. Multiple CHECK constraints
for a column are validated in the order created.
The search condition must evaluate to a Boolean expression and cannot reference another
table.
A column-level CHECK constraint can reference only the constrained column, and a
table-level CHECK constraint can reference only columns in the same table.
CHECK CONSTRAINTS and rules serve the same function of validating the data during
INSERT and DELETE statements.
When a rule and one or more CHECK constraints exist for a column or columns, all
restrictions are evaluated.

use videorentalsystem
go
create table T7(
col1 int primary key ,
col2 nvarchar(10),

col3 int check(col3 >= 10 And col3 <= 100)


)
go
use videorentalsystem
go
create table T8(
col1 int primary key ,
col2 nvarchar(10),
col3 int constraint t7_col3_chk check(col3 >= 10 And col3 <= 100)
)
go
----------------------------*
This example shows a named constraint with a pattern restriction on the character
data entered into a column of a table.
CONSTRAINT CK_emp_id CHECK (emp_id LIKE
'[A-Z][A-Z][A-Z][1-9][0-9][0-9][0-9][0-9][FM]'
OR emp_id LIKE '[A-Z]-[A-Z][1-9][0-9][0-9][0-9][0-9][FM]')

This example specifies that the values must be within a specific list or follow a specified pattern.
CHECK (emp_id IN ('1389', '0736', '0877', '1622', '1756')
OR emp_id LIKE '99[0-9][0-9]')

Additional Constraint Information


Constraint names must follow the rules for identifiers, except that the name cannot begin
with a number sign (#). If constraint_name is not supplied, a system-generated name is
assigned to the constraint. The constraint name appears in any error message about
constraint violations.
When a constraint is violated in an INSERT, UPDATE, or DELETE statement, the
statement is terminated. However, the transaction (if the statement is part of an explicit
transaction) continues to be processed. You can use the ROLLBACK TRANSACTION
statement with the transaction definition by checking the @@ERROR system function.

Composite Primary Key:

CREATE TABLE Emp_Hrs(


EmpId int,
DeptNo int,
HrsWkd int,
PRIMARY KEY(EmpId,DeptNo))
GO
DROP TABLE Emp_Hrs
GO
Difference between Clustered and Non-Clustered Indexes:
I am explaining you with an example, The Telephone
Directory is a fine example of Clustered Index as data
and
index are at the same page, whereas index in the back
side
of the book is a fine example of non-clustered index
and
non-clustered index is a fast B-tree structure as index
just points to the data page. Also only one clustered
index
is possible per table and 249 non-clustered index per
table.
Clustered index is unique for any
given table and we can have only one clustered index on
a
table. The leaf level of a clustered index is the
actual
data and the data is resorted in case of clustered
index.
Whereas in case of non-clustered index the leaf level
is
actually a pointer to the data in rows so we can have
as
many non-clustered indexes as we can on the db.

Using Clustered Indexes


Note PRIMARY KEY constraints create clustered indexes automatically if no clustered index
already exists on the table and a nonclustered index is not specified when you create the
PRIMARY KEY constraint.

Before creating clustered indexes, understand how your data will be accessed.
Consider using a clustered index for:
Columns that contain a large number of distinct values.
Queries that return a range of values using operators such as BETWEEN, >, >=, <, and
<=.
Columns that are accessed sequentially.
Queries that return large result sets.
Columns that are frequently accessed by queries involving join or GROUP BY clauses;
typically these are foreign key columns. An index on the column(s) specified in the
ORDER BY or GROUP BY clause eliminates the need for SQL Server to sort the data
because the rows are already sorted. This improves query performance.

Clustered indexes are not a good choice for:


Columns that undergo frequent changes
This results in the entire row moving (because SQL Server must keep the data values of a
row in physical order). This is an important consideration in high-volume transaction
processing systems where data tends to be volatile.
Wide keys

use videorentalsystem
go
create table T1(
col1 int primary key clustered,
col2 nvarchar(10),
col3 int unique)
go

------------------------------------------*
use videorentalsystem
go
create table T2(
col1 int primary key clustered,
col2 nvarchar(10),
col3 int unique clustered)
go
Msg 8112, Level 16, State 0, Line 2
Cannot add more than one clustered index for constraints on table 'T2'.

------------------------------------------------*
use videorentalsystem
go
create table T3(
col1 int primary key ,
col2 nvarchar(10),
col3 int unique clustered)
go
--------------------------------------------*
use videorentalsystem
go
create table T4(
col1 int ,
col2 nvarchar(10),
col3 int unique ,
primary key clustered(col1,col2) )
go
-------------------------------------------*

use videorentalsystem
go
create table T5(
col1 int primary key,
col2 nvarchar(10),
col3 int ,
unique clustered(col2,col3) )
go
--------------------------------------------*
use videorentalsystem
go
create table T6(
col1 int primary key nonclustered,
col2 nvarchar(10),
col3 int ,
)
go
---------------------------------------*
CREATE TABLE Stars
(StarID int PRIMARY KEY NONCLUSTERED,
StarName varchar(50) Unique,
SolarMass decimal(10,2) CHECK(SolarMass > 0),
StarType varchar(50) DEFAULT 'Orange Giant');
GO
CREATE CLUSTERED INDEX Ix_Star_Name
ON Stars(StarName)
GO
CREATE NONCLUSTERED INDEX Ix_Star_Type
ON Stars (StarType)
GO
-----------------------------------------------------------------*

ALTER TABLE Command:


A. Adding a new column
The following example adds a column that allows null values and has no values provided
through a DEFAULT definition. In the new column, each row will have NULL.

use videorentalsystem
go
CREATE TABLE doc_exa (column_a INT) ;
GO
ALTER TABLE doc_exa ADD column_b VARCHAR(20) NULL ;
GO
EXEC sp_help doc_exa ;
GO
DROP TABLE doc_exa ;
GO

B. Dropping a column
The following example modifies a table to remove a column.

use videorentalsystem
go
CREATE TABLE doc_exb (column_a INT, column_b VARCHAR(20) NULL) ;
GO
ALTER TABLE doc_exb DROP COLUMN column_b ;
GO
EXEC sp_help doc_exb ;
GO

DROP TABLE doc_exb ;


GO

C. Changing the data type of a column


The following example changes a column of a table from INT to DECIMAL.

use videorentalsystem
go
CREATE TABLE doc_exy (column_a INT ) ;
GO
INSERT INTO doc_exy (column_a) VALUES (10) ;
GO
Select * from doc_exy
go
exec sp_help doc_exy
go
ALTER TABLE doc_exy ALTER COLUMN column_a DECIMAL (5, 2) ;
GO
DROP TABLE doc_exy ;
GO

D. Adding a column with a constraint


The following example adds a new column with a UNIQUE constraint.

Use VideoRentalSystem
go
CREATE TABLE doc_exc (column_a INT) ;
GO
ALTER TABLE doc_exc ADD column_b VARCHAR(20) NULL
CONSTRAINT exb_unique UNIQUE ;

GO
EXEC sp_help doc_exc ;
GO
DROP TABLE doc_exc ;
GO

E. Adding an unverified CHECK constraint to an existing column


The following example adds a constraint to an existing column in the table. The column has a
value that violates the constraint. Therefore, WITH NOCHECK is used to prevent the constraint
from being validated against existing rows, and to allow for the constraint to be added.

Use VideoRentalSystem
go
CREATE TABLE doc_exd ( column_a INT) ;
GO
INSERT INTO doc_exd VALUES (-1) ;
GO
ALTER TABLE doc_exd WITH NOCHECK
ADD CONSTRAINT exd_check CHECK (column_a > 1) ;
GO
Select * from doc_exd
go
EXEC sp_help doc_exd ;
GO
DROP TABLE doc_exd ;
GO

F. Adding a DEFAULT constraint to an existing column


The following example creates a table with two columns and inserts a value into the first column,
and the other column remains NULL. A DEFAULT constraint is then added to the second
column. To verify that the default is applied, another value is inserted into the first column, and
the table is queried.

CREATE TABLE doc_exz ( column_a INT, column_b INT) ;


GO

INSERT INTO doc_exz (column_a)VALUES ( 7 ) ;


GO
ALTER TABLE doc_exz
ADD CONSTRAINT col_b_def
DEFAULT 50 FOR column_b ;
GO
INSERT INTO doc_exz (column_a) VALUES ( 10 ) ;
GO
SELECT * FROM doc_exz ;
GO
DROP TABLE doc_exz ;
GO
G. Adding several columns with constraints
The following example adds several columns with constraints defined with the new column. The
first new column has an IDENTITY property. Each row in the table has new incremental values
in the identity column.

Use VideoRentalSystem
go
CREATE TABLE doc_exe ( column_a INT CONSTRAINT column_a_un
UNIQUE) ;
GO
ALTER TABLE doc_exe ADD
-- Add a PRIMARY KEY identity column.
column_b INT IDENTITY
CONSTRAINT column_b_pk PRIMARY KEY,
-- Add a column that references another column in the same table.
column_c INT NULL
CONSTRAINT column_c_fk
REFERENCES doc_exe(column_a),
-- Add a column with a constraint to enforce that
-- nonnull data is in a valid telephone number format.
column_d VARCHAR(16) NULL
CONSTRAINT column_d_chk

CHECK
(column_d LIKE '[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]' OR
column_d LIKE
'([0-9][0-9][0-9]) [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]'),
-- Add a nonnull column with a default.
column_e DECIMAL(3,3)
CONSTRAINT column_e_default
DEFAULT .081 ;
GO
EXEC sp_help doc_exe ;
GO
DROP TABLE doc_exe ;
GO

H. Adding a nullable column with default values


The following example adds a nullable column with a DEFAULT definition, and uses WITH
VALUES to provide values for each existing row in the table. If WITH VALUES is not used,
each row has the value NULL in the new column.

Use VideoRentalSystem
go
CREATE TABLE doc_exf ( column_a INT) ;
GO
INSERT INTO doc_exf VALUES (1) ;
GO
ALTER TABLE doc_exf
ADD AddDate smalldatetime NULL
CONSTRAINT AddDateDflt
DEFAULT GETDATE() WITH VALUES ;
GO
SELECT * FROM doc_exf
go
DROP TABLE doc_exf ;
GO

I. Disabling and re-enabling a constraint


The following example disables a constraint that limits the salaries accepted in the data.
NOCHECK CONSTRAINT is used with ALTER TABLE to disable the constraint and allow for
an insert that would typically violate the constraint. CHECK CONSTRAINT re-enables the
constraint.

use VideoRentalSystem
go
CREATE TABLE cnst_example
(id INT NOT NULL,
name VARCHAR(10) NOT NULL,
salary MONEY NOT NULL
CONSTRAINT salary_cap CHECK (salary < 100000)
);
-- Valid inserts
INSERT INTO cnst_example VALUES (1,'Joe Brown',65000);
INSERT INTO cnst_example VALUES (2,'Mary Smith',75000);
-- This insert violates the constraint.
INSERT INTO cnst_example VALUES (3,'Pat Jones',105000);
-- Disable the constraint and try again.
ALTER TABLE cnst_example NOCHECK CONSTRAINT salary_cap;
INSERT INTO cnst_example VALUES (3,'Pat Jones',105000);
-- Re-enable the constraint and try another insert; this will fail.
ALTER TABLE cnst_example CHECK CONSTRAINT salary_cap;
INSERT INTO cnst_example VALUES (4,'Eric James',110000) ;

J. Dropping a constraint
The following example removes a UNIQUE constraint from a table.

Use VideoRentalSystem
go

CREATE TABLE doc_exc ( column_a INT


CONSTRAINT my_constraint UNIQUE) ;
GO
ALTER TABLE doc_exc DROP CONSTRAINT my_constraint ;
GO
DROP TABLE doc_exc ;
GO

M. Creating a PRIMARY KEY constraint with index options


The following example creates the PRIMARY KEY constraint
PK_TransactionHistoryArchive_TransactionID and sets the options FILLFACTOR, ONLINE,
and PAD_INDEX. The resulting clustered index will have the same name as the constraint.
USE AdventureWorks2008R2;
GO
ALTER TABLE Production.TransactionHistoryArchive WITH NOCHECK
ADD CONSTRAINT PK_TransactionHistoryArchive_TransactionID PRIMARY KEY
CLUSTERED (TransactionID)
WITH (FILLFACTOR = 75, ONLINE = ON, PAD_INDEX = ON);
GO

N. Dropping a PRIMARY KEY constraint in the ONLINE mode


The following example deletes a PRIMARY KEY constraint with the ONLINE option set to ON.
USE AdventureWorks2008R2;
GO
ALTER TABLE TransactionHistoryArchive
DROP CONSTRAINT PK_TransactionHistoryArchive_TransactionID
WITH (ONLINE = ON);
GO

O. Adding and dropping a FOREIGN KEY constraint


The following example creates the table ContactBackup, and then alters the table, first by adding
a FOREIGN KEY constraint that references the table Person, then by dropping the FOREIGN
KEY constraint.
USE AdventureWorks2008R2 ;
GO
CREATE TABLE ContactBackup

(ContactID int) ;
GO
ALTER TABLE ContactBackup
ADD CONSTRAINT FK_ContactBacup_Contact FOREIGN KEY (ContactID)
REFERENCES Person (BusinessEntityID) ;
ALTER TABLE ContactBackup
DROP CONSTRAINT FK_ContactBacup_Contact ;
GO
DROP TABLE ContactBackup ;

P. Changing the size of a column


The following example increases the size of a varchar column and the precision and scale of a
decimal column. Because the columns contain data, the column size can only be increased. Also
notice that col_a is defined in a unique index. The size of col_a can still be increased because the
data type is a varchar and the index is not the result of a PRIMARY KEY constraint.
javascript:CodeSnippet_CopyCode('CodeSnippetContainerCode18');
IF OBJECT_ID ( 'dbo.doc_exy', 'U' ) IS NOT NULL
DROP TABLE dbo.doc_exy;
GO
-- Create a two-column table with a unique index on the varchar column.
CREATE TABLE doc_exy ( col_a varchar(5) UNIQUE NOT NULL, col_b decimal (4,2));
GO
INSERT INTO doc_exy VALUES ('Test', 99.99);
GO
-- Verify the current column size.
SELECT name, TYPE_NAME(system_type_id), max_length, precision, scale
FROM sys.columns WHERE object_id = OBJECT_ID(N'dbo.doc_exy');
GO
-- Increase the size of the varchar column.
ALTER TABLE doc_exy ALTER COLUMN col_a varchar(25);
GO
-- Increase the scale and precision of the decimal column.
ALTER TABLE doc_exy ALTER COLUMN col_b decimal (10,4);
GO
-- Insert a new row.
INSERT INTO doc_exy VALUES ('MyNewColumnSize', 99999.9999) ;
GO
-- Verify the current column size.
SELECT name, TYPE_NAME(system_type_id), max_length, precision, scale
FROM sys.columns WHERE object_id = OBJECT_ID(N'dbo.doc_exy');

Insert Command
Use VideoRentalSystem
go
exec sp_help t1

go
INSERT INTO T1(col1, col2,col3)
SELECT 1,'First' ,1
UNION ALL
SELECT 2,'Second' ,2
UNION ALL
SELECT 3,'Third' ,3
UNION ALL
SELECT 4, 'Fourth' ,4
UNION ALL
SELECT 5,'Fifth' ,5
GO
Select * from T1
go
------------------------------------*
INSERT INTO T1(col1, col2,col3)
VALUES( 1,'First' ,1),
(2,'Second' ,2),
( 3,'Third' ,3),
( 4, 'Fourth' ,4),
(5,'Fifth' ,5)
GO
Renaming column and table:
The script for renaming any column :
Exec sp_RENAME 'TableName.[OldColumnName]' ,

'[NewColumnName]', 'COLUMN'

The script for renaming any object (table, sp etc) :


Exec sp_RENAME '[OldTableName]' , '[NewTableName]'

Renaming a database:

EXEC sp_renamedb 'oldName', 'newName'


COMMIT:
Marks the end of a successful implicit or explicit transaction. If
@@TRANCOUNT is 1, COMMIT TRANSACTION makes all data modifications
performed since the start of the transaction a permanent part of the database, frees
the resources held by the transaction, and decrements @@TRANCOUNT to 0. If
@@TRANCOUNT is greater than 1, COMMIT TRANSACTION decrements
@@TRANCOUNT only by 1 and the transaction stays active.
A. Committing a transaction
The following example deletes a job candidate.
Copy
USE AdventureWorks2008R2;
GO
BEGIN TRANSACTION;
GO
DELETE FROM HumanResources.JobCandidate
WHERE JobCandidateID = 13;
GO
COMMIT TRANSACTION;
GO

B. Committing a nested transaction


The following example creates a table, generates three levels of nested transactions, and then
commits the nested transaction. Although each COMMIT TRANSACTION statement has a
transaction_name parameter, there is no relationship between the COMMIT TRANSACTION
and BEGIN TRANSACTION statements. The transaction_name parameters are simply
readability aids to help the programmer ensure that the proper number of commits are coded to
decrement @@TRANCOUNT to 0 and thereby commit the outer transaction.
USE AdventureWorks2008R2;
GO
IF OBJECT_ID(N'TestTran',N'U') IS NOT NULL
DROP TABLE TestTran;
GO
CREATE TABLE TestTran (Cola int PRIMARY KEY, Colb char(3));
GO
-- This statement sets @@TRANCOUNT to 1.

BEGIN TRANSACTION OuterTran;


GO
PRINT N'Transaction count after BEGIN OuterTran = '
+ CAST(@@TRANCOUNT AS nvarchar(10));
GO
INSERT INTO TestTran VALUES (1, 'aaa');
GO
-- This statement sets @@TRANCOUNT to 2.
BEGIN TRANSACTION Inner1;
GO
PRINT N'Transaction count after BEGIN Inner1 = '
+ CAST(@@TRANCOUNT AS nvarchar(10));
GO
INSERT INTO TestTran VALUES (2, 'bbb');
GO
-- This statement sets @@TRANCOUNT to 3.
BEGIN TRANSACTION Inner2;
GO
PRINT N'Transaction count after BEGIN Inner2 = '
+ CAST(@@TRANCOUNT AS nvarchar(10));
GO
INSERT INTO TestTran VALUES (3, 'ccc');
GO
-- This statement decrements @@TRANCOUNT to 2.
-- Nothing is committed.
COMMIT TRANSACTION Inner2;
GO
PRINT N'Transaction count after COMMIT Inner2 = '
+ CAST(@@TRANCOUNT AS nvarchar(10));
GO
-- This statement decrements @@TRANCOUNT to 1.
-- Nothing is committed.
COMMIT TRANSACTION Inner1;
GO
PRINT N'Transaction count after COMMIT Inner1 = '
+ CAST(@@TRANCOUNT AS nvarchar(10));
GO
-- This statement decrements @@TRANCOUNT to 0 and
-- commits outer transaction OuterTran.
COMMIT TRANSACTION OuterTran;
GO
PRINT N'Transaction count after COMMIT OuterTran = '
+ CAST(@@TRANCOUNT AS nvarchar(10));
GO

ROLLBACK:
ROLLBACK TRANSACTION erases all data modifications made from the start of
the transaction or to a savepoint. It also frees resources held by the transaction.
ROLLBACK TRANSACTION without a savepoint_name or transaction_name rolls back to the
beginning of the transaction. When nesting transactions, this same statement rolls back all inner
transactions to the outermost BEGIN TRANSACTION statement. In both cases, ROLLBACK

TRANSACTION decrements the @@TRANCOUNT system function to 0. ROLLBACK


TRANSACTION savepoint_name does not decrement @@TRANCOUNT.
USE TempDB;
GO
CREATE TABLE ValueTable ([value] int)
GO
DECLARE @TransactionName varchar(20) = 'Transaction1';
--These statements start a named transaction,
--insert a two records, and then roll back
--the transaction named in the variable
--@TransactionName.
BEGIN TRAN @TransactionName
INSERT INTO ValueTable VALUES(1)
INSERT INTO ValueTable VALUES(2)
ROLLBACK TRAN @TransactionName
INSERT INTO ValueTable VALUES(3)
INSERT INTO ValueTable VALUES(4)
SELECT * FROM ValueTable
DROP TABLE ValueTable
--Results
--value
--------------3
--4

Whenever you execute a COMMIT TRANSACTION statement, any transaction


name after the statement is ignored. The only thing a COMMIT TRANSACTION
statement does is reduce the @@trancount variable by 1. If this makes

@@trancount = 0, then all database modifications are committed.


CREATE TABLE TestTran (Cola INT PRIMARY KEY, Colb CHAR(3))
GO
BEGIN TRANSACTION OuterTran @@TRANCOUNT set to 1.
GO
INSERT INTO TestTran VALUES (1, aaa)
GO
BEGIN TRANSACTION Inner1 @@TRANCOUNT set to 2.
GO
INSERT INTO TestTran VALUES (2, bbb)
GO
BEGIN TRANSACTION Inner2 @@TRANCOUNT set to 3.
GO
INSERT INTO TestTran VALUES (3, ccc)
GO
COMMIT TRANSACTION Inner2 Decrements @@TRANCOUNT to 2.
Nothing committed.
ROLLBACK TRANSACTION Inner1
GO
COMMIT TRANSACTION Inner1 Decrements @@TRANCOUNT to 1.
Nothing committed.
GO
COMMIT TRANSACTION OuterTran Decrements @@TRANCOUNT to 0.
Commits outer transaction OuterTran.
GO
DROP TABLE TestTran
The only transaction name that SQL Server cares about is OuterTran. Its fine to label Inner1

and Inner2 transactions for other developers, but SQL Server does not use them.
Also, the COMMIT TRANSACTION statement does not use the transaction name.
Only a ROLLBACK uses the transaction name, and only the outermost transaction
name. For example, trying to do ROLLBACK TRANSACTION Inner1 where it is
commented out in the code snippet above would not work.
Committing inner transactions is ignored by Microsoft SQL Server. The
transaction is either committed or rolled back based on the action taken at the end

of the outermost transaction. If the outer transaction is committed, the inner nested
transactions are also committed. If the outer transaction is rolled back, then all
inner transactions are also rolled back, regardless of whether or not the inner
transactions were individually committed.

To List all the databases on the server:

EXEC sp_databases
To list fields in a table :

sp_help tablename
Eg:
sp_help studentTable
Or

SELECT tablename
FROM DBName.sys.tables;
To the get the Tables count in the DB

SELECT Count(*)
FROM DBName.sys.tables;

By default we can find the created date of all tables also

SELECT name,Create_Date
FROM DBName.sys.tables;

Inserting Records Into Table containing Self-reference


USE VideoRentalSystem
go
CREATE TABLE Emp

(
EmpID int PRIMARY KEY,
EmpName varchar(30),
MgrID int FOREIGN KEY REFERENCES Emp(EmpID)
)
GO
INSERT dbo.Emp VALUES( 1, 'President', NULL)
go
INSERT dbo.Emp Values(2, 'Vice President', 1)
go
INSERT dbo.Emp values( 3, 'CEO', 2)
go
INSERT dbo.Emp values( 4, 'CTO', 2)
go
INSERT dbo.Emp values( 5, 'Group Project Manager', 4)
go

The UPDATE command


UPDATE tableName SET Field1= 'val1', Field2 = val2, Field3 = val3
WHERE Field4 = val4
The DELETE command

Delete From Table-name --> Deletes all the records


Delete From Table-name where condition --> Deletes only those records that
meet the criteria

Using OUTPUT clause with insert,update


and delete commands:
Use Mycompany
go
--Select * from customer
--go
insert into MyCompany.dbo.customer
output inserted.CustId,inserted.CustName,inserted.CustCity
values
(400,'John','Chennai')
go
update customer set CustName='xxxxx',CustCity='yyyy'
output inserted.CustName,inserted.CustCity where CustId=300
go
update customer set CustName='xxxxx',CustCity='yyyy'
output inserted.* where CustId=300
go
delete from customer output deleted.* where CustId >= 300
go

Queries:

List All the distributors


Select * from Distributor
go
Show number and phone belonging to all distributors
Select DistributorNum,Phone from Distributor
go
Show Id,First name and Last name of all customers
Select CustomerId,Fname,Lname from Customer
Go
Show First Name, Id and Last Name of all customers
Select FName,CustomerId,LName from Customer
Go
Display Id and City of all customers
Select CustomerId,City from Customer
go
Show all the details of all the customers:
Select CustomerId,FName,LName,Phone,Street,City,ZipCode from customer
go
--Select * from Customer
--go

Coulmn-aliasing:
Show all the details of all the distributors. In the report, change first and second

filed names as Distributor Number and Title respecitvely


Select DistributorNum as [Distributor Number],DistributorName as [Title],Phone
from Distributor
go
Prefixing Column name with Table name
Select Distributor.DistributorNum,Distributor.DistributorName,Distributor.Phone
from Distributor
Table aliasing:
Select Dist.DistributorNum,Dist.DistributorName,Dist.Phone
from Distributor Dist
Conditional Retrieval:
List the details of all those customers who live in LA
Select * from Customer where City='LA'
go
Show First name and Last name of that customer whose id is 200334
Select FName,LName from Customer where CustomerId=200334
go
Show number,title,distributor number and price of all those videos whose prices
are greater than or equal to 3.0
Select VideoNum,Vtitle, DistNum, Price from Video where Price >= 3.0
go

Select VideoNum,Vtitle, DistNum, Price from Video where Price >= 1.0 and Price
<= 3.0
go

Some More Sample Tables and Queries:


CREATE TABLE DEPARTMENTS
(DEPTNO NUMERIC(2) PRIMARY KEY,
DNAME VARCHAR(14),
LOC VARCHAR(13) )
INSERT INTO DEPARTMENTS VALUES (10, 'ACCOUNTING', 'NEW YORK'),
(20, 'RESEARCH', 'DALLAS'),
(30, 'SALES', 'CHICAGO'),
(40, 'OPERATIONS', 'BOSTON');
GO

CREATE TABLE EMPLOYEE


(EMPNO NUMERIC(4) PRIMARY KEY,
ENAME VARCHAR(10) NOT NULL,
JOB VARCHAR(9) NOT NULL,
MGR NUMERIC(4) NULL,
HIREDATE DATETIME NOT NULL,
SAL NUMERIC(7, 2) NOT NULL CHECK(SAL <= 10000),
COMM NUMERIC(7, 2) NULL,
DEPTNO NUMERIC(2) REFERENCES Departments(DEPTNO))
INSERT INTO EMPLOYEE VALUES
(7369, 'SMITH', 'CLERK', 7902, '17-DEC-1980', 800, NULL, 20),
(7499, 'ALLEN', 'SALESMAN', 7698, '20-FEB-1981', 1600, 300, 30),
(7521, 'WARD', 'SALESMAN', 7698, '22-FEB-1981', 1250, 500, 30),
(7566, 'JONES', 'MANAGER', 7839, '2-APR-1981', 2975, NULL, 20),
(7654, 'MARTIN', 'SALESMAN', 7698, '28-SEP-1981', 1250, 1400, 30),
(7698, 'BLAKE', 'MANAGER', 7839, '1-MAY-1981', 2850, NULL, 30),
(7782, 'CLARK', 'MANAGER', 7839, '9-JUN-1981', 2450, NULL, 10),
(7788, 'SCOTT', 'ANALYST', 7566, '09-DEC-1982', 3000, NULL, 20),
(7839, 'KING', 'PRESIDENT', NULL, '17-NOV-1981', 5000, NULL, 10),

(7844, 'TURNER', 'SALESMAN', 7698, '8-SEP-1981', 1500, 0, 30),


(7876, 'ADAMS', 'CLERK', 7788, '12-JAN-1983', 1100, NULL, 20),
(7900, 'JAMES', 'CLERK', 7698, '3-DEC-1981', 950, NULL, 30),
(7902, 'FORD', 'ANALYST', 7566, '3-DEC-1981', 3000, NULL, 20),
(7934, 'MILLER', 'CLERK', 7782, '23-JAN-1982', 1300, NULL, 10);
GO

CREATE TABLE SALGRADE


(GRADE NUMERIC,
LOSAL NUMERIC,
HISAL NUMERIC)
INSERT INTO SALGRADE VALUES (1, 700, 1200),
(2, 1201, 1400),
(3, 1401, 2000),
(4, 2001, 3000),
(5, 3001, 9999);
Operators in SQLServer:
An operator is a symbol specifying an action that is performed on one or more
expressions. The following tables lists the operator categories that SQL Server
uses.
Arithmetic Operators

Logical Operators

Assignment Operator

Scope Resolution Operator

Bitwise Operators

Set Operators

Comparison Operators

String Concatenation Operator

Compound Operators

Unary Operators

Operators have the precedence levels shown in the following table. An operator on
higher levels is evaluated before an operator on a lower level.
Level
1

Operators
~ (Bitwise NOT)

* (Multiply), / (Division), % (Modulo)

+ (Positive), - (Negative), + (Add), (+ Concatenate), - (Subtract), & (Bitwise AND), ^ (Bitwise


Exclusive OR), | (Bitwise OR)

=, >, <, >=, <=, <>, !=, !>, !< (Comparison operators)

NOT

(Logical)

AND

(Logical)

ALL, ANY, BETWEEN, IN, LIKE, OR, EXISTS, SOME

= (Assignment)

(Logical)

Note:
The plus (+) and minus (-) operators can also be used to perform arithmetic
operations on datetime and smalldatetime values.
SQL Server provides the following set operators. Set operators combine results
from two or more queries into a single result set.
EXCEPT INTERSECT
UNION

The scope resolution operator :: provides access to static members of a compound


data type. A compound data type is one that contains multiple simple data types
and methods.

Compound operators execute some operation and set an original value to the result
of the operation. For example, if a variable @x equals 35, then @x += 2 takes the
original value of @x, add 2 and sets @x to that new value (37).

select * from employee where Sal >= 2000 AND Sal <= 4500
select * from employee where Sal BETWEEN 2000 AND 4500
select * from employee where Sal not between 2000 and 4500
select * from employee where hiredate between '1980-12-17' and '1981-12-03'
select * from employee where hiredate between '17-DEC-1980' and '3-DEC-1981'
select * from employee where deptno = 10 or deptno = 20;
select * from employee where deptno in(10,20);
select * from employee where deptno NOT in(10,20);
select * from employee where comm is null

select empno,ename from employee order by empno


select ename,Sal from employee order by sal
select ename,Sal from employee order by sal,ename
select * from employee order by deptno,job
wrong: for displaying records of those employees who are managers and working
in 10 or 20

select * from employee where job='MANAGER' and deptno=10 or deptno=20


order by deptno
select * from employee where deptno=10 or deptno=20 AND job='MANAGER'
order by deptno
Correct:
select * from employee where job='MANAGER' and (deptno=10 or deptno=20)
order by deptno
select * from employee where ename='CLARK'
select ename from EMPLOYEE where ENAME='martin'
SELECT ename FROM employee
WHERE ename COLLATE Latin1_General_CS_AS = 'martin'
What is collation?
Collation refers to a set of rules that determine how data is sorted and compared. Character data
is sorted using rules that define the correct character sequence.

CREATE TABLE mytable


(
mycolumn VARCHAR(10)
)
GO
INSERT mytable VALUES('Case')
GO
SELECT mycolumn FROM mytable WHERE mycolumn='Case'
SELECT mycolumn FROM mytable WHERE mycolumn='caSE'
SELECT mycolumn FROM mytable WHERE mycolumn='case'
You can alter your query by forcing collation at the column level:

SELECT myColumn FROM myTable

WHERE myColumn COLLATE Latin1_General_CS_AS = 'caSE'


SELECT myColumn FROM myTable
WHERE myColumn COLLATE Latin1_General_CS_AS = 'case'
SELECT myColumn FROM myTable
WHERE myColumn COLLATE Latin1_General_CS_AS = 'Case'
-- if myColumn has an index, you will likely benefit by adding
-- AND myColumn = 'case'
ALTER TABLE mytable
ALTER COLUMN mycolumn VARCHAR(10)
COLLATE Latin1_General_CS_AS
GO

INSERT mytable VALUES('Case')


SELECT mycolumn FROM mytable WHERE mycolumn='Case'
SELECT mycolumn FROM mytable WHERE mycolumn='caSE'
SELECT mycolumn FROM mytable WHERE mycolumn='case'
CREATE TABLE mytable
(
mycolumn VARCHAR(10)COLLATE Latin1_General_CS_AS
)
GO

use master

go
create database BIN collate Latin1_General_BIN
go
create database CI_AI_KS collate Latin1_General_CI_AI_KS
go
create database CS_AS_KS_WS collate Latin1_General_CS_AS_KS_WS
go

DELETE FROM TableName


OUTPUT DELETED.Columns
WHERE Condition(s)

Appendix A: Collation Suffixes


Suffix
Meaning
_BIN
binary sort
_CI_AI
case-insensitive, accent-insensitive, kanatype-insensitive, width-insensitive
_CI_AI_WS
case-insensitive, accent-insensitive, kanatype-insensitive, width-sensitive
_CI_AI_KS
case-insensitive, accent-insensitive, kanatype-sensitive, width-insensitive
_CI_AI_KS_WS case-insensitive, accent-insensitive, kanatype-sensitive, width-sensitive
_CI_AS
case-insensitive, accent-sensitive, kanatype-insensitive, width-insensitive
_CI_AS_WS
case-insensitive, accent-sensitive, kanatype-insensitive, width-sensitive
_CI_AS_KS
case-insensitive, accent-sensitive, kanatype-sensitive, width-insensitive
_CI_AS_KS_WS case-insensitive, accent-sensitive, kanatype-sensitive, width-sensitive
_CS_AI
case-sensitive, accent-insensitive, kanatype-insensitive, width-insensitive
_CS_AI_WS
case-sensitive, accent-insensitive, kanatype-insensitive, width-sensitive
_CS_AI_KS
case-sensitive, accent-insensitive, kanatype-sensitive, width-insensitive
_CS_AI_KS_WS case-sensitive, accent-insensitive, kanatype-sensitive, width-sensitive
_CS_AS
case-sensitive, accent-sensitive, kanatype-insensitive, width-insensitive
_CS_AS_WS
case-sensitive, accent-sensitive, kanatype-insensitive, width-sensitive
_CS_AS_KS
case-sensitive, accent-sensitive, kanatype-sensitive, width-insensitive
_CS_AS_KS_WS case-sensitive, accent-sensitive, kanatype-sensitive, width-sensitive
Note Kana sensitivity is set by default to insensitive. In other words, by default,
katakana and hiragana are treated as the same. Width sensitivity is also insensitive by
default. In other words, by default, full-width and half-width characters are treated as
the same.

select langid, alias, lcid, msglangid from sys.syslanguages


A collation is a set of rules defining a character set and its sorting rules. SQL
Server support a large number of built-in collations. For example:
Albanian_CI_AI_KS_WS - Albanian, case-insensitive (CI), accent-insensitive (AI),
kanatype-sensitive (KS), width-sensitive (WS).
Arabic_CI_AS_KS_WS - Arabic, case-insensitive, accent-sensitive, kanatype-sensitive,

width-sensitive.
French_CI_AI - French, case-insensitive, accent-insensitive, kanatype-insensitive, widthinsensitive.
Korean_Wansung_BIN - Korean-Wansung, binary sort.
SQL_Latin1_General_CP1250_CI_AS - Latin1-General, case-insensitive, accentsensitive, kanatype-insensitive, width-insensitive.

SELECT * FROM fn_helpcollations()


GO

SQL Server Functions Grouping Records


Ordering Records - Partitioning Records
To support determinism and non-determinism, Transact-SQL provides two broad categories of
functions. A function that always returns the same or known value is referred to as deterministic.
A function whose returned value may depend on a condition is referred to as non-deterministic.
Cast Function:
In most cases, a value the user submits to your database is primarily considered a string. This is
convenient if that's what you are expecting. If the value the user provides must be treated as
something other than a string, for example, if the user provides a number, before using such a
value, you should first convert it to the appropriate type, that is, from a string to the expected
type.
CAST(Expression AS DataType)

The Expression is the value that needs to be cast.


The DataType factor is the type of value we want to convert the Expression to.

Print Cast('121' As int)

Print Cast('1234' As Decimal(6,2))


Convert Function:
Like CAST(), the CONVERT() function is used to convert a value.
Unlike CAST(), CONVERT() can be used to convert a value from its original
type into a non-similar type.
For example, you can use CONVERT to cast a number into a string
and vice-versa.
The syntax of the CONVERT() function is:
CONVERT(DataType [ ( length ) ] , Expression)

Print Convert(int,125.66);
String based functions:
To get the length of a string, you can use the LEN() function.
Its syntax is:
int LEN(String)

select LEN('hello world')


print len('hello world')

If you have a string, to get the ASCII code of its leftmost character,
you can use the ASCII() function. Its syntax is:
int ASCII(String)

This function takes a string as argument and returns the


ASCII code of the first (the left) character of the string.

print Ascii('allen')
If you have the ASCII code of a character and want to find its actual character, you
can use the CHAR() function. Its syntax is:
char CHAR(int value)

This function takes an integer value as argument

and returns the ASCII equivalent of that number.

print Char(65)
When you receive a string, if you want to convert all of its characters to lowercase,
you can use the LOWER() function. Its syntax is:
varchar LOWER(String)

This function takes as argument a string. Any lowercase letter that is part of the string would not
change. Any letter that is part of the string would be converted to lowercase. Any other character
or symbol would be kept "as is". After conversion, the LOWER() function returns a new string.

print lower('HELLO world9%')


A sub-string is a section gotten from a string. The idea is to isolate one or a group
of characters for any necessary reason.
A left sub-string is one or a group of characters retrieved from the left side of a known string. To
get the left sub-string of a string, you can use the LEFT() function. Its syntax is:
varchar LEFT(String, NumberOfCharacters)

This function takes two arguments.


The first argument specifies the original string.
The second argument specifies the number of characters from
the most-left that will constitute the sub-string.
After the operation, the LEFT() function returns a new
string made of the left character + the NumberOfCharacters
on its right from the String.

print left('system',3)
varchar RIGHT(String, NumberOfCharacters)
print right('system',3)
To replace one character or a sub-string from a string, you can use the
REPLACE() function. Its syntax is:
varchar REPLACE(String, FindString, ReplaceWith)

print replace('system','sys','xxxx')

Arithmetic Functions:
SIGN(Expression)
print sign(125)
print sign(-125)
print sign(null)
To get the absolute value of a number, you can use the ABS() function. Its syntax
is:
ABS(Expression)

print abs(-1567.77789)
print abs('-12.5')
In algebra, the ceiling of a number is the closest integer that is greater than or
higher than the number considered. In the first case, the ceiling of 12.155 is 13
because 13 is the closest integer greater than or equal to 12.155. The ceiling of
24.06 is 24.
To get the ceiling of a number, Transact-SQL provides the CEILING() function. Its syntax is:
CEILING(Expression)

This function takes as argument a number or an expression that can evaluate to a number. After
the conversion, if the function succeeds, it returns a double-precision number that is greater than
or equal to Expression.

print ceiling(12.456)
print ceiling(-24.06)
Consider two decimal numbers such as 128.44 and -36.72. The number 128.44 is
between 128 and 129 with 128 being the lower. The number 36.72 is between 37
and 36 with 37 being the lower. The lowest but closest integer value of a number
is referred to as its floor. Based on this, the floor of 128.44 is 128. The floor of
36.72 is 37.

To support finding the floor of a number, Transact-SQL provides the FLOOR() function. Its
syntax is:
FLOOR(Expression)

The FLOOR() function takes as argument a numeric value or an expression that can be
evaluated to a number.

print floor(128.44)
print floor(-36.72)
To calculate the exponential value of a number, Transact-SQL provides the EXP()
function. Its syntax is:
EXP(Expression)

This function takes one argument as a number or an expression that can be evaluated to a
number.

print exp(6.48)
The power of a number is the value of that number when raised to another number.
This is done using the following formula:
ReturnValue = xy

To support finding the power of a number, Transact-SQL provides the POWER() function. Its
syntax is:
POWER(x, y)

This function takes two required arguments. The first argument, x, is used as the base number to
be evaluated. The second argument, y, also called the exponent, will raise x to this value.

print power(5,2)
print power(5,2.1)
print power(2.667,8)
To assist with finding the natural logarithm of a number, Transact-SQL provides
the LOG() function. Its syntax is:
LOG(Expression)

This function takes one argument as a number or an expression that can evaluate to a number.
After the calculation, it returns the natural logarithm of the argument.

print log(10)
print log(48.16)
To calculate the base 10 logarithm of a number, Transact-SQL provides the
LOG10() function. Its syntax is:
LOG10(Expression)

The number to be evaluated is passed as the argument X. The function returns the logarithm on
base 10 using the formula:
y = log10x

which is equivalent to
x = 10y

print log10(10)
print log10(48.16)
To support the calculation of a square root, Transact-SQL provides the SQRT()
function. Its syntax is:
SQRT(Expression)

This function takes one argument as a positive decimal number. If the number is positive, after
the calculation, the function returns the square root of x.

print sqrt(25)
print sqrt(27.999)
Measure based function:
The letter , also written as PI, is a number used in various mathematical
calculations. Its approximate value is 3.1415926535897932. The calculator of
Microsoft Windows represents it as 3.1415926535897932384626433832795. To
get the value of PI, Transact-SQL provides the PI() function. Its syntax is simply:
PI()

print PI()
If you know the value of an angle in degrees and you want to get the radians,
Transact-SQL provides the RADIANS() function. Its syntax is:
RADIANS(Expression)

This function takes as argument a value in degrees. If it succeeds in its calculation, it returns the
radians value.

print radians(180)
If you know the radians but want to get the degrees of an angle, you can use the
DEGREES() function. Its syntax is:
DEGREES(Expression)

This function takes as argument a value in radians. If it succeeds, it returns the equivalent value
in degrees.

print degrees(4)
To get the cosine of an angle, you can call the COS() function. Its syntax is:
COS(Expression)

The angle to be considered is passed as the argument to this function. The function then
calculates and returns its cosine.

print cos(45)
To get the sine of an angle, you can use the SIN() function whose syntax is:
SIN(Expression)

The angle to be considered is passed as the argument. After its calculation, the function returns
the sine of the angle between 1 and 1.

print sin(60)
To get the tangent of an angle, you can use the TAN() function of Transact-SQL.
Its syntax is:
TAN(Expression)

Date and time based functions:


To get the current date and the current time of the computer that a user is using,
you can use the GETDATE() function of Transact-SQL. Its syntax is:
GETDATE()

This function simply returns the current date and time of the operating system.

print GetDate()
One of the primary operations you may want to perform on a date or a time value
would consist of adding a value to it. To support this operation, Transact-SQL
provides the DATEADD() function. Its syntax is:
DATEADD(TypeOfValue, ValueToAdd, DateOrTimeReferenced)

The third argument to this function is the value of a date or a time on which the operation will be
performed. It can be a constant value in the form of 'year/month/day' for a date or 'hour:minutes
AM/PM' for a time.
The second argument is the value that will be added. It should be a constant integer, such as 8, or
a floating point value, such as 4.06.
When calling this function, you must first specify the type of value that you want to add. This
type is passed as the first argument. It is used as follows:
If you want to add a number of years to a date, specify the TypeOfValue as Year or yy, or
yyyy (remember that SQL is case-insensitive).

print DATEADD(yy,4,GetDate())
print DATEADD(mm,4,GetDate())
print DATEADD(dd,4,GetDate())
print DATEADD(yy,8,'2010-04-27')
select DATEADD(yy,8,'2010-04-27') as [resultant date]
If you want to add a number of quarters of a year to a date, specify the
TypeOfValue as Quarter or d, or qq.
In the same way, you can add values as follows:
Type of
Value
Year
quarter
Month
dayofyear
Day
Week

Abbreviation
yy
yyyy
q
qq
m
mm
y
dy
d
dd
wk
ww

As a result
A number of years will be added to the date value
A number of quarters of a year will be added to the date value
A number of months will be added to the date value
A number of days of a year will be added to the date value
A number of days will be added to the date value
A number of weeks will be added to the date value

Hour
minute
second
millisecond

hh
n
mi
s
ss
ms

A number of hours will be added to the time value


A number of minutes will be added to the time value
A number of seconds will be added to the time value
A number of milliseconds will be added to the time value

Another regular operation performed on a date or a time value consists of getting


the number of units that has elapsed in the range of two dates or two time values.
To support this operation, Transact-SQL provides the DATEDIFF() function. Its
syntax is:
DATEDIFF(TypeOfValue, StartDate, EndDate)

This function takes three arguments. The second argument is the starting date or the starting time
of the range to be considered. The third argument is the end or last date or time of the considered
range. You use the first argument to specify the type of value you want the function to produce.
This argument uses the same value as those of the DATEADD() function:
Type of
Value
Year
quarter
Month
dayofyear
Day
Week
Hour
minute
second
millisecond

Abbreviation
yy
yyyy
q
qq
m
mm
y
dy
d
dd
wk
ww
hh
n
mi
s
ss
ms

As a result
The function will return the number of years that have elapsed
between the start and the end dates
The function will return the number of quarters of a year that have
elapsed between the start and the end dates
The function will return the number of months that have elapsed
between the start and the end dates
The function will return the number of days of a year that have
elapsed between the start and the end dates
The function will return the number of days that have elapsed
between the start and the end dates
The function will return the number of weeks that have elapsed
between the start and the end dates
The function will return the number of hours that have elapsed
between the start and the end times or dates
The function will return the number of minutes that have elapsed
between the start and the end times or dates
The function will return the number of seconds that have elapsed
between the start and the end times or dates
The function will return the number of milliseconds that have elapsed
between the start and the end times or dates

print DATEDIFF(yy,'2000-11-10',GetDate())

Aggregate Functions:
Count: The database engine uses the Count() function to count the number of
occurrences of the category in the column and produces the total. This function
also counts NULL values. The syntax of the Count() function is:
int COUNT ( { [ [ ALL | DISTINCT ] expression ] | * } )

This function takes one argument. To get the count of occurrences of a value, in the Criteria
section, select COUNT(*).

The Count() function returns an int value. If you are working on a large number of
records, you can call the Count_Big() function. Its syntax is:
bigint COUNT_BIG ( { [ ALL | DISTINCT ] expression } | * )

If the column holds numeric values:


Sum: The Sum() function is used to sum up the values in the category. The syntax of the
Sum() function is:
Number SUM ( [ ALL | DISTINCT ] expression )

Avg: The sum of value in a category would be divided by the number of


occurrences in that category to get the average. The syntax of the Avg() function is:
Number AVG ( [ ALL | DISTINCT ] expression )

Min: The lowest value of the category would be produced from the Min()
function. The syntax of this function is:

DependsOnType MIN ( [ ALL | DISTINCT ] expression )

Max: The highest value of the category would be produced using the Max()
function. The syntax of this function is:

DependsOnType MAX ( [ ALL | DISTINCT ] expression )

StdDev: The StdDev() function is used to calculate the standard deviation


of all numeric values of a group. If there is no value or the same value in the
considered group, this function returns NULL. This means that there
should be at least two different values in the group.
The syntax of the StdDev() function is:
float STDEV ( [ ALL | DISTINCT ] expression )

Var: The Var() function calculates the statistical variance of


all numeric values of a group. If there is no value or the same value in the
considered group, this function returns NULL. The syntax of the
Var() function is:
float VAR ( [ ALL | DISTINCT ] expression )

select COUNT(comm) from EMPLOYEE;


select COUNT(*) from EMPLOYEE;
select COUNT(*) 'total_no_emp' from EMPLOYEE;
select count(*) as [total number of employees]from EMPLOYEE ;
select COUNT(job)from EMPLOYEE;
select COUNT(distinct job) from EMPLOYEE;
select AVG(sal) from EMPLOYEE;
select MIN(sal) from EMPLOYEE;
select MAX(sal) from EMPLOYEE;
select MAX(comm) from EMPLOYEE;
select stdev(Sal) from EMPLOYEE;
select VAR(sal) from EMPLOYEE;
use videorentalsystem
go
select * from video

go
Select SUM(Price) from Video
go
Select MIN(Price) from Video
go
Select MAX(Price) from Video
go
Select AVG(Price) from Video
go
Select COUNT(Phone) from Customer
go
Select COUNT(*) from Customer
go
Select COUNT(VTitle) from Video
go
Select COUNT(distinct VTitle) from Video
go
Select COUNT(VType) from Video
go
Select COUNT(Distinct VType) from Video
go
use videorentalsystem
go
Select * from Video
go
SElect City, COUNT(CustomerId) from customer
Group By City
go
SElect City, COUNT(CustomerId) As [Customer Id] from customer
Group By City

go
Select VType, COUNT(*) As [Num Of Videos] from Video
group by VType
go
Select DistNum, COUNT(*) As [Num of Videos] from Video
group by DistNum
go
Select VType,DistNum, COUNT(*) As [Num of Videos] from Video
group by VType,DistNum order by VType
go
Select DistNum, SUM(Price) as [Total Investment] from Video
Group By DistNum
go
Select DistNum, Avg(Price) as [Average Price] from Video
Group By DistNum
go
RollUp:
It is used to calculate cumulative totals at the end of grouping
created based on the first column in group.
Select VType, Sum(Price) as [Total Invested] from Video
Group By VType with RollUp
go
Select isnull(VType,'Total') VType, Sum(Price) as [Total Invested] from Video
Group By VType with RollUp
go
Cube is used for calculating sub-totals at the end of each group
Select DistNum,isnull(VType,'Total'), Sum(Price) As [Total Cost] from Video
group by VType,DistNum with cube
go

Compute and Compute by:


Compute by is like group by in that it also groups records and
applies aggregate functions on each group but unlike group by
compute by allows us to retrieve data from any column.
use videorentalsystem
go
select * from video compute sum(price)
use videorentalsystem
go
select * from video compute count(VideoNum)

Every column that is in by clause of compute by must be in order by


use videorentalsystem
go
select * from video order by VType compute sum(price) by VType;
Over (partition by...)
Determines the partitioning and ordering of the rowset before the associated
window function is applied.
PARTITION BY
Divides the result set into partitions. The aggregate function is applied to each partition
separately and computation restarts for each partition.

while "compute by" will display the result of aggregate only once at end of the
group where as over(partition by...) displays the results of aggregates with every
row in the group and not at the end of the group.
Find total cost of videos their type wise while displaying complete details of
video.
use videorentalsystem
go

select *, SUM(price) over(Partition by VType) from Video


use videorentalsystem
go
select *, SUM(price) over(Partition by VType) AS [Total Price] from Video
Find highest and lowest costs of videos in a type wise manner while displaying
complete details of every video.
use VideoRentalSystem
go
select *, MAX(price) over (Partition by VType), MIN(price) over(Partition by
VType) from Video
go
select *, MAX(price) over (Partition by VType) As [Min], MIN(price)
over(Partition by VType) As [Max] from Video
go
Ranking functions return a ranking value for each row in a partition. Depending on
the function that is used, some rows might receive the same value as other rows.
Ranking functions are nondeterministic.
Rank:
Returns the rank of each row within the partition of a result set. The rank of a row
is one plus the number of ranks that come before the row in question.
If two or more rows tie for a rank, each tied rows receives the same rank. For
example, if salaries of two employees are the highest and are also equal then,
they are both ranked one. The employee with the next highest salary is ranked
number three, because there are two rows that are ranked higher. Therefore, the
RANK function does not always return consecutive integers. The sort order that is
used for the whole query determines the order in which the rows appear in a result
set.
Dense Rank:
Returns the rank of rows within the partition of a result set, without any gaps in the

ranking. The rank of a row is one plus the number of distinct ranks that come
before the row in question.
If two or more rows tie for a rank in the same partition, each tied rows receives the
same rank. For example, if salaries of two employees are the highest and are
also equal then, they are both ranked one. The employee with the next highest
salary is ranked number two. This is one more than the number of distinct rows
that come before this row. Therefore, the numbers returned by the DENSE_RANK
function do not have gaps and always have consecutive ranks. The sort order used
for the whole query determines the order in which the rows appear in a result. This
implies that a row ranked number one does not have to be the first row in the
partition.
use VideoRentalSystem
go
select row_number() over (order by price desc) as [Row number],
VTitle,Price,RANK() over (order by price desc) as [Rank],
DENSE_RANK() over (order by price desc) as [Dense Rank]
from Video
---------------------*
select ROW_NUMBER() over(order by sal desc), ename,Sal,RANK()
over (order by sal desc), DENSE_RANK() over (order by sal desc) from employee
show emplyoee name,department number and salary along with rank fro the
employee based on salary dept wise by giving rank1 for the highest paid employee.
select ROW_NUMBER() over(partition by deptno order by sal desc)
as Sno, ename,deptno,sal,RANK() over (partition by deptno order by sal desc)
as [rank],DENSE_RANK() over (partition by deptno order by sal desc)
as [dense rank] from EMPLOYEE
---------------------------------*
Top 'n':
This is used to retrieve top 'n' rows from the list of rows retrieved by the selected
statements. It supports a keyword percent to retrieve top n percent of rows
instead of top n rows. It also supports the keyword 'with ties to retrieve every row
from the table that has same value as last row retrieved by the top n clause withing
the column that is specified by in order by clasuse.

Select Top 3 * from Video


go
Select Top 2 * from Video order by Price
go
Select Top 2 * from Video Order By Price Desc
go
Select Top 2 With Ties * from Video Order By Price Desc
go
Select Top 50 Percent * from Video
go
Select Top 20 Percent * from Video Order By Price Desc
go
select top 2 * from EMPLOYEE order by SAL desc
select top 2 with ties * from EMPLOYEE order by SAL desc
select top 40 percent * from EMPLOYEE order by SAL desc

Select Case Statement in Queries

Use Videorentalsystem
go
SELECT VideoNum, VTitle, Vtype,Price, Price =
CASE

WHEN Price >=5 Then 'High Cost'


WHEN Price >= 3 Then 'Medium Cost'
ELSE 'Low Cost'
END
FROM Video
-------------------------------*
Use Videorentalsystem
go
select
case when GROUPING(DistNum)=1 then 'All Distributors'
else CAST(DistNum as varchar) end DistNum,
case when grouping (VType) =1 then 'All Categories'
else VType end Ttype,
SUM(Price)
from Video group by DistNum,VType with rollup
------------------------------*
Use Videorentalsystem
go
select
case when GROUPING(DistNum)=1 then 'All Distributors'
else CAST(DistNum as varchar) end DistNum,
case when grouping (VType) =1 then 'All Categories'
else VType end Ttype,
SUM(Price)AS [Sum]
from Video group by DistNum,VType with Cube
---------------------------------------*

select
case when GROUPING(deptno)=1 then 'All Departments'

else CAST(deptno as varchar) end deptno,


case when grouping (job) =1 then 'All Jobs'
else Job end job,
SUM(sal)
from employee group by deptno,job with rollup
-------------------------------------------------*
select
case when grouping (job) =1 then 'All Jobs'
else Job end job,
case when GROUPING(deptno)=1 then 'All Departments'
else CAST(deptno as varchar) end deptno,
SUM(sal)
from employee group by deptno,job with cube

JOINS
A Join allows us to retrieve data from multiple tables using
a single select statement.
They are classified as:
Cross Join
Inner Join
Outer Join
ANSI syntax:
SELECT <columns-list> FROM <table1>
inner join / outer join/ cross join <table2>
[ on <join condition>]......
Non-ANSI
SELECT <columns-list> FROM <table1>,<table2>....,<tableN>
[where <join codition>]

Inner JOIN
A JOIN that displays only rows that have a match in both the joined
tables is known as INNER JOIN.
Equi Join: This is the inner join or outer join that uses '=' operator in the join condition

Natural Join: Either inner join or outer join is a natural join if:
it uses '=' operator
all common columns in the tables are in the join condition
only one set of common columns is displayed in the operation
Non-Equi join: The inner join or outer join that uses an operator other than '=' in join condition
Self-Join: A join that joins a table with itself

Outer JOIN
A JOIN that includes rows even if they do not have related rows in the joined table is an
Outer JOIN. You can create three different outer JOINs to specify the unmatched rows to be
included:
Left Outer JOIN: In Left Outer JOIN, all rows in the first-named table, i.e. left table,
which appears leftmost in the JOIN clause, are included.
Unmatched rows in the right table do not appear.
Right Outer JOIN: In Right Outer JOIN, all rows in the second-named table, i.e. right table,
which appears rightmost in the JOIN clause, are included. Unmatched rows in the left table are
not included.

Full Outer JOIN: In Full Outer JOIN, all rows in all the joined tables are included, whether they
are matched or not.

Examples:
Use Videorentalsystem
go
Create Table VideoGrades(LowPrice decimal(5,2),HighPrice decimal(5,2),Grade
char(1))
go
Insert into VideoGrades values(0.5,1.0,'C')
go
Insert into VideoGrades values(1.1,3.0,'B')
go
Insert into VideoGrades values(3.1,5.0,'A')
go
Use Videorentalsystem
go
select Rental.*,customer.FName,customer.LName
from Rental Cross Join Customer
go

Use Videorentalsystem
go
select Rental.CustomerId,Rental.VideoNumber,
Rental.DateRented,Customer.FName,Customer.LName,Customer.City
from Rental Inner Join Customer
ON Rental.CustomerId=Customer.CustomerId
go
--OR
Use Videorentalsystem
go
select Rental.CustomerId,Rental.VideoNumber,
Rental.DateRented,Customer.FName,Customer.LName,Customer.City
from Rental Join Customer
ON Rental.CustomerId=Customer.CustomerId
go

Joining 3 Tables:
Use Videorentalsystem
go
select Rental.CustomerId,Rental.VideoNumber,Video.VTitle,
Video.VType,Rental.DateRented,Customer.FName,Customer.LName,
Customer.City from Rental Inner Join Video
ON Rental.VideoNumber = Video.VideoNum Inner Join customer
ON Rental.CustomerId=Customer.CustomerId
Go

Examples Based On AdventureWorks


Database
INNER JOIN Example
In this example we are joining between the Sales.SalesOrderDetail and Production.Product
tables. The tables are aliased with the following: SOD for Sales.SalesOrderDetail and P for
Production.Product. The JOIN logic is based on matching records in the SOD.ProductID and
P.ProductID columns. The records are filtered by only returning records with the SOD.UnitPrice
greater than 1000. Finally, the result set is returned in order with the most expensive first based
on the ORDER BY clause and only the highest 100 products based on the TOP clause.

USE ADWorks
GO
SELECT TOP 100 P.ProductID,
P.Name,
P.ListPrice,
P.Size,
P.ModifiedDate,
SOD.UnitPrice,
SOD.UnitPriceDiscount,
SOD.OrderQty,
SOD.LineTotal
FROM Sales.SalesOrderDetail SOD
INNER JOIN Production.Product P
ON SOD.ProductID = P.ProductID
WHERE SOD.UnitPrice > 1000
ORDER BY SOD.UnitPrice DESC
GO
Joining 3 Tables

USE AdWorks;
GO
SELECT C.ContactID,
C.FirstName,
C.LastName,
SP.SalesPersonID,
SP.CommissionPct,
SP.SalesYTD,
SP.SalesLastYear,
SP.Bonus,
ST.TerritoryID,
ST.Name,
ST.[Group],
ST.SalesYTD
FROM Person.Contact C
INNER JOIN Sales.SalesPerson SP
ON C.ContactID = SP.SalesPersonID
Inner JOIN Sales.SalesTerritory ST
ON ST.TerritoryID = SP.TerritoryID
ORDER BY ST.TerritoryID, C.LastName
GO

LEFT OUTER JOIN Example

In this example we are combining two concepts to show that more than two tables can be
JOINed in one SELECT statement and more than one JOIN type can be used in a single
SELECT statement. In the sample code below, we are retrieving the matching data between the
Person.Contact and Sales.SalesPerson tables in conjunction with all of the data from the
Sales.SalesPerson table and matching data in the Sales.SalesTerritory table. For records that
exist Sales.SalesPerson table and not in the Sales.SalesTerritory table, NULL values are returned
for the columns in the Sales.SalesTerritory. In addition, this code uses two columns to order the
data i.e. ST.TerritoryID and C.LastName.

USE AdWorks;

GO
SELECT C.ContactID,
C.FirstName,
C.LastName,
SP.SalesPersonID,
SP.CommissionPct,
SP.SalesYTD,
SP.SalesLastYear,
SP.Bonus,
ST.TerritoryID,
ST.Name,
ST.[Group],
ST.SalesYTD
FROM Person.Contact C
INNER JOIN Sales.SalesPerson SP
ON C.ContactID = SP.SalesPersonID
LEFT OUTER JOIN Sales.SalesTerritory ST
ON ST.TerritoryID = SP.TerritoryID
ORDER BY ST.TerritoryID, C.LastName
GO
RIGHT OUTER JOIN Example
In an effort to explain how the RIGHT OUTER JOIN and LEFT OUTER JOIN is logically a
reciprocal on one another, the code below is re-written version of the LEFT OUTER JOIN
above. As you can see the JOIN order and tables are different, but the final result set matches the
LEFT OUTER JOIN logic. In the sample code below, we are retrieving the matching data
between the Person.Contact and Sales.SalesPerson tables in conjunction with all of the data from
the Sales.SalesPerson table and matching data in the Sales.SalesTerritory table. For records that
exist Sales.SalesPerson table and not in the Sales.SalesTerritory table, NULL values are returned
for the columns in the Sales.SalesTerritory.

USE AdWorks;
GO
SELECT C.ContactID,
C.FirstName,
C.LastName,
SP.SalesPersonID,
SP.CommissionPct,
SP.SalesYTD,
SP.SalesLastYear,
SP.Bonus,

ST.TerritoryID,
ST.Name, ST.[Group],
ST.SalesYTD

FROM Sales.SalesTerritory ST
RIGHT OUTER JOIN Sales.SalesPerson SP
ON ST.TerritoryID = SP.TerritoryID
INNER JOIN Person.Contact C
ON C.ContactID = SP.SalesPersonID
ORDER BY ST.TerritoryID, C.LastName
GO
Self Join Example
In this example, we are actually self joining to the HumanResources.Employee table. We are
doing this to obtain the information about the Employee and Manager relationship in the
HumanResources.Employee table. In conjunction with that JOIN logic we are also joining to the
Person.Contact twice in order to capture the name and title data based on the original Employee
and Manager relationships. In addition, another new concept introduced in this query is aliasing
each of the columns. Although we could have done so in the previous examples, we made point
of doing so in this query to differentiate between the Employee and Manager related data.

USE AdWorks;
GO
SELECT M.ManagerID AS 'ManagerID',
M1.ContactID AS 'ManagerContactID',
M1.FirstName AS 'ManagerFirstName',
M1.LastName AS 'ManagerLastName',
M.Title AS 'ManagerTitle',
E.EmployeeID AS 'EmployeeID',
E1.ContactID AS 'EmployeeContactID',
E1.FirstName AS 'EmployeeFirstName',
E1.LastName AS 'EmployeeLastName',
E.Title AS 'EmployeeTitle'
FROM HumanResources.Employee E
INNER JOIN HumanResources.Employee M
ON E.ManagerID = M.ManagerID
INNER JOIN Person.Contact E1
ON E1.ContactID = E.ContactID
INNER JOIN Person.Contact M1
ON M1.ContactID = M.ContactID
ORDER BY M1.LastName
GO

CROSS JOIN Example


As indicated above, please heed caution when running or modifying this query in any SQL
Server database environment. The result set is intentionally limited by the TOP 100 clause and
the WHERE clause to prevent a Cartesian product, which is the result of each of the rows from
the left table multiplied by the number of rows in the right table.

USE AdWorks;
GO
SELECT TOP 100 P.ProductID,
P.Name,
P.ListPrice,
P.Size,
P.ModifiedDate,
SOD.UnitPrice,
SOD.UnitPriceDiscount,
SOD.OrderQty,
SOD.LineTotal
FROM Sales.SalesOrderDetail SOD
CROSS JOIN Production.Product P
WHERE SOD.UnitPrice > 3500
ORDER BY SOD.UnitPrice DESC
GO
FULL OUTER JOIN Example
In our last example, we have modified the logic from the LEFT OUTER JOIN example above
and converted the LEFT OUTER JOIN syntax to a FULL OUTER JOIN. In this circumstance,
the result set is the same as the LEFT OUTER JOIN where we are returning all of the data
between both tables and data not available in the Sales.SalesTerritory is returned as NULL.

USE AdWorks;
GO
SELECT C.ContactID,
C.FirstName,
C.LastName,
SP.SalesPersonID,
SP.CommissionPct,
SP.SalesYTD,

SP.SalesLastYear,
SP.Bonus,
ST.TerritoryID,
ST.Name,
ST.[Group],
ST.SalesYTD

FROM Person.Contact C
INNER JOIN Sales.SalesPerson SP
ON C.ContactID = SP.SalesPersonID
FULL OUTER JOIN Sales.SalesTerritory ST
ON ST.TerritoryID = SP.TerritoryID
ORDER BY ST.TerritoryID, C.LastName
GO

SET OPERATIONS
Set Operations are used to combine multiple result sets
into one single result set.
There is BIG difference between join and Combine.
Join is Horizontal operation and Combine is vertical operation.
select * into cheapvideos from video where price < 3.0
select * into Employee_Hist from employee where hiredate < '1981-12-31'
Lets go with simple example so that it will give you clear picture.
Basically there are 3 set operators available in SQL Server.
1) Union: This is to combine two or more result sets into single
with or without (by using ALL) duplicates.
2) Except: Takes the data from one result set
where there is no matching in another.

3) Intersect: Takes the data from both the


result sets which are in common.
One thing you need to make sure is when you are using set Operations,
the No. of columns should be same with the data type.
There is no restriction on the column names.
Rules on Set Operations:
1) The column names or aliases must be determined by the first select.
2) Every select must have the same number of columns,
and each lineup of columns must share the same data-type family.
3) Expressions may be added to the select statements to identify
the source of the row so long as the column is added to every select.
4) ORDER BY clause should be part of the last Select statement,
which orders the results.

SELECT VideoNum,Vtitle,Price from Video


Union
SELECT VideoNum,Vtitle,Price from CheapVideos
go
SELECT VideoNum,Vtitle,Price from Video
Union ALL
SELECT VideoNum,Vtitle,Price from CheapVideos
go

SELECT Empno,eName,Sal,hiredate from Employee


UNION
SELECT Empno,eName,Sal,hiredate from Employee_HIST

Here also we are combining the results from Employee and Employee_HIST table.
When you use UNION ALL operator it will not eliminate the duplicate records
meaning if you have the same record in both tables then in the final output you will
see both the records.
UNION is always creates the performance issue. So when ever you are using
UNION use it very judiciously. If you are not sure of what kind of data you have
then you can use UNION. If you know you dont have any duplicate records for
which you want to combine the results then use UNION ALL.
SELECT Empno,eName,Sal,hiredate from Employee
UNION ALL
SELECT Empno,eName,Sal,hiredate from Employee_HIST
Intersection:
As you know this is basically to combine multiple result sets into single to fetch
the common records in multiple result sets. Inner join finds common rows
horizontally, while an INTERSECT finds common rows vertically.
SELECT VideoNum,Vtitle,Price from Video
Intersect
SELECT VideoNum,Vtitle,Price from CheapVideos
go
SELECT Empno,eName,Sal,hiredate from Employee
INTERSECT
SELECT Empno,eName,Sal,hiredate from Employee_HIST
Except:
This is basically to return all the records from one result set where there is no
matching in another table. This looks very similar to Outer join but join does
horizontally and EXCEPT does vertically.
SELECT VideoNum,Vtitle,Price from Video
Except
SELECT VideoNum,Vtitle,Price from CheapVideos

go
SELECT Empno,eName,Sal,hiredate from Employee
EXCEPT
SELECT Empno,eName,Sal,hiredate from Employee_HIST
With the above query we are fetching only the records which are in Employee but
not in Employee_HIST.
SELECT VideoNum,Vtitle,Price,Price*0.5 AS sf1 from Video
Union ALL
SELECT VideoNum,Vtitle,Price,Price*0.5 As sf2 from CheapVideos
go
SELECT VideoNum,Vtitle,Price from Video
Union ALL
SELECT VideoNum,Vtitle,Price from CheapVideos Order by Price
go
Summary:
Normally set operations are costly operations so use them very judiciously.

SUBQUERIES
A subquery is a query that is nested inside a
SELECT, INSERT, UPDATE, or DELETE statement,
or inside another subquery.
A subquery is also called an inner query or inner select,
while the statement containing a subquery is also called
an outer query or outer select.
Many Transact-SQL statements that include subqueries
can be alternatively formulated as joins. Other questions

can be posed only with subqueries.


In Transact-SQL,
there is usually no performance difference between a
statement that includes a subquery and a join.
However, in some
cases where existence must be checked, a join yields
better performance.
Otherwise, the nested query must
be processed for each result of the outer query to ensure
elimination of duplicates. In such cases, a join approach
would yield better results.
A subquery nested in the outer SELECT statement has
the following components:
A regular SELECT query including the regular select list components.
A regular FROM clause including one or more tables or view names.
An optional WHERE clause.
An optional GROUP BY clause.
An optional HAVING clause.
The SELECT query of a subquery is always enclosed in parentheses.
It cannot include a COMPUTE clause, and may
only include an ORDER BY clause when a TOP
clause is also specified.
A subquery can be nested inside the WHERE or HAVING clause of an outer
SELECT, INSERT, UPDATE, or DELETE statement, or inside another subquery.
Up to 32 levels of nesting is possible,

although the limit varies based on available memory


and the complexity of other expressions in the query.
A subquery can appear anywhere an expression can be used, if it returns a single
value.
If a table appears only in a subquery and not in the outer query, then columns from
that table cannot be included in the output (the select list of the outer query).
Statements that include a subquery usually take one of these formats:
WHERE expression [NOT] IN (subquery)
WHERE expression comparison_operator [ANY | ALL] (subquery)
WHERE [NOT] EXISTS (subquery)

In some Transact-SQL statements, the subquery can be evaluated as if it were an

independent query. Conceptually, the subquery results are substituted into the outer
query (although this is not necessarily how Microsoft SQL Server actually
processes Transact-SQL statements with subqueries).
There are three basic types of subqueries:
Subqueries that operate on lists introduced with IN,
or those that a comparison operator modified by ANY or ALL.
Subqueries tht are introduced with an unmodified
comparison operator and must return a single value.
A subquery that only selects one column or expression
and returns just one row is also called as a Scalar subquery.
Subquries that are used with EXISTS.
Scalar sunqueries:
scalar subqueries allow us to treat the output of a subquery as a column or even an
expression within a SELECT statement. It is a query that only selects one column
or expression and returns just one row. If the scalar subquery fails to return any
rows, Sql Server will use a NULL value for the output of the scalar subquery.

Write a query to determine number of videos supplied by


each Distributor and display the result along with
distrubutor number and name

Use VideoRentalSystem
go
select d.distributornum,d.DistributorName ,
(select COUNT(*) from video v
where v.distnum=d.distributornum) As [Num Videos]
from Distributor d;
----------------------------------------*
Show number,title,type and distribuotr number of all
those videos supplied by the distrbutor Disney Studios
Use VideoRentalSystem
go
select VideoNum,VTitle,VType,DistNum from Video where
Distnum = (select DistributorNum from Distributor
where DistributorName = 'Disney Studios' );
Correlated Subquery:
Write a query to determine how many number of times every video is ever issued
to any customer:
select v.VideoNum,v.VTitle,(select COUNT(*) from rental r
where r.VideoNumber=v.VideoNum) As [Num Issues] from Video V;
go
----------------------------*

---------------------------*
Write a query to show all the details of all those videos
that were supplied by the same distributor who supplied the
video 4777-1
select * from Video where DistNum =
(select DistNum from Video where
VideoNum='4777-1')
go
--------------------------------*
select * from Employee where job = (select job from employee where
empno=7698);
-----------------------------------*

Subqueries returning more than one row:


Show all the details of all the videos whose type is not the same
as the type of the video Gone with the breeze
Select v1.* from Video v1
where v1.VType Not In
(select v2.VType from video v2
where v2.VTitle ='Gone with the breeze')
go

List those videos whose price is less than the price of any video
belonging to the category 'Drama'
Select * from Video where Price < Any(

Select Price from Video where VType='Drama')


go
List those videos whose price is less than the price of all videos
belonging to the category 'Drama'
List those videos whose price is greater than the price of all
videos belonging to the category 'Drama'
Select * from Video where Price > ALL(
Select Price from Video where VType='Drama')
go
List those videos whose price is less than the least price of all Drama type videos
Select * from Video where Price < ALL(
Select Price from Video where VType='Drama')
go
-----------------------------*

Select e1.* from employee e1 where e1.deptno <> (select e2.deptno from
employee e2 where e2.ename='SMITH');
-----------------------*
Nested Subquery:
Write a query to list all the details of all those videos rented by customers living in
the city LA
Select Video.* from Video where VideoNum In
(Select Rental.VideoNumber from Rental where Rental.CustomerId In
(Select Customer.CustomerId from customer where Customer.City='LA'))
go
-------------------------------*
List all the employees who are working in Chicago.
select empno,ename,job,sal,deptno from empLOYEE where

deptno in (select deptno from departments

where loc = 'CHICAGO');


----------------------------------------*
select * from employee where sal > any(select Sal from employee where deptno =
30);
select * from employee where sal > all(select Sal from employee where deptno =
30);
select * from employee where sal < all(select Sal from employee where deptno =
30);
select * from Employee where Deptno in (select Deptno from departments where
loc in('NEW YORK','CHICAGO')) ;
-------------------------------------*
using aggregate functions in subqueries:
Find second highest salary:
Find second highest price :
select MAX(Price) as high2 from Video
where price < (Select MAX(price) from Video);

select MAX(sal) as high2 from employee


where Sal < (Select MAX(sal) as sal1 from employee);
Find 3rd highest Price:

select MIN(price) as high3 from video


where price in
(select distinct top 3 price from video order by price desc )
Find 4th highest Price:
select MIN(price) as high4 from video
where price in
(select distinct top 4 price from video order by price desc )
-------------------------------------*
Find 5th highest salary:
select MIN(sal) as high5 from employee
where Sal in (select distinct top 5 sal from employee order by Sal desc )

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Replacing a column name with a subquery:


write a query to display price and avg of price for all videos:
Use Videorentalsystem
go
Select VTitle,Price,

(select SUM(Price) from Video )/(select COUNT(*) from Video) AS


[Avg Price] from Video
go

Write a query to find by how much price of each video


differs from the highest price:
Use Videorentalsystem
go
select VTitle,
(select max(Price) from Video) as [maxprice] ,
price,
((select max(price) from Video ) - price )
as [difference] from Video
----------------------*
go
select ename,
(select max(sal) from employee) as [maxsal] ,
sal,
((select max(sal) from employee ) - sal )
as [difference] from employee;

Correlated subquery
A correlated subquery is evaluated once FOR EACH ROW as opposed to a normal
subquery which is evaluated only once for each table.
You can reference the outer query inside the correlated subquery using an alias
which makes it so handy to use.
Let's select all employees whose salary is less than the average of all the
employees' salaries in the same department.

Correlated Subquery:
Write a query to determine how many number of times every video is ever issued
to any customer:
select v.VideoNum,v.VTitle,(select COUNT(*) from rental r
where r.VideoNumber=v.VideoNum) As [Num Issues] from Video V;
----------------------------*
Write a query to determine how many rows in the DEPARTMENTS table contain
an employee corresponding to each row in the EMPLOYEE table.

select d.deptno,d.dname,(select COUNT(*) from employee e


where e.deptno=d.deptno) As [Num Dept] from departments d;
-----------------------------------*
Write a query to determine number of videos supplied by
each Distributor and display the result along with
distrubutor number and name

Use VideoRentalSystem
go
select d.distributornum,d.DistributorName ,
(select COUNT(*) from video v
where v.distnum=d.distributornum) As [Num Videos]
from Distributor d;
------------------------------------*
select x.ename ,x.sal ,x.deptno from employee x where
x.sal < (select avg(sal) from employee y
where x.deptno = y.deptno)

order by x.deptno;
---------------------------------------------*
Using a subquery in an update:
Raise the prices of all cheap videos
whose present prices are less than the
present avg price to the present average price itself.
Select * into TempVideo from Video
go
UPDATE TempVideo
set price = (select avg(price)
from Tempvideo)
where price <
(select avg(price) from TempVideo );
Select * from TempVideo
go
------------------------*
Let's give these people
(whose salary is less than their department's average) a raise.

select * into employee3 from employee;


select ename, sal, deptno from employee3
order by deptno, ename;
UPDATE employee3
set sal = (select avg(sal)
from employee3 b
where
deptno = b.deptno)

where sal <


(select avg(sal) from employee3 c
where deptno = c.deptno);
Using a subquery in a delete
Write a query to delete lowest priced video or videos among
Vtype - 'Comedy'
delete from Video3 where VType='Comedy' AND
price = (select min(price) from Video3 x
where x.VType='Comedy')
GO
---------------------*
Let's delete the highest earning employees in each department.
delete from employee2 where
sal = (select max(sal) from employee2 b
where deptno = b.deptno);
------------------------------*

Inserting into Tables, based on Values from other Tables


Scalar subqueries are also handy for inserting into tables,
based on values from other tables.

Crate a table and store the following summaries


of Price as a record:
sum,max,min and avg
create table summary (
sum_price numeric,

max_price numeric,
min_price numeric,
avg_price numeric

);
insert into summary (
sum_price,
max_price,
min_price,
avg_price)
values (
(select sum(price) from video),
(select max(price) from video),
(select min(price) from video),
(select avg(price) from video)
);
select * from summary;
_________________________________*
create table summary (
sum_sal numeric,
max_sal numeric,
min_sal numeric,
avg_sal numeric
);
insert into summary (
sum_sal,
max_sal,
min_sal,
avg_sal)
values (
(select sum(sal) from employee),
(select max(sal) from employee),
(select min(sal) from employee),
(select avg(sal) from employee)
);

select * from summary;


--------------------------------*

Using

Exists:

Write a query to list all those videos which have


been issued for at least once until now:

Select v.* from Video v


where
exists(
Select r.VideoNumber From Rental r
Where r.VideoNumber = v.VideoNum)
go
Select * from Video
go
Select * from Rental
go
Select v.* from Video v where not exists(
Select r.VideoNumber From Rental r
Where r.VideoNumber = V.VideoNum)
go
-------------*

select ename from employee e


where mgr in (select EMPNO from EMPLOYEE where ENAME='KING');
select ename from employee e

where exists (select ename from employee x where e.mgr = x.empno and
ename = 'KING');

WHEN YOU USE 'IN', WHILE CHECKING FOR WHERE CONDITION SQL
SERVER ENGINE DOES WHOLE TABLE SCAN.
IF YOU USE 'EXISTS' AS SOON AS ENGINE FINDS THE REQUIRED
ROW IT WILL STOP EXECUTING QUERY AND GOING FURTHER SCANNING
TABLE.
SO BASICALLY EXISTS IS FASTER AS COMPARED TO IN.

using the IN clause, you're telling the rule-based


optimizer that you want the inner query to drive the outer
query (think: IN = inside to outside).
When you write EXISTS in a where clause, you're telling the
optimizer that you want the outer query to be run first,
using each value to fetch a value from the inner query
(think: EXISTS = outside to inside).

Find the names of all those employees who are working In Mr.Smith's department.
In the output show department name also against each employee name.
SELECT e1.ename, d.dname
FROM employee e1 inner join departments d
on e1.deptno = d.deptno
AND EXISTS
(SELECT * FROM employee e2
WHERE e2.ename = 'Smith' AND e2.deptno = e1.deptno)
--------------------------------------------*
Nested sub query:

Display all the details of those videos whose price is more than the least price of all
videos supplied by 'Disney Studios'.
Select * from Video where Price > (
Select MIN(price) from Video
where DistNum = (
Select DistributorNum from Distributor
where DistributorName='Disney Studios'))
go
-----------------------*
Display the records of those employees who are earning more than the least salary
earned by any employee working at NEW YORK.
SELECT eName
FROM Employee
WHERE sal >(SELECT min(sal)
FROM Employee
WHERE deptno = (SELECT deptno
FROM departments
WHERE loc = 'NEW
YORK'));
Show the records of those employees who are earning less than any salesman along
with records of those employees who are working the same department in which
any salesman works;
SELECT *
FROM Employee
WHERE sal <(SELECT min(sal) FROM Employee
WHERE job = 'SALESMAN')
or
deptno = (SELECT distinct deptno
FROM Employee
WHERE job = 'SALESMAN');

VIEWS
View
A view is a virtual table that consists of columns from one or more tables.
These tables are referred to as base or underlying tables.
Once we define a view, we can reference it like any other table in a database.
A view serves as a security mechanism. It ensures that users are able to
retrieve and modify only the data seen by them.
A view also serves as a mechanism to simplify query execution.
Complex queries can be stored in the form of a view,
and data from the view can be extracted using simple queries.

Creating Views
A view can be created by using the CREATE VIEW statement.
Syntax
CREATE VIEW view_name
[(column_name[,column_name].)]
[WITH ENCRYPTION]
AS select_statement [WITH CHECK OPTION]
Where:
view_name specifies the name of the view and must follow the rules for identifiers.
column_name specifies the name of the column to be used in view. If the
column_name option is not specified, then the view is created with the same
columns as specified in the select_statement.

WITH ENCRYPTION encrypts the text for the view in the syscomments table.
AS specifies the actions that will be performed by the view.
select_statement specifies the SELECT Statement that defines a view. The view
may use the data contained in other views and tables.
WITH CHECK OPTION forces the data modification statements to fulfill the
criteria given in the SELECT statement defining the view. It also ensures that the
data is visible after the modifications are made permanent.
The restrictions imposed on views are as follows:
A view can be created only in the current database.
The name of a view must follow the rules for identifiers and must not be the
same as that of the base table.
A view can be created only if there is a SELECT permission on its base
table.
A SELECT INTO statement cannot be used in view declaration statement.
A for trigger or an index cannot be defined on a view.
The CREATE VIEW statement cannot be combined with other SQL
statements in a single batch.
Example
CREATE VIEW vwCustomer
AS
SELECT CustomerId, Company Name, Phone
FROM Customers
Creates a view called vwCustomer. Note that the view is a query stored as an
object. The data is derived from the columns of the base table Customers.
You use the view by querying the view like a table.
SELECT *FROM vwCUSTOMER
Updatable Views
You can modify the data of an underlying base table through a view,
as long as the following conditions are true:
Any modifications, including UPDATE, INSERT, and DELETE statements,
must reference columns from only one base table.

The columns being modified in the view must directly reference the
underlying data in the table columns. The columns cannot be derived in
any other way, such as through the following:
An aggregate function: AVG, COUNT, SUM, MIN, MAX,
GROUPING, STDEV, STDEVP, VAR, and VARP.
A computation. The column cannot be computed from an expression
that uses other columns. Columns that are formed by using the set
operators UNION, UNION ALL, CROSSJOIN, EXCEPT,
and INTERSECT amount to a computation and are also not updatable.
The columns being modified are not affected by GROUP BY,
HAVING, or DISTINCT clauses.
TOP is not used anywhere in the select_statement of the view together with
the WITH CHECK OPTION clause.

Syntax
sp_helptext
sp_helptext

Displaying

@objname
[

@objname

the

sp_helptext 'dbo.nameofsp'

definition

'name'

=
[

of

@columnname

trigger

'name'
=

or

computed_column_name

stored

procedure

STORED PROCEDURES
Creating a Stored Procedure that returns a value:
use videorentalsystem
go
CREATE PROC TestReturn (@InValue int)
AS
Return @Invalue
GO
DECLARE @ReturnValue INT
EXEC @ReturnValue = TestReturn 3
SELECT ReturnValue=@ReturnValue
GO

Creating a Stored Procedure with OUTPUT Parameters


use videorentalsystem
go
CREATE PROCEDURE GetCountByLastName (
@LName NVARCHAR(50),
@LastNameCount INT OUTPUT )
AS
SELECT @LastNameCount = COUNT(*)
FROM customer
WHERE LName = @LName
GO
DECLARE @TheCount INT
EXEC GetCountByLastName
@LName = 'Brown',

@LastNameCount = @TheCount OUTPUT

SELECT TheCount = @TheCount


GO

Creating a Stored Procedure with OUTPUT Parameters

use videorentalsystem
go
CREATE PROCEDURE op_test
@ip1 int,
@op1 int OUTPUT,
@op2 int OUTPUT
AS
set @op1 = 10 + @ip1
set @op2 = 20 + @ip1
go
--Call it like this:
declare @p int = 10
declare @x int
declare @y int
exec op_test @p ,@x OUTPUT, @y OUTPUT
select @X
select @y
Creating a Stored Procedure with OUTPUT Parameters
use videorentalsystem
go
CREATE PROCEDURE GetNumOfVideosByVType (
@VType NVARCHAR(50),

@VideoCount INT OUTPUT )

AS
SELECT @VideoCount = COUNT(*)
FROM Video
WHERE VType = @VType
Return
Go
--call
DECLARE @TheCount INT
EXEC GetNumOfVideosByVType
@VType = 'Comedy', @VideoCount = @TheCount OUTPUT
SELECT TheCount = @TheCount
GO
------------------*

Stored procedure with default parameters


use VideoRentalSystem
go
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'MyProcedure1' AND type = 'P')
DROP PROCEDURE MyProcedure1
GO
Create procedure MyProcedure1(
@para1 int = 10,
@para2 int)
As
Print @para1 + @para2
Return
Go
Exec MyProcedure1 @para2 = 30
go
------------------------*
use VideoRentalSystem

go
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'MyProcedure2' AND type = 'P')
DROP PROCEDURE MyProcedure2
GO
Create procedure MyProcedure2(
@para1 int ,
@para2 int=100)
As
Print @para1 + @para2
Return
Go
Exec MyProcedure2 150
go
Exec MyProcedure2 @para1 = 200
go
-------------------------------*
use VideoRentalSystem
go
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'MyProcedure3' AND type = 'P')
DROP PROCEDURE MyProcedure3
GO
Create procedure MyProcedure3(
@para1 int=50 ,
@para2 int=100)
As
Print @para1 + @para2
Return
Go
Exec MyProcedure3 10,20
go
Exec MyProcedure3 @para1 = 200
go
Exec MyProcedure3 @para2 = 5

go
Exec MyProcedure3 @para1 = 45, @para2 = 60
go
-------------------------*

Stored procedure with wildcard parameters


use videorentalsystem
go
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'VideoInfo' AND type = 'P')
DROP PROCEDURE VideoInfo
GO
CREATE PROCEDURE VideoInfo
@VTitle varchar(30) = 'A%'
AS
SELECT VideoNum,VTitle,Price
FROM Video
WHERE VTitle LIKE @VTitle
GO
--The VideoInfo stored procedure can be
--executed in many combinations.

EXECUTE VideoInfo
-- Or
EXECUTE VideoInfo 'G%'
-- Or
EXECUTE VideoInfo @VTitle = 'T%'
-- Or
EXECUTE VideoInfo 'Alien Surfer'

-------------------------------*

Use deferred name resolution


This example shows a procedure that uses deferred name resolution. The stored procedure is
created although the table that is referenced does not exist at compile time. The table must exist,
however, at the time the procedure is executed.
use VideoRentalSystem

go
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'MyProcedure4' AND type = 'P')
DROP PROCEDURE MyProcedure4
GO
Create procedure MyProcedure4
AS
Select * from UnKnownTable
Go

Use a simple procedure with a complex SELECT


use northwind;
go
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'emp_info_all' AND type = 'P')
DROP PROCEDURE emp_info_all
GO
CREATE PROCEDURE emp_info_all
AS
SELECT e.empno,e.ename,e.mgr,m.ename AS
Manager,e.sal,SALGRADE.GRADE,
e.deptno,d.dname,d.loc FROM EMPLOYEE e INNER JOIN DEPARTMENTS d

ON
e.DEPTNO = d.DEPTNO INNER JOIN SALGRADE ON e.SAL BETWEEN
SALGRADE.LOSAL AND
SALGRADE.HISAL LEFT OUTER JOIN EMPLOYEE m ON e.MGR =
m.EMPNO ORDER BY e.deptno
GO

Use the WITH RECOMPILE option


The WITH RECOMPILE clause is helpful when the parameters supplied to the procedure will
not be typical, and when a new execution plan should not be cached or stored in memory.
(a) The sp_recompile system stored procedure forces a recompile
of a stored procedure the next time it is executed. For example:
exec sp_recompile MyTable

(b) Create a stored procedure specifying WITH RECOMPILE option.


If WITH RECOMPILE is specified SQL Server does not cache a plan
for this stored procedure; the stored procedure is recompiled
each time it is executed. Use the WITH RECOMPILE option when
stored procedures take parameters whose values differ widely
between executions of the stored procedure, resulting in
different execution plans to be created each time.
Here is how you can create a store procedure using RECOMPILE
option:
CREATE PROCEDURE usp_MyProcedure WITH RECOMPILE
AS
Select SampleName, SampleDesc From SampleTable
GO
(c) You can force the stored procedure to be recompiled by specifying the WITH RECOMPILE
option when you execute the stored procedure. Use this option only if the parameter you are
supplying is atypical or if the data has significantly changed since the stored procedure was
created. For example:
EXEC usp_MyProcedure WITH RECOMPILE

Use the WITH ENCRYPTION option

The WITH ENCRYPTION clause obfuscates the text of a stored procedure. This example
creates an obfuscated procedure, uses the sp_helptext system stored procedure to get
information on that obfuscated procedure, and then attempts to get information on that procedure
directly from the syscomments table.

use VideoRentalSystem
go
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'MyProcedure5' AND type = 'P')
DROP PROCEDURE MyProcedure5
GO
Create procedure MyProcedure5
AS
Select * from Video
Go
exec sp_helptext MyProcedure5
go
-------------------------*
use VideoRentalSystem
go
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'MyProcedure5' AND type = 'P')
DROP PROCEDURE MyProcedure5
GO
Create procedure MyProcedure5 WITH ENCRYPTION
AS
Select * from Video

Go
exec sp_helptext MyProcedure5
go
---------------------*

BEGIN
Declare @a int = 10
Print @a
End

Triggers
Introduction to Triggers
A trigger is an action that is performed behind-the-scenes when an event occurs.
Unlike a stored procedure, we never have to execute a trigger. The operating system (through
the object(s) event(s)) and the database engine take care of this. A trigger acts behind the scenes
when the object to which it is associated fires the appropriate event. In fact, the event fires
whether the object received a change or not (whether a record was created, edited, or deleted, or
not).
There are

three types of triggers: DML, DDL, and logon.

DML Triggers
A DML trigger is a procedure that acts as a result of a data manipulation language (DML) event
occurring on a table. This means that the trigger must be created in connection to a table of a
non-system database.
AFTER/FOR INSERT Triggers :
An insert trigger is a DML trigger that acts when a new record is added to its intended table.
Such a trigger uses the INSERT keywork. The primary formula to create an INSERT DML
trigger on a table is:
CREATE TRIGGER TriggerName
ON TableName
AFTER/FOR INSERT/UPDATE/DELETE
AS
TriggerCode

In our formula, we assume that the trigger will apply when a record has been added to the table.
Therefore, you use either the AFTER INSERT or the FOR INSERT expression.
To start the SQL code that constitutes the trigger, write AS, and then write your code.
After creating an INSERT trigger, at the right time (when its intended event fires), it will be
executed. When this happens, the database engine automatically and internally creates a
temporary table named inserted. This table holds a copy of the records that were created. You
can access those records if necessary.

use northwind;
go
Create table MyBooks(Bookid int primary key,
BookTitle nvarchar(100),
BookAuthor nvarchar(100),
BookPrice decimal);
go
CREATE TABLE DatabaseOperations (
DBOperationID int identity(1,1) NOT NULL,
ObjectType nchar(20),
ObjectName nvarchar(40),
PerformedBy nvarchar(50),
ActionPerformed nvarchar(50),
TimePerformed datetime,
CONSTRAINT PK_DBOperations PRIMARY KEY(DBOperationID)
);
GO
CREATE TRIGGER RecordInsertion
ON MyBooks
AFTER INSERT
AS
BEGIN
INSERT INTO DatabaseOperations
VALUES(N'Table', N'MyBooks', SUSER_SNAME(),
N'Created a new record', GETDATE())
END
GO
select * from databaseoperations;
go
insert into MyBooks values(1,'Programming through C',
'Venugopal',450);
go

(1 row(s) affected)
(1 row(s) affected)

select * from mybooks;


go
select * from databaseoperations;
go
AFTER/FOR UPDATE Triggers :
Instead of record insertion time, a DML trigger can act when a record has been
updated on a table. To support this operation, you can use the following formula:
CREATE TRIGGER TriggerName
ON TableName
AFTER/FOR UPDATE
AS
TriggerCode

The new keyword in this formula is UPDATE. This indicates that the DML trigger will act when
the record has been updated. Everything else is as described for the INSERT operator.
Remember to use either AFTER UPDATE or FOR UPDATE.

CREATE TRIGGER RecordUpdate


ON MyBooks
AFTER UPDATE
AS
BEGIN
INSERT INTO DatabaseOperations
VALUES(N'Table', N'MyBooks', SUSER_SNAME(),
N'Changed an existing book record', GETDATE())
END
GO
update MyBooks set Booktitle='Learn C', Bookauthor='Vimala' where
BookId = 1;
go
(1 row(s) affected)
(1 row(s) affected)

select * from mybooks;

go
select * from databaseoperations;
go
AFTER/FOR DELETE Triggers
When a record has been removed from a table, you can apply a DML trigger in
response. To make it possible, you can use the following formula:
CREATE TRIGGER TriggerName
ON TableName
AFTER/FOR DELETE
AS
TriggerCode

This time, the formula uses the DELETE operator as in AFTER DELETE or FOR DELETE.
The other factors follow the same description we saw for the INSERT operator.
When a DELETE trigger has acted on a table, the database engine creates a special temporary
table named deleted. This table holds a copy of the records that were deleted. Eventually, if
necessary, you can access this table to find out about those records.

CREATE TRIGGER RecordDeletion


ON MyBooks
AFTER DELETE
AS
BEGIN
INSERT INTO DatabaseOperations
VALUES(N'Table', N'MyBooks', SUSER_SNAME(),
N'Deleted a book', GETDATE())
END
GO
delete from mybooks where bookid=1
go

Trigger Management
A trigger is a database object. As such, it has a name. It can be modified. It can also
be deleted.
Modifying a Trigger
If the behavior of a trigger is not appropriate, you can change it. The formula to

modify a trigger is:


ALTER TRIGGER schema_name.trigger_name
ON schema_name.table_name
AFTER , UPDATE>
AS
statement

Deleting a Trigger
If you do not need a trigger anymore, you can remove it from a table. The formula
to do this is:
DROP TRIGGER TriggerName

After the DROP TRIGGER expression, enter the name (of the trigger).

Characteristics of DML Triggers


Although we created only one trigger for a table so far, you can go farther than
that:
You can create many DML triggers (using different names, of course) that perform the
same action on a table. This means that you can create many INSERT triggers (or many
UPDATE triggers or many DELETE triggers) that act on the same table and that target
the same action
You can create different triggers that act on a table

DML Triggers and Constraints


If you create a DML trigger that must act against that table, if the nullity rule is
violated, the trigger will not run.
If a DML trigger is supposed to act on the table, if this rule is not respected, the
trigger would fail.
A DML trigger can be created to perform a check constraint on more than one
table. This provides its advantage over the normal check constraint.
When a DML trigger runs, if a referential rule is violated, the trigger, which also
checks the referential integrity, fails.
Instead of DML Triggers
From what we have seen so far, when a user opens a table or a view to perform
data entry, when a new record has been created, the table or view fires an event.

We saw that, using a DML trigger, you can make a notification. For example you
can fill out a log to keep track of the changes. By default, when a record is
submitted, it gets saved. In some cases, when a user has opened a table and tried to
make a change, such as adding a new record, editing an existing record, or deleting
a record, instead of accepting the change, you can dismiss it. You can then use a
DML trigger to make a note. This is the basis of another category of DML triggers:
an "instead of" trigger.
While an AFTER/FOR trigger acts on a table after the action has occurred, you may want to do
something before the event fires. For example, you may want to prevent the user from adding a
new record on a tale, or from changing an existing record, or from deleting a record. Of course, it
is better to take care of this before the action is performed. One way you can do this is by
creating an "instead of" trigger.

CREATE DATABASE SmallBusiness;


GO
USE SmallBusiness;
GO
CREATE TABLE Customers
(
CustomerID int identity(1, 1) primary key not null,
AccountNumber nchar(10),
FullName nvarchar(50)
);
GO
CREATE TABLE DatabaseOperations (
EmployeeName nvarchar(50),
ActionPerformed nvarchar(50),
TimePerformed time
);
GO
Creating an INSTEAD OF Trigger
While an AFTER trigger can be applied to a table only, an "instead of" trigger can
be associated with either a table or a view. Therefore, to create an "instead of"
trigger, you use the following formula:
CREATE TRIGGER TriggerName
ON TableOrViewName
INSTEAD OF INSERT/UPDATE/DELETE

AS

TriggerCode

You start with the CREATE TRIGGER expression followed by a name for the trigger. After the
name of the trigger, type ON followed by the name of either a table or a view on which the
trigger will act.
From our review of the AFTER trigger, the new expression here is INSTEAD OF. This
expression is followed by the type of operation to perform:
If you want to catch the creation of a new record, use the INSERT operator
If you want to catch the editing operation of an existing record, use the UPDATE
operator
If you want to catch the removal of a record, use the DELETE operator
To start the triggering code, type AS and write the desired code.
If you use the INSTEAD OF expression, the trigger starts when the table or view is opened but
before a change has taken place. The difference with the AFTER trigger is that, this time, you
can perform some action(s) before the change is made on the table or view. This also implies
that, if the code of the trigger is to create a new record, at this time, the record doest not yet exist,
which means you cannot catch that record. At this time also, you can prevent the record from
being created (since it has not yet been created anyway). For example, the following code will
not accept that a new record be added to the table:

USE SmallBusiness;
GO
CREATE TRIGGER CreateCustomer
ON Customers
INSTEAD OF INSERT
AS
BEGIN
INSERT INTO DatabaseOperations
VALUES(SUSER_SNAME(),
N'Attempt to create new record', GETDATE())
END
GO
If you want to get a copy of the record that was affected by the event, you can
access it from the inserted (for an INSERT or UPDATE trigger) or from the
deleted (for a DELETE) trigger. Here is an example:
USE SmallBusiness;
GO

DROP TRIGGER CreateCustomer;


GO
CREATE TRIGGER CreateCustomer
ON Customers
INSTEAD OF INSERT
AS
BEGIN
INSERT INTO Customers
SELECT AccountNumber, FullName FROM inserted
END
GO
CREATE TRIGGER AttemptedRecordUpdate
ON Customers
INSTEAD OF UPDATE
AS
BEGIN
INSERT INTO DatabaseOperations
VALUES(SUSER_SNAME(),
N'Attempted to change customer information',
GETDATE())
END
GO
Characteristics of INSTEAD OF Triggers
An AFTER/FOR and an INSTEAD OF triggers have many differences. For
example:
If a table has a relationship to another table and the referential integrity
on that relationship is marked with either ON DELETE or ON UPDATE,
an INSTEAD OF UPDATE or an INSTEAD OF DELETE trigger cannot
act on that table
You can create only one type of INSTEAD OF trigger for each table.
For example, a table cannot have more than one INSTEAD OF INSERT
trigger

DDL Triggers

A DDL trigger is a trigger that acts when a certain type of


DDL event fires. These include the creation, modification,
or removal of an object like table but not its records. This is the primary
difference with a DML trigger which fires when a record is
added or modified.
A DDL trigger gives you the opportunity to do some administrative work in
response to the event. For example, you can get a notification,
or notify someone else using an automatically generated email,
that an object (and what object) has been created.
Or you can use a DDL trigger to discard the operation.

Creating a DDL Trigger


You create a DDL trigger using code. The basic formula is:
CREATE TRIGGER TriggerName
ON DATABASE/ALL SERVER
FOR/AFTER WhatEvent
AS
TriggerCode

You start a DDL trigger with the CREATE TRIGGER expression followed by a name for the
new trigger. The name follows the same rules we have applied to objects so far. After the name
of the trigger, type the ON keyword:
If you want the trigger to act on the current database, type DATABASE. When the
intended event occurs on the current database, the trigger will execute
If you want the trigger to act on the server, follow the ON operator with ALL SERVER.
In this case, when the intended event occurs on any part of the server, the trigger executes
After specifying the object (the whole server or only the current database) on which the trigger
will act, type either FOR or AFTER. This is followed by the event against which the trigger will
act. As mentioned already, the events are DDL commands. To specify the event, use the formula
of the command with the words separated by an underscore. For example, if you want the trigger
to act when a CREATE TABLE command is executed, specify the event as CREATE_TABLE.
After specifying the event that will fire, type AS followed by the normal code of the trigger.
Here is an example that makes a note and adds it to a table when a new table has been created:

USE SmallBusiness;
GO
CREATE TRIGGER LogNewTableCreation
ON DATABASE
FOR CREATE_TABLE

AS
BEGIN
INSERT INTO DatabaseOperations
VALUES(SUSER_SNAME(),
N'A new table was created', GETDATE())
END
GO
Whenever a new table is created in the current database, the trigger runs, gets the
name of the user who created the table, the date and time the table was created, and
a small message. These pieces of information are then stored in a log table.
As mentioned for DML triggers, you manage DDL triggers by modifying or deleting them.
These are done using the same description we saw for DML triggers.

DDL Trigger:
Returns information about server or database events. EVENTDATA is called when
an event notification fires, and the results are returned to the specified service
broker. EVENTDATA can also be used inside the body of a DDL or logon trigger.
USE Exercise;
GO
CREATE TRIGGER safety
ON DATABASE
FOR CREATE_TABLE
AS
PRINT 'CREATE TABLE Issued.'
SELECT EVENTDATA().value
('(/EVENT_INSTANCE/TSQLCommand/CommandText)
[1]','nvarchar(max)')
RAISERROR ('New tables cannot be created in this database.', 16, 1)
ROLLBACK
;
GO
--Test the trigger.
CREATE TABLE NewTable (Column1 int);
GO
--Drop the trigger.

DROP TRIGGER safety


ON DATABASE;
GO

Using a logon trigger


The following logon trigger example denies an attempt to log in to SQL Server as a
member of the login_test login if there are already three user sessions running
under that login.
USE master;
GO
CREATE LOGIN login_test WITH PASSWORD = '3KHJ6dhx(0xVYsdf' MUST_CHANGE,
CHECK_EXPIRATION = ON;
GO
GRANT VIEW SERVER STATE TO login_test;
GO
CREATE TRIGGER connection_limit_trigger
ON ALL SERVER WITH EXECUTE AS 'login_test'
FOR LOGON
AS
BEGIN
IF ORIGINAL_LOGIN()= 'login_test' AND
(SELECT COUNT(*) FROM sys.dm_exec_sessions
WHERE is_user_process = 1 AND
original_login_name = 'login_test') > 3
ROLLBACK;
END;

More examples of Triggers


Use TriExamples
go
CREATE TABLE Person
(
SSN
char(11) PRIMARY KEY,
Name
nvarchar(100),
Address nvarchar(100),
Birthdate datetime
)
go

Create Table InsAudit(


RowId int Identity(1,1),
SSN char(11),
DateOfIns datetime,
InsByWhom nvarchar(30))
go

Triggers use two logical tables called the INSERTED and the DELETED table.
These tables are accessed only inside triggers and we cannot directly modify the
data in these tables. These tables hold the new and old rows of the data being
inserted or deleted.
If we DELETE a row , a row will be created in the DELETED table.
Similarly if we INSERT a row, a row is created in the INSERTED table.
If we update a record with an UPDATE statement, the INSERTED table will
contain the updated row and a previous state of the row will be added to the
DELETED table.
Note: we cannot use a CREATE INDEX command on these tables.
CREATE TRIGGER TrigIns
ON Person
AFTER INSERT
AS
insert into InsAudit(SSN,DateOfIns,InsByWhom)
values((Select SSN From INSERTED),GetDate(),SYSTEM_USER)
Go
insert into Person(SSN,Name,Address,BirthDate)
values('111-11','John','5th Avenue LA','1980-05-25')
go
Select * From Person
go

Select * from InsAudit


go
*************************************
CREATE TABLE ModifyAudit(
RowId int IDENTITY(1,1) NOT NULL,
OldSSN char(11) NULL,
OldName nvarchar(100) NULL,
OldAddress nvarchar(100) NULL,
OldBirthDate datetime NULL
)
go
CREATE TRIGGER TrigUpdate
ON Person After Update
AS
insert into ModifyAudit
(OldSSN,OldName,OldAddress,OldBirthDate)
values(
(Select SSN From DELETED),
(Select Name From DELETED),
(Select [Address] From DELETED),
(Select BirthDate From DELETED))
Go
--------------------Use VideoRentalSystem
go
CREATE TRIGGER TrigDelete
ON Person After Delete
AS
Raiserror ('cannot delete record',10,1)
RoLLBACK

Go
Delete From Person
go
Select * from Person
go

--------------------------Disabling a DML trigger on a table


The following example disables trigger uAddress that was created on table
Address.
USE AdventureWorks;
GO
DISABLE TRIGGER dbo.TrigDelete ON dbo.Person
go

----------------------------------Disabling a DDL trigger


The following example creates a DDL trigger safety with database scope, and then
disables it.
IF EXISTS (SELECT * FROM sys.triggers
WHERE parent_class = 0 AND name = 'safety')
DROP TRIGGER safety ON DATABASE;
GO
CREATE TRIGGER safety
ON DATABASE
FOR DROP_TABLE, ALTER_TABLE
AS
PRINT 'You must disable Trigger "safety" to drop or alter tables!'
ROLLBACK;
GO

DISABLE TRIGGER safety ON DATABASE;


-------------------------------------Disabling all triggers that were defined with the same scope
The following example disables all DDL and logon triggers that were created at the
server scope.
USE AdventureWorks;
GO
DISABLE Trigger ALL ON ALL SERVER;
GO
----------------------------A. Enabling a DML trigger on a table
The following example disables trigger uAddress that was created on table
Address, and then enables it.
USE AdventureWorks;
GO
DISABLE TRIGGER Person.uAddress ON Person.Address;
GO
ENABLE Trigger Person.uAddress ON Person.Address;
GO
B. Enabling a DDL trigger
The following example creates a DDL trigger safety with database scope, and then
disables it.
IF EXISTS (SELECT * FROM sys.triggers
WHERE parent_class = 0 AND name = 'safety')
DROP TRIGGER safety ON DATABASE;
GO
CREATE TRIGGER safety
ON DATABASE

FOR DROP_TABLE, ALTER_TABLE


AS
PRINT 'You must disable Trigger "safety" to drop or alter tables!'
ROLLBACK;
GO
DISABLE TRIGGER safety ON DATABASE;
GO
ENABLE TRIGGER safety ON DATABASE;
GO
C. Enabling all triggers that were defined with the same scope
The following example enables all DDL and logon triggers that were created at the
server scope.
USE AdventureWorks;
GO
ENABLE Trigger ALL ON ALL SERVER;
GO
----------------------------------ALTERING A TRIGGER
USE AdventureWorks;
GO
IF OBJECT_ID(N'Sales.bonus_reminder', N'TR') IS NOT NULL
DROP TRIGGER Sales.bonus_reminder;
GO
CREATE TRIGGER Sales.bonus_reminder
ON Sales.SalesPersonQuotaHistory
WITH ENCRYPTION
AFTER INSERT, UPDATE
AS RAISERROR ('Notify Compensation', 16, 10);
GO
-- Now, change the trigger.
USE AdventureWorks;
GO
ALTER TRIGGER Sales.bonus_reminder

ON Sales.SalesPersonQuotaHistory
AFTER INSERT
AS RAISERROR ('Notify Compensation', 16, 10);
GO

-----------------------------------------INSTEAD OF TRIGGERS (Revisited)


The primary advantage of INSTEAD OF triggers is that they enable views to
support updates which are not updatable by default. A view based on multiple base
tables must use an INSTEAD OF trigger to support inserts, updates, and deletes
that reference data in more than one table. Another advantage of INSTEAD OF
triggers is that they enable you to code logic that can reject parts of a batch while
letting other parts of a batch to succeed.
An INSTEAD OF trigger can take actions such as:
Ignoring parts of a batch.
Not processing a part of a batch and logging the problem rows.
Taking an alternative action when an error condition is encountered.
In the following sequence of Transact-SQL statements, an INSTEAD OF trigger
updates two base tables from a view. Additionally, the following approaches to
handling errors are shown:
Duplicate inserts to the Person table are ignored, and the information from the
insert is logged in the PersonDuplicates table.
Inserts of duplicates to the EmployeeTable are turned into an UPDATE
statement that retrieves the current information into the EmployeeTable without
generating a duplicate key violation.

The Transact-SQL statements create two base tables, a view, a table to record
errors, and the INSTEAD OF trigger on the view. The following tables separate
personal and business data and are the base tables for the view.
CREATE TABLE Person
(
SSN
char(11) PRIMARY KEY,
Name
nvarchar(100),
Address nvarchar(100),
Birthdate datetime
)
CREATE TABLE EmployeeTable
(
EmployeeID
int PRIMARY KEY,
SSN
char(11) UNIQUE,
Department
nvarchar(10),
Salary
money,
CONSTRAINT FKEmpPer FOREIGN KEY (SSN)
REFERENCES Person (SSN)
)
The following view reports all relevant data from the two tables for a person.
CREATE VIEW Employee AS
SELECT P.SSN as SSN, Name, Address,
Birthdate, EmployeeID, Department, Salary
FROM Person P, EmployeeTable E
WHERE P.SSN = E.SSN
We can record attempts to insert rows with duplicate social security numbers. The
PersonDuplicates table logs the inserted values, the name of the user who tried the
insert, and the time of the insert.
CREATE TABLE PersonDuplicates
(
SSN
char(11),
Name
nvarchar(100),
Address
nvarchar(100),
Birthdate datetime,

InsertSNAME nchar(100),
WhenInserted datetime
)
The INSTEAD OF trigger inserts rows into multiple base tables from a single
view. Attempts to insert rows with duplicate SSN are recorded in the
PersonDuplicates table. Duplicate rows in the EmployeeTable are changed to
update statements.
------------------------------------------------------------------------------------------CREATE TRIGGER IO_Trig_INS_Employee ON Employee
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON
-- Check for duplicate Person. If there is no duplicate, do an insert.
IF (NOT EXISTS (SELECT P.SSN
FROM Person P, inserted I
WHERE P.SSN = I.SSN))
INSERT INTO Person
SELECT SSN,Name,Address,Birthdate
FROM inserted
ELSE
-- Log an attempt to insert duplicate Person row in PersonDuplicates table.
INSERT INTO PersonDuplicates
SELECT SSN,Name,Address,Birthdate,SUSER_SNAME(),GETDATE()
FROM inserted
-- Check for duplicate Employee. If there is no duplicate, do an INSERT.
IF (NOT EXISTS (SELECT E.SSN
FROM EmployeeTable E, inserted
WHERE E.SSN = inserted.SSN))
INSERT INTO EmployeeTable
SELECT EmployeeID,SSN, Department, Salary
FROM inserted
ELSE
--If there is a duplicate, change to UPDATE so that there will not
--be a duplicate key violation error.

UPDATE EmployeeTable
SET EmployeeID = I.EmployeeID,
Department = I.Department,
Salary = I.Salary
FROM EmployeeTable E, inserted I
WHERE E.SSN = I.SSN
END
----------------------------------------------------

USER DEFINED FUNCTIONS


With SQL Server 2000, Microsoft has introduced the concept of
User-Defined Functions that allow us to define our own T-SQL
functions that can accept zero or more parameters and return a single
scalar data value or a table data type.

What Kind of User-Defined Functions can I Create?


There are three types of User-Defined functions in SQL Server and they are
Scalar,
Inline Table-Valued and
Multi-statement Table-valued.

How to create and use a Scalar User-Defined Function?


A Scalar user-defined function returns one of the scalar data types. Text, ntext,
image and timestamp data types are not supported. These are the type of userdefined functions that most developers are used to in other programming
languages. We can pass 0 to many parameters and we get a return value.
Below is an example:
Use IndianEnterprise
go
Create Table Customers(CustId int primary key,
CustName nvarchar(30),
Country nvarchar(30))
go
Insert into Customers values(1000,'Smith','Argentina')
go
Insert into Customers values(1001,'Blake','Argentina')
go
Insert into Customers values(1002,'Lara','Canada')
go
Insert into Customers values(1003,'Ronald','Belgium')
go
Insert into Customers values(1004,'Martin','Finland')
go
Insert into Customers values(1005,'King','France')
go
Insert into Customers values(1006,'Obama','USA')
go
Insert into Customers values(1007,'Pele','Brazil')
go

CREATE FUNCTION whichContinent


(@Country nvarchar(15))
RETURNS varchar(30)
AS
BEGIN
declare @Return varchar(30)
select @return = case @Country
when 'Argentina' then 'South America'
when 'Belgium' then 'Europe'
when 'Brazil' then 'South America'
when 'Canada' then 'North America'
when 'Denmark' then 'Europe'
when 'Finland' then 'Europe'
when 'France' then 'Europe'
else 'Unknown'
end
return @return
end

Because this function returns a scalar value of a varchar(30) this function could be
used anywhere a varchar(30) expression is allowed such as a computed column in
a table, view, a T-SQL select list item.
print dbo.whichContinent('Denmark')
create table test
(Country varchar(15),
Continent as (dbo.WhichContinent(Country)))
insert into test (country)
values ('USA')
select * from test
insert into test (country)

values ('Argentina')
select * from test

How to create and use an


Inline Table-Valued User-Defined Function?
An Inline Table-Valued user-defined function returns a table data type
and is an exceptional alternative to a view as the user-defined function
can pass parameters into a T-SQL select command and in
essence provide us with a parameterized, non-updateable view
of the underlying tables.

Use IndianEnterprise
go
CREATE FUNCTION CustomersByContinent
(@Continent varchar(30))
RETURNS TABLE
AS
RETURN
SELECT dbo.WhichContinent(Customers.Country) as continent,
customers.*
FROM customers
WHERE dbo.WhichContinent(Customers.Country) = @Continent
GO

SELECT * from CustomersbyContinent('North America')


SELECT * from CustomersByContinent('South America')
SELECT * from customersbyContinent('Unknown')

How to create and use a Multi-statement


Table-Valued User-Defined Function?
A Multi-Statement Table-Valued user-defined function returns a table
and is also an exceptional alternative to a view as the function can
support multiple T-SQL statements to build the final result where the view
is limited to a single SELECT statement. Within the create function
command we must define the table structure that is being returned.
After creating this type of user-defined function, we can call it in the
FROM clause of a Select command.

Use IndianEnterprise
go
CREATE FUNCTION dbo.CustomersbyCountry ( @Country varchar(15) )
RETURNS
@CustomersbyCountryTab table (
CustID int ,
CustName nvarchar (30),
Country nvarchar(30)
)
AS
BEGIN
INSERT INTO @CustomersByCountryTab
SELECT CustID,
CustName,
Country
FROM [Customers]
WHERE country = @Country
IF((SELECT COUNT(*) FROM @customersbyCountryTab)=0)
Begin
INSERT INTO @CustomersByCountryTab (
CustId,
CustName,
Country

)
VALUES (null,'No Customer Found','Unknown')
End
RETURN
END
GO

SELECT * FROM dbo.customersbycountry('USA')


SELECT * FROM dbo.customersbycountry('CANADA')
SELECT * FROM dbo.customersbycountry('ADF')
Sr.No
User Defined Function
.

Stored Procedure

Stored Procedure may or not return values.

Function must return a value.


Will allow only Select statements, it

will not allow us to use DML


statements.

3
4
5
6
7

It will allow only input parameters,


doesn't support output parameters.
It will not allow us to use try-catch
blocks.
Transactions are not allowed within
functions.
We can use only table variables, it will
not allow using temporary tables.
Stored Procedures can't be called
from a function.
Functions can be called from a select
statement.
A UDF can be used in join clause as a
result set.

Can have select statements as well as DML statements such as insert,


update, delete and so on
It can have both input and output parameters.
For exception handling we can use try catch blocks.
Can use transactions within Stored Procedures.
Can use both table variables as well as temporary table in it.
Stored Procedures can call functions.
Procedures can't be called from Select/Where/Having and so on
statements. Execute/Exec statement can be used to call/execute Stored
Procedure.
Procedures can't be used in Join clause

Using Synonyms in SQL Server 2005


If you've been developing with SQL Server for any length of time, you're undoubtedly used to
referring to objects with four-part identifiers:
[[[server.][database].][schema_name].]object_name
As the square brackets show, different parts of this syntax can be omitted, as long as you supply
enough to unambiguously identify what you're talking about. For example, all of these might
refer to the same object:
Server1.AdventureWorks.Production.ProductCategory
AdventureWorks.Production.ProductCategory
AdventureWorks..ProductCategory
ProductCategory
For the most part, you can get by with three-part names, omitting the server name - unless you're
dealing with objects on a linked server. By default, the context of all objects is the local database
where your SQL statements are executing. But sometimes, to be precise, you have no choice but
to use the four-part name (otherwise known as a fully-qualified name. Or do you? In SQL Server
2005, the story changes a bit.

Enter the Synonym


SQL Server 2005 introduces the concept of a synonym: a single-part name
that can replace a two-, three-, or four-part name in many SQL statements.
Using synonyms lets you cut down on typing (always a welcome
advance for developers!) and can also provide an abstraction layer
to protect you against changes in underlying objects.
To understand how this works, let's start with the syntax
for creating synonyms. Not surprisingly, this is the CREATE SYNONYM statement:
CREATE SYNONYM [schema_name.]synonym_name FOR object_name
Here object_name is the name of a SQL Server object (specified fully enough to identify the
object) and synonym_name is the new name that you want to assign to it. If you don't specify a
schema for the synonym, then SQL Server uses the current user's default schema. The object
doesn't need to exist when you create the synonym, because synonyms are late bound: SQL
Server only checks the base object when you actually use the synonym.
For example, in the AdventureWorks sample database you can create a synonym this way:
CREATE SYNONYM ProdCat

FOR AdventureWorks.Production.ProductCategory
Having done this, you can now proceed to use the synonym in SQL statements. For example:
SELECT * FROM ProdCat

When you're done with a synonym,


you can get rid of it using the DROP SYNONYM statement,
which has the syntax you expect:
DROP SYNONYM [schema_name.]synonym_name

A Few of the Details


Naturally, there are some limits to synonym use. For starters, you can't create a synonym for just
anything. SQL Server 2005 contains more objects than ever before,
but synonyms are limited to a core set of the most useful objects:
Tables
Views
Stored procedures
CLR stored procedures
CLR functions
Replication filter procedures
Extended stored procedures
SQL scalar, table-valued, and inline table-valued functions
There are also limits on where we can use synonyms.
Generally speaking, we can use a synonym in these T-SQL statements:
SELECT
sub-selects
UPDATE
INSERT
DELETE
EXECUTE

If you think about it, that second list shouldn't be too surprising: it encompasses the most
common statements where you'd use the objects from the first list. Note that you cannot
reference a synonym in a DDL statement. If you want to use ALTER TABLE to change
something about the ProductCategory table, for example, you need to work with the base
table, not with the ProdCat synonym.
To create a synonym, you need CREATE SYNONYM permission.
After a synonym has been created, it has its own associated GRANT, DENY,
and REVOKE permissions.

Synonyms as an Abstraction Layer


Besides saving you typing, synonyms can also serve as an abstraction layer over unstable or
frequently updated portions of your database. That's because the bindings between a synonym
and its base object are only checked at runtime, not at design time.
To illustrate this, examine what happens if you redefine the ProdCat synonym:
DROP SYNONYM ProdCat
CREATE SYNONYM ProdCat
FOR AdventureWorks.Production.ProductCategory
SELECT * FROM ProdCat
DROP SYNONYM ProdCat
CREATE SYNONYM ProdCat
FOR AdventureWorks.Production.Culture
SELECT * FROM ProdCat
Note that you need to use DROP and CREATE whenever you want to change a synonym; there's
no ALTER SYNONYM statement. Figure 2 shows the result of running this batch of statements.
Note the very different results from the second execution of SELECT * FROM ProdCat,
because the synonym was redefined to refer to a different table in the interim.
You can take advantage of this behavior in your own applications. For example, suppose you've
got an application that needs to analyze customer data from a variety of different databases.
Rather than linking and unlinking the base tables from the individual databases, or writing
complex SQL that selects the tables to analyze, you could use synonyms. Define a synonym such
as DataTable to refer to the four-part name of the data that you want to work with, and redefine it
whenever you want to switch source data.
Of course, this late binding is a two-edged sword. Because SQL Server doesn't track whether a
synonym points to anything, it also doesn't do any sort of schema binding. If you drop a
synonym that's used in another statement, you won't find out that anything is wrong until you try
to run that statement.

File Under "Nice to Have"


Could you develop your next SQL Server application without synonyms? Sure. They don't bring
anything fundamentally new to the table; you could always use fully-qualified names anywhere

that you could use a synonym. But sometimes it's nice to have these little amenities in the
product, just because they make for less typing and an easier development experience. Perhaps
synonyms will only save you ten minutes over the course of an entire application, but still, those
little ten-minute savings add up. Let's hope Microsoft keeps delivering nice little improvements
like this along with the big headline features.

Table Indexes And Table Partitioning


Like a book, a table or a view can use the mechanism provided by an index. In a table or a view,
an index is a column (or many columns) that can be used to locate records and take a specific
action based on some rule reinforced on that (those) column(s).

Creating an Index With SQL


To create an index in SQL, the basic formula to follow is:
CREATE INDEX IndexName ON Table/View(Column(s))

IF EXISTS (
SELECT name
FROM sys.databases
WHERE name = N'Exercise'

)
DROP DATABASE Exercise
GO
CREATE DATABASE Exercise
GO
USE Exercise;
GO
CREATE TABLE Employees
(
EmployeeNumber int NOT NULL,
LastName nvarchar(20) NOT NULL,
FirstName nvarchar(20),
Username nchar(8) NOT NULL,
DateHired date NULL,
HourlySalary money
);
GO

INSERT INTO Employees


VALUES(62480, N'James', N'Haans', N'jhaans', N'1998-10-25', 28.02),
(35844, N'Gertrude', N'Monay', N'gmonay', N'2006-06-22', 14.36),
(24904, N'Philomne', N'Guillon', N'pguillon', N'2001-10-16', 18.05),
(48049, N'Eddie', N'Monsoon', N'emonsoon', N'08/10/2009',
26.22),
(25805, N'Peter', N'Mukoko', N'pmukoko', N'03-10-2004', 22.48),
(58405, N'Chritian', N'Allen', N'callen', N'06/16/1995', 16.45);
GO

CREATE INDEX IX_Employees


ON Employees(EmployeeNumber);
GO
If the index will include more than one column, list them separated by commas.
Here is an example:
CREATE INDEX IX_Employees2

ON Employees(LastName, Username);
GO
Deleting an Index
The basic syntax to delete an index in Transact-SQL is:
DROP INDEX IndexName ON TableName;

USE Exercise;
GO
DROP INDEX IX_Employees ON Employees;
GO
Checking the Existence of an Indexes
USE Exercise;
GO
IF EXISTS (SELECT name FROM sys.indexes
WHERE name = N'IX_Employees')
DROP INDEX IX_Employees
ON Employees
GO
CREATE INDEX IX_Employees
ON Employees(EmployeeNumber);
GO
The Types of Indexes
Clustered Indexes
In our introduction, we saw that an index is primarily created using one or more
columns from a designated table. This means that, when it comes to using the
index, we would use the values stored in the column(s) that was (were) selected for
the index. Such an index is referred to as clustered. The columns that were made
part of an index are referred to as keys.
USE Exercise;
GO
CREATE CLUSTERED INDEX IX_Employees

ON Employees(LastName);
GO
Non-clustered Index
While a clustered index uses a sorted list of records of a table or view, another type
of index can use a mechanism not based on the sorted records but on a bookmark.
This is called a non-clustered index. As opposed to a clustered table that can
contain only one clustered index, you can create not only one, but as many as 249
non-clustered indexes.
To create a non-clustered index in SQL, use the following formula:
CREATE NONCLUSTERED INDEX IndexName ON Table/View(Column(s))

USE Exercise;
GO
CREATE NONCLUSTERED INDEX NIX_Employees
ON Employees(LastName, FirstName);
GO
Introduction to Index Uniqueness
When creating a table, we can create index for it and let the index apply a rule that
states that each record would be unique. To take care of this, we can apply a
uniqueness rule on the index.

To create a uniqueness index in SQL, apply the UNIQUE keyword in the formula:
CREATE [UNIQUE] [CLUSTERED | NONCLUSTERED] INDEX index_name ON
Table/View(Column(s))

USE Exercise;
GO
CREATE UNIQUE CLUSTERED INDEX UIX_Employees
ON Employees(EmployeeNumber);
GO
Cannot create more than one clustered index on table 'Employees'. Drop the existing clustered index 'IX_Employees' before creating another.

USE Exercise;

GO
DROP INDEX IX_Employees ON Employees
Go
CREATE UNIQUE CLUSTERED INDEX UIX_Employees
ON Employees(EmployeeNumber);
GO
Table and Index Partitioning
Data in your database may involve many records, in thousands or millions, so
much that at one time, it may become difficult to manage. One way you can deal
with this is to store the records of a table in different file groups. This makes it
possible to store one section of records in one file group, another section in another
file group, possibly another section in another file group, and so on. As a result,
when it comes time to look for one or a few records among thousands or millions
of records, it would be easier to locate it or to locate them. Of course, the data still
belongs to one database and to the same table.
USE master;
GO

CREATE DATABASE RealEstate3


ON PRIMARY
( NAME = N'RealEstatePrimary',
FILENAME = N'C:\Real Estate Main Repository\RealEstateMain.mdf',
SIZE = 4MB,
MAXSIZE = 10MB,
FILEGROWTH = 1MB),
FILEGROUP RealEstateGroupRecords1
( NAME = N'RealEstateRecords1',
FILENAME = N'C:\Real Estate Main Repository\RealEstateFirst.ndf',
SIZE = 1MB,
MAXSIZE = 10MB,
FILEGROWTH = 1MB),
FILEGROUP RealEstateGroupRecords2
( NAME = N'RealEstateRecords2',
FILENAME = N'C:\Real Estate Secondary Repository\RealEstateSecond.ndf',
SIZE = 1MB,
MAXSIZE = 10MB,
FILEGROWTH = 1MB),
FILEGROUP RealEstateGroupRecords3
( NAME = N'RealEstateRecords3',
FILENAME = N'C:\Real Estate Third Repository\RealEstateThird.ndf',
SIZE = 1MB,
MAXSIZE = 10MB,
FILEGROWTH = 1MB)
LOG ON

( NAME = N'RealEstate3Log',
FILENAME = N'C:\Real Estate Main Repository\RealEstateLogger.ldf',
SIZE = 1MB,
MAXSIZE = 10MB,
FILEGROWTH = 1MB);

GO

Partitioning a Table
Before partitioning a table, you must create the necessary file groups. This can be
done when creating the database since it is at that time that you specify how the
database will be stored; that is, what files will hold the information of the database.
After creating the database and creating its file groups. Before partitioning a table, you must
create a partition function and a partition scheme.

A Partition Function
A partition function is used to define the ranges of records that will be stored in
what file group. The SQL formula to create a partition function is:
CREATE PARTITION FUNCTION PartitionFunctionName ( ParameterType )
AS RANGE [ LEFT | RIGHT ]
FOR VALUES (StartRange1, StartRange2, StartRange_n)

After closing the parenthesis, type AS RANGE, which indicates that you are going
to specify the ranges of values. This is followed by either LEFT or RIGHT. When
the partition function will have been created and when the table itself will have
been created, when the database engine is asked to look for a record or a range of
records, it may have to sort the records. If you want it to sort the records from left
to right, use the LEFT keyword. If you want the records sorted from right to left,
use the RIGHT keyword.
The AS RANGE LEFT or AS RANGE RIGHT expression is followed by FOR VALUES that
is followed by parentheses.
When creating a partition function, you must provide a way for the database engine to get a
range of records. For example, you can use records from number 1 to number 1000, then another
range from 1001 to 5000, and so on. Or you can specify that a range of records would go from
February 11th, 2000 to June 26th, 2005. Then another range would go from June 26th 2005 to
December 14th, 2006, and so on.
You specify the range in the parentheses that follow the FOR VALUES expression. Type the
first value of the first range, followed by a comma, followed by the first value of the second
range, and so on.

USE RealEstate3;
GO
CREATE PARTITION FUNCTION RealEstateSegmentation(int)
AS RANGE LEFT FOR VALUES(1, 10);
GO

A Partition Scheme
A partition scheme specifies the names of the file groups, in their order that will
store the ranges of records that were created in the partition function. The formula
to create a partition scheme is:
CREATE PARTITION SCHEME PartitionSchemeName
AS PARTITION PartitionFunctionName
[ ALL ] TO ( { file_group_name | [ PRIMARY ] } [ ,...n ] )

You start with the CREATION PARTITION SCHEME expression do indication your
intention. This is followed by a name. The name follows the rules of objects.
After the name of the partition scheme, type AS PARTITION followed by the name of the
partition function you should have previously created.
If you are planning to use only one file group, after the name of the partition function, enter
ALL, followed by parentheses, in which you will type PRIMARY.
If you are planning to use different file groups, after the name of the partition function, enter TO,
followed by parentheses. We saw that, in the parentheses of the FOR VALUES of the partition
function, you entered the starting value of the first range. In the parentheses of the TO keyword,
type the name of the file group that will hold the records of the first range of the partition
function. We also saw how to specify the second range in the partition function. In the
parentheses of the TO clause, after the name of the first file group, type a comma followed by the
name of the file group that will hold the records of the second range.

USE RealEstate3;
GO

CREATE PARTITION SCHEME RealEstateDistributionScheme


AS PARTITION RealEstateSegmentation
TO (RealEstateGroupRecords1, RealEstateGroupRecords2,
RealEstateGroupRecords3);
GO

Partitioning a Table

After creating the partition scheme, you can create the table. The formula to
specify a partition scheme when creating a table is:
CREATE TABLE What We Have Learned So Far
(
What We Have Learned So Far
) ON PartitionSchemeName(ColumnName)

USE RealEstate3;
GO

CREATE TABLE PropertyTypes


(
PropertyTypeID int identity(1,1) NOT NULL,
PropertyType varchar(20),
CONSTRAINT PK_PropertyTypes PRIMARY KEY(PropertyTypeID)
) ON RealEstateDistributionScheme(PropertyTypeID);
GO

CREATE TABLE Conditions


(

ConditionID int identity(1,1) NOT NULL,


Condition varchar(20),
CONSTRAINT PK_Conditions PRIMARY KEY(ConditionID)
) ON RealEstateDistributionScheme(ConditionID);
GO

CREATE TABLE Properties


(

PropertyID int identity(1,1) NOT NULL,


PropertyNumber char(6),
Address varchar(100),
City varchar(50),
State char(2),
ZIPCode varchar(12),
PropertyTypeID int
CONSTRAINT FK_PropertyTypes
FOREIGN KEY REFERENCES PropertyTypes(PropertyTypeID),
ConditionID int
CONSTRAINT FK_Conditions
FOREIGN KEY REFERENCES Conditions(ConditionID),
Bedrooms smallint,
Bathrooms float,
FinishedBasement bit,
IndoorGarage bit,
Stories smallint,
YearBuilt smallint,
MarketValue money,
CONSTRAINT PK_Properties PRIMARY KEY(PropertyID)
) ON RealEstateDistributionScheme(PropertyID);
GO

CURSORS
Processing Sequentially Through a Set of Records
Operations in a relational database act on a complete set of rows. The set of rows returned
by a SELECT statement consists of all the rows that satisfy the conditions in the WHERE
clause of the statement. This complete set of rows returned by the statement is known as
the result set. Applications, especially interactive online applications, cannot always work
effectively with the entire result set as a unit.

If applications need a mechanism to work with one row or a small block of rows at a time,
then Cursors are an extension to result sets that provide that mechanism.
Using a Cursor
To define a cursor the DECLARE CURSOR statement is used. Here is the basic format for the
simple cursor .
DECLARE cursor_name CURSOR
FOR select_statement
The cursor_name is the name we want to associate with the cursor. The select_statement is
the query that will determine the rows that make up the cursor.
Complete syntax:
ISO Syntax
DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR
FOR select_statement
[ FOR { READ ONLY | UPDATE [ OF column_name [ ,...n ] ] } ]
[;]
Transact-SQL Extended Syntax
DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ]
[ FORWARD_ONLY | SCROLL ]
[ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
[ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
[ TYPE_WARNING ]
FOR select_statement
[ FOR UPDATE [ OF column_name [ ,...n ] ] ]

[;]

cursor_name - the name of the server side cursor, must contain from 1 to 128 characters.
LOCAL - specifies that cursor can be available only in the batch, stored procedure,
or trigger in which the cursor was created. The LOCAL cursor will be implicitly
deallocated when the batch, stored procedure, or trigger terminates.

GLOBAL - specifies that cursor is global to the connection.


The GLOBAL cursor will be implicitly deallocated at disconnect.

FORWARD_ONLY - specifies that cursor can only fetch data sequentially


from the first to the last row. FETCH NEXT is the only fetch option supported.
STATIC - specifies that cursor will use a temporary copy of the data instead
of base tables. This cursor does not allow modifications and modifications
made to base tables are not reflected in the data returned by fetches made
to this cursor.
KEYSET - specifies that cursor uses the set of keys that uniquely identify
the cursor's rows (keyset), so that the membership and order of rows
in the cursor are fixed when the cursor is opened. SQL Server uses a table
in tempdb to store keyset. The KEYSET cursor allows updates nonkey
values from being made through this cursor, but inserts made by other
users are not visible. Updates nonkey values made by other users are
visible as the owner scrolls around the cursor, but updates key values
made by other users are not visible. If a row is deleted, an attempt to
fetch the row returns an @@FETCH_STATUS of -2.
DYNAMIC - specifies that cursor reflects all data changes made to the
base tables as you scroll around the cursor. FETCH ABSOLUTE
option is not supported with DYNAMIC cursor.

READ ONLY - specifies that cursor cannot be updated.

select_statement - the standard select statement, cannot contain COMPUTE, COMPUTE BY


and INTO keywords.
UPDATE [OF column_name [,...n]] - specifies that all cursor's columns can be updated
(if OF column_name [,...n] is not specified), or only the columns listed in the OF
column_name [,...n] list allow modifications.
DIFFERENT OPTIONS FOR FETCH:
NEXT - the default cursor fetch option.
FETCH NEXT returns the next row after the current row.
PRIOR - returns the prior row before the current row.
FIRST - returns the first row in the cursor.
LAST - returns the last row in the cursor.

Cursor Process

Transact-SQL cursors and API cursors have different syntax, but the following general process is
used with all SQL Server cursors:
1. Associate a cursor with the result set of a Transact-SQL statement, and define
characteristics of the cursor, such as whether the rows in the cursor can be updated.
2. Execute the Transact-SQL statement to populate the cursor.
3. Retrieve the rows in the cursor we want to see. The operation to retrieve one row or one
block of rows from a cursor is called a FETCH. Performing a series of fetches to retrieve
rows in either a forward or backward direction is called scrolling.
4. Optionally, perform modification operations (update or delete) on the row at the current
position in the cursor.
5. Close the cursor.
Cursor Functions:

@@FETCH_STATUS returns the status of the last cursor


FETCH statement issued against any cursor currently opened by
the connection.

Return value

Description

0
-1
-2

FETCH statement was successful.


FETCH statement failed or the row was beyond the result set.
Row fetched is missing.

@@CURSOR_ROWS
Returns the number of qualifying rows currently in the last cursor opened on the connection.
@@CURSOR_ROWS can be called to determine that the number of the rows that qualify for
a cursor are retrieved at the time @@CURSOR_ROWS is called.

CURSOR_STATUS:
A scalar function that allows the caller of a stored procedure to determine whether or not
the procedure has returned a cursor and result set for a given parameter.

declare @Empno nchar(5)


declare @RowNum int
declare EmpList cursor for
select top 5 Empno from Employee
OPEN EmpList
FETCH NEXT FROM EmpList
INTO @Empno
set @RowNum = 0
WHILE @@FETCH_STATUS = 0
BEGIN
set @RowNum = @RowNum + 1
print cast(@RowNum as char(1)) + ' ' + @Empno
FETCH NEXT FROM EmpList
INTO @Empno
END
CLOSE EmpList
DEALLOCATE EmpList
Here are the results that are generated from the print statement when I run it against my
Northwind Database.

1 7369
2 7499
3 7521

4 7566
5 7654
Let's look at the above code in a little more detail.
We first declared a cursor called "EmpList".

The "EmpList" cursor is populated using a SELECT statement that uses the
TOP clause to return only the top 5 employee no's.

Next the cursor is opened.

Each record in the "EmpList" cursor is retrieved, one record at a time,


using the "FETCH NEXT" next statement. The "FETCH NEXT" statement populates
the local variable @Empno with the Empno of the current record being fetched.

The @@FETCH_STATUS variable controls whether the WHILE loop is executed.


@@FETCH_STATUS is set to zero when a record is successfully retrieved from
the cursor "EmpList".

Inside the WHILE loop the @RowNum variable is incremented by 1 for each record
processed. The calculated Row Number and @Empno are then printed out.
Lastly, a "FETCH NEXT" statement is used to retrieve the next row before the next cycle of
the WHILE loop. This process continues one record at a time until all records in cursor
"EmpList" have been processed.

Another Example:

In this example, I chose the FAST_FORWARD option to optimize performance because it


creates a forward only, read only cursor.

DECLARE @VTitle nvarchar(30)


DECLARE @presentPrice decimal(5,2)
DECLARE @newPrice decimal(5,2)
DECLARE @MyCursor CURSOR

SET @MyCursor = CURSOR


FOR
Select VTitle,Price
From Video

FAST_FORWARD

OPEN @MyCursor
FETCH NEXT FROM @MyCursor
INTO @VTitle,@presentPrice
WHILE @@FETCH_STATUS = 0
BEGIN
if @presentPrice < 3
set @newPrice = @presentPrice + @presentPrice * 0.10
else
set @newPrice = @presentPrice + @presentPrice * 0.05
PRINT @VTitle + ' - present price is ' + cast(@presentPrice as nvarchar) +
' - new price is ' + cast(@newPrice as nvarchar)
FETCH NEXT FROM @MyCursor
INTO @VTitle,@presentPrice
END
CLOSE @MyCursor
DEALLOCATE @MyCursor
GO
--------------------------------------*

DECLARE @ename nvarchar(20)


DECLARE @presentSal numeric
DECLARE @newSal numeric
DECLARE @MyCursor CURSOR
SET @MyCursor = CURSOR FAST_FORWARD
FOR
Select ename,sal
From Employee

OPEN @MyCursor
FETCH NEXT FROM @MyCursor
INTO @ename,@presentSal
WHILE @@FETCH_STATUS = 0
BEGIN
if @presentSal < 3000
set @newSal = @presentSal + @presentSal * 0.10
else
set @newSal = @presentSal + @presentSal * 0.05
PRINT @ename + ' ' + cast(@presentSal as nvarchar) + ' ' + cast(@newSal as
nvarchar)
FETCH NEXT FROM @MyCursor
INTO @ename,@presentSal
END
CLOSE @MyCursor
DEALLOCATE @MyCursor
GO
Another example:

DECLARE @Ename nchar(15)


DECLARE @RowNum int
DECLARE EmpList SCROLL CURSOR
FOR SELECT Ename FROM Employee
OPEN EmpList
FETCH LAST FROM EmpList
INTO @Ename
SET @RowNum = 0
WHILE @@FETCH_STATUS = 0
BEGIN
SET @RowNum = @RowNum + 1
PRINT cast(@RowNum as char(1)) + ' ' + @Ename
FETCH PRIOR FROM EmpList
INTO @Ename

END
CLOSE EmpList
DEALLOCATE EmpList

Another Example:

This example declares a cursor and uses SELECT to display the


value of @@CURSOR_ROWS. The setting has a value of 0 before
the cursor is opened, and a value of -1 to indicate that the cursor
keyset is populated asynchronously.
SELECT @@CURSOR_ROWS
DECLARE videos_cursor CURSOR FOR
SELECT VTitle FROM video
OPEN videos_cursor
FETCH NEXT FROM videos_cursor
SELECT @@CURSOR_ROWS
CLOSE videos_cursor
DEALLOCATE videos_cursor

SELECT @@CURSOR_ROWS
DECLARE employees_cursor CURSOR FOR
SELECT ename FROM Employee
OPEN employees_cursor
FETCH NEXT FROM employees_cursor
SELECT @@CURSOR_ROWS
CLOSE employees_cursor
DEALLOCATE employees_cursor
Using a Select Statement
We can also use a SELECT statement to process through a set of records one record at a
time. To do this we will issue an initial SELECT statement that will return the first row, then
a series of follow on SELECT statements where each SELECT statement retrieves the next
row. This is done by using the "TOP 1" clause of the SELECT statement, and a WHERE
statement.
We will use the same example as above and only return the top 5 employee no's from the
Northwind database Employee table. In this code we will use two different "SELECT TOP 1"
statements and a WHILE loop to return all 5 records. Each record will be processed one at a

time.

declare @Empno nchar(5)


declare @RowNum int
select top 1 @Empno=Empno from Northwind.dbo.Employee
set @RowNum = 0
WHILE @RowNum < 5
BEGIN
set @RowNum = @RowNum + 1
print cast(@RowNum as char(1)) + ' ' + @Empno
select top 1 @Empno=Empno from Northwind.dbo.Employee
where Empno > @Empno
END
1
2
3
4
5

7369
7499
7521
7566
7654

Here we can see the first SELECT statement selects only the first Empno.
This ID is placed in the local variable @Empno.
The WHILE loop is controled by the local variable @RowNum.
Each time through the WHILE loop, the Row Number and Empno are printed out.
Prior to returning to the top of the WHILE loop we used another "SELECT TOP 1" statement
to select the next Empno.
This SELECT statement uses a WHERE clause on the SELECT statement to select the first
Empno that is greater than the Empno that was just printed.
The WHILE loop is processed 5 times, allowing the SELECT TOP 1 method to retrieve the top
5 Empno's one records at a time.

DECLARE @Empno nchar(5)


DECLARE @RowNum int
DECLARE EmpList CURSOR FAST_FORWARD FOR
SELECT TOP 5 Empno FROM Employee
OPEN EmpList
FETCH NEXT FROM EmpList
INTO @Empno
SET @RowNum = 0

WHILE @@FETCH_STATUS = 0
BEGIN
SET @RowNum = @RowNum + 1
PRINT cast(@RowNum as char(1)) + ' ' + @Empno
FETCH NEXT FROM EmpList
INTO @Empno
END
CLOSE EmpList
DEALLOCATE EmpList

Cursor Optimization Tips

Try to avoid using SQL Server cursors, whenever possible.


SQL Server cursors can results in some performance degradation in comparison with
select statements. Try to use correlated subquery or derived tables, if you need to
perform row-by-row operations.

Do not forget to close SQL Server cursor when its result set is not needed.

Do not forget to deallocate SQL Server cursor when the data structures
comprising the cursor are not needed.

Try to reduce the number of records to process in the cursor.


To reduce the cursor result set, use the WHERE clause in the cursor's select
statement.

Try to reduce the number of columns to process in the cursor.


Include in the cursor's select statement only necessary columns. It will reduce the
cursor result set. So, the cursor will use fewer resources. It can increase cursor
performance and reduce SQL Server overhead.

Use READ ONLY cursors, whenever possible, instead of updatable cursors.


Because using cursors can reduce concurrency and lead to unnecessary locking, try
to use READ ONLY cursors, if you do not need to update cursor result set.

Try avoid using insensitive, static and keyset cursors, whenever possible.
These types of cursor produce the largest amount of overhead on SQL Server,
because they cause a temporary table to be created in TEMPDB, which results in
some performance degradation.

Use FAST_FORWARD cursors, whenever possible.


The FAST_FORWARD cursors produce the least amount of overhead on SQL Server,
because there are read-only cursors and can only be scrolled from the first to the last
row. Use FAST_FORWARD cursor if you do not need to update cursor result set and
the FETCH NEXT will be the only used fetch option.

Use FORWARD_ONLY cursors, if you need updatable cursor and the FETCH
NEXT will be the only used fetch option.
If you need read-only cursor and the FETCH NEXT will be the only used fetch option,
try to use FAST_FORWARD cursor instead of FORWARD_ONLY cursor. By the way, if
one of the FAST_FORWARD or FORWARD_ONLY is specified the other cannot be
specified.

Here is an example cursor where backups are issued in a serial manner:

DECLARE @name VARCHAR(50) -- database name


DECLARE @path VARCHAR(256) -- path for backup files
DECLARE @fileName VARCHAR(256) -- filename for backup
DECLARE @fileDate VARCHAR(20) -- used for file name
SET @path = 'C:\MyBackup\'
SELECT @fileDate = CONVERT(VARCHAR(20),GETDATE(),112)
DECLARE db_cursor CURSOR FOR
SELECT name
FROM master.dbo.sysdatabases
WHERE name NOT IN ('master','model','msdb','tempdb')
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @name
WHILE @@FETCH_STATUS = 0
BEGIN
SET @fileName = @path + @name + '_' + @fileDate + '.BAK'
BACKUP DATABASE @name TO DISK = @fileName

FETCH NEXT FROM db_cursor INTO @name


END
CLOSE db_cursor
DEALLOCATE db_cursor

Cursor Components
Based on the example above, cursors include these components:
DECLARE statements - Declare variables used in the code block
SET\SELECT statements - Initialize the variables to a specific value
DECLARE CURSOR statement - Populate the cursor with values that will be evaluated
NOTE - There are an equal number of variables in the DECLARE <cursor_name>
CURSOR FOR statement as there are in the SELECT statement. This could be 1
or many variables and associated columns.
OPEN statement - Open the cursor to begin data processing
FETCH NEXT statements - Assign the specific values from the cursor to the variables
NOTE - This logic is used for the initial population before the WHILE statement
and then again during each loop in the process as a portion of the WHILE
statement
WHILE statement - Condition to begin and continue data processing
BEGIN...END statement - Start and end of the code block
NOTE - Based on the data processing multiple BEGIN...END statements can be
used
Data processing - In this example, this logic is to backup a database to a specific path and
file name, but this could be just about any DML or administrative logic

CLOSE statement - Releases the current data and associated locks, but permits the cursor
to be re-opened
DEALLOCATE statement - Destroys the cursor

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

declare @myvar int = 10, @mystr nvarchar(15)='Hello'


print @myvar
print @mystr
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

An insensitive cursor is not affected by changes to the underlying data. When the cursor
is opened, a temporary table is created in the tempdb database. This table is populated
with the results of the query immediately. Once populated, each fetch retrieves information
from the temporary table, rather than the live data.

To specify that a cursor is insensitive, add the INSENSITIVE clause immediately after the cursor
name in the declaration. For example:
DECLARE BillingCursor INSENSITIVE CURSOR
FOR SELECT JobId, ContractNumber, Duration, EngineerCost, PartsCost
FROM BillingSystemOutputData
If a DECLARE CURSOR using Transact-SQL syntax does not specify READ_ONLY,
OPTIMISTIC, or SCROLL_LOCKS, the default is as follows:

If the SELECT statement does not support updates (insufficient permissions, accessing
remote tables that do not support updates, and so on), the cursor is READ_ONLY.
STATIC and FAST_FORWARD cursors default to READ_ONLY.
DYNAMIC and KEYSET cursors default to OPTIMISTIC.

General Interview Questions of SQL SERVER


What is RDBMS?
Relational Data Base Management Systems (RDBMS) are database management systems that
maintain data records and indices in tables. Relationships may be created and maintained across
and among the data and tables. In a relational database, relationships between data items are
expressed by means of tables. Interdependencies among these tables are expressed by data values
rather than by pointers. This allows a high degree of data independence. An RDBMS has the
capability to recombine the data items from different files, providing powerful tools for data
usage.
What are the properties of the Relational tables?
Relational tables have six properties:
Values are atomic.
Column values are of the same kind.
Each row is unique.
The sequence of columns is insignificant.
The sequence of rows is insignificant.
Each column must have a unique name.
What is Normalization?
Database normalization is a data design and organization process applied to data structures based
on rules that help building relational databases. In relational database design, the process of
organizing data to minimize redundancy is called normalization. Normalization usually involves
dividing a database into two or more tables and defining relationships between the tables. The
objective is to isolate data so that additions, deletions, and modifications of a field can be made
in just one table and then propagated through the rest of the database via the defined
relationships.
What are different normalization forms?
1NF: Eliminate Repeating Groups
Make a separate table for each set of related attributes, and give each table a primary key. Each

field contains at most one value from its attribute domain.


2NF: Eliminate Redundant Data
If an attribute depends on only part of a multi-valued key, remove it to a separate table.
3NF: Eliminate Columns Not Dependent On Key
If attributes do not contribute to a description of the key, remove them to a separate table. All
attributes must be directly dependent on the primary key.
BCNF: Boyce-Codd Normal Form
If there are non-trivial dependencies between candidate key attributes, separate them out into
distinct tables.
4NF: Isolate Independent Multiple Relationships
No table may contain two or more 1:n or n:m relationships that are not directly related.
5NF: Isolate Semantically Related Multiple Relationships
There may be practical constrains on information that justify separating logically related manyto-many relationships.
ONF: Optimal Normal Form
A model limited to only simple (elemental) facts, as expressed in Object Role Model notation.
DKNF: Domain-Key Normal Form
A model free from all modification anomalies is said to be in DKNF.
Remember, these normalization guidelines are cumulative. For a database to be in 3NF, it must
first fulfill all the criteria of a 2NF and 1NF database.
What is De-normalization?
De-normalization is the process of attempting to optimize the performance of a database by
adding redundant data. It is sometimes necessary because current DBMSs implement the
relational model poorly. A true relational DBMS would allow for a fully normalized database at
the logical level, while providing physical storage of data that is tuned for high performance. Denormalization is a technique to move from higher to lower normal forms of database modeling in
order to speed up database access.
What is Stored Procedure?
A stored procedure is a named group of SQL statements that have been previously created and
stored in the server database. Stored procedures accept input parameters so that a single
procedure can be used over the network by several clients using different input data. And when
the procedure is modified, all clients automatically get the new version. Stored procedures
reduce network traffic and improve performance. Stored procedures can be used to help ensure
the integrity of the database.
e.g. sp_helpdb, sp_renamedb, sp_depends etc.
What is Trigger?
A trigger is a SQL procedure that initiates an action when an event (INSERT, DELETE or

UPDATE) occurs. Triggers are stored in and managed by the DBMS. Triggers are used to
maintain the referential integrity of data by changing the data in a systematic fashion. A trigger
cannot be called or executed; DBMS automatically fires the trigger as a result of a data
modification to the associated table. Triggers can be viewed as similar to stored procedures in
that both consist of procedural logic that is stored at the database level. Stored procedures,
however, are not event-drive and are not attached to a specific table as triggers are. Stored
procedures are explicitly executed by invoking a CALL to the procedure while triggers are
implicitly executed. In addition, triggers can also execute stored procedures.
Nested Trigger: A trigger can also contain INSERT, UPDATE and DELETE l
ogic within itself, so when the trigger is fired because of data modification
it can also cause another data modification, thereby firing another trigger.
A trigger that contains data modification logic
within itself is called a nested trigger.
What is View?
A simple view can be thought of as a subset of a table. It can be used for retrieving data, as well
as updating or deleting rows. Rows updated or deleted in the view are updated or deleted in the
table the view was created with. It should also be noted that as data in the original table changes,
so does data in the view, as views are the way to look at part of the original table. The results of
using a view are not permanently stored in the database. The data accessed through a view is
actually constructed using standard T-SQL select command and can come from one to many
different base tables or even other views.
What is Index?
An index is a physical structure containing pointers to the data.
Indices are created in an existing table to locate rows more quickly and efficiently. It is possible
to create an index on one or more columns of a table, and each index is given a name. The users
cannot see the indexes; they are just used to speed up queries. Effective indexes are one of the
best ways to improve performance in a database application. A table scan happens when there is
no index available to help a query. In a table scan SQL Server examines every row in the table to
satisfy the query results. Table scans are sometimes unavoidable, but on large tables, scans have
a terrific impact on performance.
What is a Linked Server?
Linked Servers is a concept in SQL Server by which we can add
other SQL Server to a Group and query both the SQL Server databases using
T-SQL Statements.
With a linked server, you can create very clean, easy to follow, SQL statements that allow remote
data to be retrieved, joined and combined with local data. Stored Procedure sp_addlinkedserver,
sp_addlinkedsrvlogin will be used add new Linked Server-level
1) General Questions of SQL SERVER
What is Cursor?

Cursor is a database object used by applications to manipulate data in a set on a row-by-row


basis, instead of the typical SQL commands that operate on all the rows in the set at one time.
In order to work with a cursor we need to perform some steps in the following order:
Declare cursor
Open cursor
Fetch row from the cursor
Process fetched row
Close cursor
Deallocate cursor
What is Collation?
Collation refers to a set of rules that determine how data is sorted and compared. Character data
is sorted using rules that define the correct character sequence, with options for specifying case
sensitivity, accent marks, kana character types and character width.
What is Difference between Function and Stored Procedure?
UDF can be used in the SQL statements anywhere in the WHERE/HAVING/SELECT section
where as Stored procedures cannot be. UDFs that return tables can be treated as another rowset.
This can be used in JOINs with other tables. Inline UDFs can be thought of as views that take
parameters and can be used in JOINs and other Rowset operations.
What is sub-query? Explain properties of sub-query?
Sub-queries are often referred to as sub-selects, as they allow a SELECT statement to be
executed arbitrarily within the body of another SQL statement. A sub-query is executed by
enclosing it in a set of parentheses. Sub-queries are generally used to return a single row as an
atomic value, though they may be used to compare values against multiple rows with the IN
keyword.
A subquery is a SELECT statement that is nested within another T-SQL statement. A subquery
SELECT statement if executed independently of the T-SQL statement, in which it is nested, will
return a resultset. Meaning a subquery SELECT statement can standalone and is not depended on
the statement in which it is nested. A subquery SELECT statement can return any number of
values, and can be found in, the column list of a SELECT statement, a FROM, GROUP BY,
HAVING, and/or ORDER BY clauses of a T-SQL statement. A Subquery can also be used as a
parameter to a function call. Basically a subquery can be used anywhere an expression can be
used. (Read More Here)
What are different Types of Join?
Cross Join
A cross join that does not have a WHERE clause produces the Cartesian product of the tables
involved in the join. The size of a Cartesian product result set is the number of rows in the first
table multiplied by the number of rows in the second table. The common example is when
company wants to combine each product with a pricing table to analyze each product at each
price.

Inner Join
A join that displays only the rows that have a match in both joined tables is known as inner Join.
This is the default type of join in the Query and View Designer.
Outer Join
A join that includes rows even if they do not have related rows in the joined table is an Outer
Join. You can create three different outer join to specify the unmatched rows to be included:
Left Outer Join: In Left Outer Join all rows in the first-named table i.e. left table,
which appears leftmost in the JOIN clause are included. Unmatched rows in the right
table do not appear.
Right Outer Join: In Right Outer Join all rows in the second-named table i.e. right
table, which appears rightmost in the JOIN clause are included. Unmatched rows in the
left table are not included.
Full Outer Join: In Full Outer Join all rows in all joined tables are included, whether
they are matched or not.
Self Join
This is a particular case when one table joins to itself, with one or two aliases to avoid confusion.
A self join can be of any type, as long as the joined tables are the same. A self join is rather
unique in that it involves a relationship with only one table. The common example is when
company has a hierarchal reporting structure whereby one member of staff reports to another.
Self Join can be Outer Join or Inner Join.
What are primary keys and foreign keys?
Primary keys are the unique identifiers for each row. They must contain unique values and
cannot be null. Due to their importance in relational databases, Primary keys are the most
fundamental of all keys and constraints. A table can have only one Primary key.
Foreign keys are both a method of ensuring data integrity and a manifestation of the relationship
between tables.
What is a User Defined Function? What kind of User-Defined Functions
can be created?
User-Defined Functions allow defining its own T-SQL functions that can accept 0 or more
parameters and return a single scalar data value or a table data type.
Different Kinds of User-Defined Functions created are:
Scalar User-Defined Function
A Scalar user-defined function returns one of the scalar data types. Text, ntext, image and
timestamp data types are not supported. These are the type of user-defined functions that most
developers are used to in other programming languages. You pass in 0 to many parameters and
you get a return value.
Inline Table-Value User-Defined Function
An Inline Table-Value user-defined function returns a table data type and is an exceptional

alternative to a view as the user-defined function can pass parameters into a T-SQL select
command and in essence provide us with a parameterized, non-updateable view of the
underlying tables.
Multi-statement Table-Value User-Defined Function
A Multi-Statement Table-Value user-defined function returns a table and is also an exceptional
alternative to a view as the function can support multiple T-SQL statements to build the final
result where the view is limited to a single SELECT statement. Also, the ability to pass
parameters into a TSQL select command or a group of them gives us the capability to in essence
create a parameterized, non-updateable view of the data in the underlying tables. Within the
create function command you must define the table structure that is being returned. After
creating this type of user-defined function, It can be used in the FROM clause of a T-SQL
command unlike the behavior found when using a stored procedure which can also return record
sets.
What is Identity?
Identity (or AutoNumber) is a column that automatically
generates numeric values. A start and increment value can be set,
but most DBA leave these at 1.
A GUID column also generates numbers; the value of this cannot be controlled. Identity/GUID
columns do not need to be indexed.
What is DataWarehousing?
Subject-oriented, meaning that the data in the database is organized
so that all the data elements relating to the same real-world event or
object are linked together;
Time-variant, meaning that the changes to the data in the
database are tracked and recorded so that reports can be produced
showing changes over time;
Non-volatile, meaning that data in the database is never
over-written or deleted, once committed, the data is static,
read-only, but retained for future reporting.
Integrated, meaning that the database contains data from
most or all of an organizations operational applications,
and that this data is made consistent.
1) General Questions of SQL SERVER
2) Common Questions Asked
Which TCP/IP port does SQL Server run on? How can it be changed?
SQL Server runs on port 1433. It can be changed from the
Network Utility TCP/IP properties -> Port number, both on client and the server.

What are the difference between clustered and a non-clustered index?


A clustered index is a special type of index that reorders
the way records in the table are physically stored.
Therefore table can have only one clustered index.
The leaf nodes of a clustered index contain the data pages.
A non clustered index is a special type of index in which the logical
order of the index does not match the physical stored order
of the rows on disk. The leaf node of a non clustered
index does not consist of the data pages but contains pointers to data.
What are the different index configurations a table can have?
A table can have one of the following index configurations:
No indexes
A clustered index
A clustered index and many nonclustered indexes
A nonclustered index
Many nonclustered indexes
What are different types of Collation Sensitivity?
Case sensitivity A and a, B and b, etc.
Accent sensitivity a and , o and , etc.
Kana Sensitivity When Japanese kana characters Hiragana and Katakana are treated differently,
it is called Kana sensitive.
Width sensitivity A single-byte character (half-width) and the same character represented as a
double-byte character (full-width) are treated differently than it is width sensitive.
What is OLTP (Online Transaction Processing)?
In OLTP online transaction processing systems relational database design use the discipline of
data modeling and generally follow the Codd rules of data normalization in order to ensure
absolute data integrity. Using these rules complex information is broken down into its most
simple structures (a table) where all of the individual atomic level elements relate to each other
and satisfy the normalization rules.
Whats the difference between a primary key and a unique key?
Both primary key and unique key enforces uniqueness of the column on which they are defined.
But by default primary key creates a clustered index on the column, where are unique creates a
nonclustered index by default. Another major difference is that, primary key doesnt allow
NULLs, but unique key allows one NULL only.
What is difference between DELETE & TRUNCATE commands?

Delete command removes the rows from a table based on the


condition that we provide with a WHERE clause.
Truncate will actually remove all the rows from a table and we can rollback it.
TRUNCATE
TRUNCATE is faster and uses fewer system and transaction log resources than DELETE.
TRUNCATE removes the data by deallocating the data pages used to store the tables
data, and only the page deallocations are recorded in the transaction log.
TRUNCATE removes all rows from a table, but the table structure, its columns,
constraints, indexes and so on, remains. The counter used by an identity for new rows is
reset to the seed for the column.
You cannot use TRUNCATE TABLE on a table referenced by a FOREIGN KEY
constraint. Because TRUNCATE TABLE is not logged, it cannot activate a trigger.
TRUNCATE cannot be rolled back.
TRUNCATE is DDL Command.
TRUNCATE Resets identity of the table
DELETE
DELETE removes rows one at a time and records an entry in the transaction log for each
deleted row.
If you want to retain the identity counter, use DELETE instead. If you want to remove
table definition and its data, use the DROP TABLE statement.
DELETE Can be used with or without a WHERE clause
DELETE Activates Triggers.
DELETE can be rolled back.
DELETE is DML Command.
DELETE does not reset identity of the table.
When is the use of UPDATE_STATISTICS command?
This command is basically used when a large processing of data has occurred. If a large amount
of deletions any modification or Bulk Copy into the tables has occurred, it has to update the
indexes to take these changes into account. UPDATE_STATISTICS updates the indexes on these
tables accordingly.
What is the difference between a HAVING CLAUSE and a WHERE CLAUSE?
They specify a search condition for a group or an aggregate. But the difference is that HAVING
can be used only with the SELECT statement. HAVING is typically used in a GROUP BY
clause. When GROUP BY is not used, HAVING behaves like a WHERE clause. Having Clause
is basically used only with the GROUP BY function in a query whereas WHERE Clause is

applied to each row before they are part of the GROUP BY function in a query.
What are the properties and different Types of Sub-Queries?
Properties of Sub-Query
A sub-query must be enclosed in the parenthesis.
A sub-query must be put in the right hand of the comparison operator, and
A sub-query cannot contain an ORDER-BY clause.
A query can contain more than one sub-query.
Types of Sub-query
Single-row sub-query, where the sub-query returns only one row.
Multiple-row sub-query, where the sub-query returns multiple rows,. and
Multiple column sub-query, where the sub-query returns multiple columns
What is SQL Profiler?
SQL Profiler is a graphical tool that allows system administrators to monitor events in an
instance of Microsoft SQL Server. You can capture and save data about each event to a file or
SQL Server table to analyze later. For example, you can monitor a production environment to see
which stored procedures are hampering performances by executing too slowly.
Use SQL Profiler to monitor only the events in which you are interested. If traces are becoming
too large, you can filter them based on the information you want, so that only a subset of the
event data is collected. Monitoring too many events adds overhead to the server and the
monitoring process and can cause the trace file or trace table to grow very large, especially when
the monitoring process takes place over a long period of time.
What are the authentication modes in SQL Server? How can it be changed?
Windows mode and Mixed Mode SQL & Windows.
To change authentication mode in SQL Server click Start, Programs, Microsoft SQL Server and
click SQL Enterprise Manager to run SQL Enterprise Manager from the Microsoft SQL Server
program group. Select the server then from the Tools menu select SQL Server Configuration
Properties, and choose the Security page.
1) General Questions of SQL SERVER
Which command using Query Analyzer will give you the version of SQL server and
operating system?
SELECT SERVERPROPERTY ('productversion'), SERVERPROPERTY ('productlevel'),
SERVERPROPERTY ('edition')

What is SQL Server Agent?


SQL Server agent plays an important role in the day-to-day tasks of a database administrator
(DBA). It is often overlooked as one of the main tools for SQL Server management. Its purpose
is to ease the implementation of tasks for the DBA, with its full-function scheduling engine,
which allows you to schedule your own jobs and scripts.
Can a stored procedure call itself or recursive stored procedure? How much level SP

nesting is possible?
Yes. Because Transact-SQL supports recursion, you can write stored procedures that call
themselves. Recursion can be defined as a method of problem solving wherein the solution is
arrived at by repetitively applying it to subsets of the problem. A common application of
recursive logic is to perform numeric computations that lend themselves to repetitive evaluation
by the same processing steps. Stored procedures are nested when one stored procedure calls
another or executes managed code by referencing a CLR routine, type, or aggregate. You can
nest stored procedures and managed code references up to 32 levels.
What is Log Shipping?
Log shipping is the process of automating the backup of database and transaction log files on a
production SQL server, and then restoring them onto a standby server. Enterprise Editions only
supports log shipping. In log shipping the transactional log file from one server is automatically
updated into the backup database on the other server. If one server fails, the other server will
have the same db and can be used this as the Disaster Recovery plan. The key feature of log
shipping is that it will automatically backup transaction logs throughout the day and
automatically restore them on the standby server at defined interval.
Name 3 ways to get an accurate count of the number of records in a table?
SELECT * FROM table1
SELECT COUNT(*) FROM table1
SELECT rows FROM sysindexes WHERE id = OBJECT_ID(table1) AND indid < 2

What does it mean to have QUOTED_IDENTIFIER ON? What are the implications of
having it OFF?
When SET QUOTED_IDENTIFIER is ON, identifiers can be delimited by double quotation
marks, and literals must be delimited by single quotation marks. When SET
QUOTED_IDENTIFIER is OFF, identifiers cannot be quoted and must follow all Transact-SQL
rules for identifiers.
What is the difference between a Local and a Global temporary table?
A local temporary table exists only for the duration of a connection or, if defined inside a
compound statement, for the duration of the compound statement.
A global temporary table remains in the database permanently, but the rows exist only within a
given connection. When connection is closed, the data in the global temporary table disappears.
However, the table definition remains with the database for access when database is opened next
time.
What is the STUFF function and how does it differ from the REPLACE function?
STUFF function is used to overwrite existing characters. Using this syntax, STUFF
(string_expression, start, length, replacement_characters), string_expression is the string that will
have characters substituted, start is the starting position, length is the number of characters in the
string that are substituted, and replacement_characters are the new characters interjected into the
string. REPLACE function to replace existing characters of all occurrences. Using the syntax
REPLACE (string_expression, search_string, replacement_string), where every incidence of
search_string found in the string_expression will be replaced with replacement_string.

What is PRIMARY KEY?


A PRIMARY KEY constraint is a unique identifier for a row within a database table. Every table
should have a primary key constraint to uniquely identify each row and only one primary key
constraint can be created for each table. The primary key constraints are used to enforce entity
integrity.
What is UNIQUE KEY constraint?
A UNIQUE constraint enforces the uniqueness of the values in a set of columns, so no duplicate
values are entered. The unique key constraints are used to enforce entity integrity as the primary
key constraints.
What is FOREIGN KEY?
A FOREIGN KEY constraint prevents any actions that would destroy links between tables with
the corresponding data values. A foreign key in one table points to a primary key in another
table. Foreign keys prevent actions that would leave rows with foreign key values when there are
no primary keys with that value. The foreign key constraints are used to enforce referential
integrity.
What is CHECK Constraint?
A CHECK constraint is used to limit the values that can be placed in a column. The check
constraints are used to enforce domain integrity.
What is NOT NULL Constraint?
A NOT NULL constraint enforces that the column will not accept null values. The not null
constraints are used to enforce domain integrity, as the check constraints.
How to get @@ERROR and @@ROWCOUNT at the same time?
If @@Rowcount is checked after Error checking statement then it will have 0 as the value of
@@Recordcount as it would have been reset. And if @@Recordcount is checked before the
error-checking statement then @@Error would get reset. To get @@error and @@rowcount at
the same time do both in same statement and store them in local variable. SELECT @RC =
@@ROWCOUNT, @ER = @@ERROR
What is a Scheduled Jobs or What is a Scheduled Tasks?
Scheduled tasks let user automate processes that run on regular or predictable cycles. User can
schedule administrative tasks, such as cube processing, to run during times of slow business
activity. User can also determine the order in which tasks run by creating job steps within a SQL
Server Agent job. E.g. back up database, Update Stats of Tables. Job steps give user control over
flow of execution. If one job fails, user can configure SQL Server Agent to continue to run the
remaining tasks or to stop execution.
What are the advantages of using Stored Procedures?
Stored procedure can reduced network traffic and latency, boosting application
performance.
Stored procedure execution plans can be reused, staying cached in SQL Servers memory,

reducing server overhead.


Stored procedures help promote code reuse.
Stored procedures can encapsulate logic. You can change stored procedure code without
affecting clients.
Stored procedures provide better security to your data.
What is a table called, if it has neither Cluster nor Non-cluster Index? What is it used for?
Unindexed table or Heap. Microsoft Press Books and Book on Line (BOL) refers it as Heap. A
heap is a table that does not have a clustered index and, therefore, the pages are not linked by
pointers. The IAM pages are the only structures that link the pages in a table together. Unindexed
tables are good for fast storing of data. Many times it is better to drop all indexes from table and
then do bulk of inserts and to restore those indexes after that.
Can SQL Servers linked to other servers like Oracle?
SQL Server can be linked to any server provided it has OLE-DB provider from Microsoft to
allow a link. E.g. Oracle has an OLE-DB provider for oracle that Microsoft provides to add it as
linked server to SQL Server group
What is BCP? When does it used?
BulkCopy is a tool used to copy huge amount of data from tables and views. BCP does not copy
the structures same as source to destination. BULK INSERT command helps to import a data file
into a database table or view in a user-specified format.
What command do we use to rename a db, a table and a column?
To rename db
sp_renamedb 'oldname' , 'newname'

If someone is using db it will not accept sp_renmaedb. In that case first bring db to single user
using sp_dboptions. Use sp_renamedb to rename database. Use sp_dboptions to bring database
to multi user mode.
E.g.
USE master;
GO
EXEC sp_dboption AdventureWorks, 'Single User', True
GO
EXEC sp_renamedb 'AdventureWorks', 'AdventureWorks_New'
GO
EXEC sp_dboption AdventureWorks, 'Single User', False
GO

To rename Table
We can change the table name using sp_rename as follows,
sp_rename 'oldTableName' 'newTableName'

E.g.

sp_RENAME 'Table_First', 'Table_Last'


GO

To rename Column
The script for renaming any column :
sp_rename 'TableName.[OldcolumnName]', 'NewColumnName', 'Column'

E.g.
sp_RENAME 'Table_First.Name', 'NameChange' , 'COLUMN'
GO

What are sp_configure commands and set commands?


Use sp_configure to display or change server-level settings. To change database-level settings,
use ALTER DATABASE. To change settings that affect only the current user session, use the
SET statement.
E.g.
sp_CONFIGURE 'show advanced', 0
GO
RECONFIGURE
GO
sp_CONFIGURE
GO

You can run following command and check advance global configuration settings.
sp_CONFIGURE 'show advanced', 1
GO
RECONFIGURE
GO
sp_CONFIGURE
GO

How to implement one-to-one, one-to-many and many-to-many relationships while


designing tables?
One-to-One relationship can be implemented as a single table and rarely as two tables with
primary and foreign key relationships. One-to-Many relationships are implemented by splitting
the data into two tables with primary key and foreign key relationships.
Many-to-Many relationships are implemented using a junction table with the keys from both the
tables forming the composite primary key of the junction table.
What is an execution plan? When would you use it? How would you view the execution
plan?
An execution plan is basically a road map that graphically or textually shows the data retrieval
methods chosen by the SQL Server query optimizer for a stored procedure or ad-hoc query and is
a very useful tool for a developer to understand the performance characteristics of a query or
stored procedure since the plan is the one that SQL Server will place in its cache and use to
execute the stored procedure or query. From within Query Analyzer is an option called Show
Execution Plan (located on the Query drop-down menu). If this option is turned on it will
display query execution plan in separate window when query is ran again.

What are the basic functions for master, msdb, model, tempdb and resource databases?
The master database holds information for all databases located on the SQL Server instance and
is theglue that holds the engine together. Because SQL Server cannot start without a functioning
masterdatabase, you must administer this database with care.
The msdb database stores information regarding database backups, SQL Agent information,
DTS packages, SQL Server jobs, and some replication information such as for log shipping.
The tempdb holds temporary objects such as global and local temporary tables and stored
procedures.
The model is essentially a template database used in the creation of any new user database
created in the instance.
The resoure Database is a read-only database that contains all the system objects that are
included with SQL Server. SQL Server system objects, such as sys.objects, are physically
persisted in the Resource database, but they logically appear in the sys schema of every database.
The Resource database does not contain user data or user metadata.
What is Service Broker?
Service Broker is a message-queuing technology in SQL Server that allows developers to
integrate SQL Server fully into distributed applications. Service Broker is feature which provides
facility to SQL Server to send an asynchronous, transactional message. it allows a database to
send a message to another database without waiting for the response, so the application will
continue to function if the remote database is temporarily unavailable.
Where SQL server user names and passwords are stored in SQL server?
They get stored in System Catalog Views sys.server_principals and sys.sql_logins.
What is Policy Management?
Policy Management in SQL SERVER 2008 allows you to define and enforce policies for
configuring and managing SQL Server across the enterprise. Policy-Based Management is
configured in SQL Server Management Studio (SSMS). Navigate to the Object Explorer and
expand the Management node and the Policy Management node; you will see the Policies,
Conditions, and Facets nodes. (Read More Here)
What is Replication and Database Mirroring?
Database mirroring can be used with replication to provide availability for the publication
database. Database mirroring involves two copies of a single database that typically reside on
different computers. At any given time, only one copy of the database is currently available to
clients which are known as the principal database. Updates made by clients to the principal
database are applied on the other copy of the database, known as the mirror database. Mirroring
involves applying the transaction log from every insertion, update, or deletion made on the
principal database onto the mirror database.
What are Sparse Columns?
A sparse column is another tool used to reduce the amount of physical storage used in a database.

They are the ordinary columns that have an optimized storage for null values. Sparse columns
reduce the space requirements for null values at the cost of more overhead to retrieve nonnull
values. (Read More Here)
What does TOP Operator Do?
The TOP operator is used to specify the number of rows to be returned by a query. The TOP
operator has new addition in SQL SERVER 2008 that it accepts variables as well as literal values
and can be used with INSERT, UPDATE, and DELETES statements.
What is CTE?
CTE is an abbreviation Common Table Expression. A Common Table Expression (CTE) is an
expression that can be thought of as a temporary result set which is defined within the execution
of a single SQL statement. A CTE is similar to a derived table in that it is not stored as an object
and lasts only for the duration of the query. (Read More Here)
What is MERGE Statement?
MERGE is a new feature that provides an efficient way to perform multiple DML operations. In
previous versions of SQL Server, we had to write separate statements to INSERT, UPDATE, or
DELETE data based on certain conditions, but now, using MERGE statement we can include the
logic of such data modifications in one statement that even checks when the data is matched then
just update it and when unmatched then insert it. One of the most important advantages of
MERGE statement is all the data is read and processed only once.
What is Filtered Index?
Filtered Index is used to index a portion of rows in a table that means it applies filter on INDEX
which improves query performance, reduce index maintenance costs, and reduce index storage
costs compared with full-table indexes. When we see an Index created with some where clause
then that is actually a FILTERED INDEX.
Which are new data types introduced in SQL SERVER 2008?
The GEOMETRY Type: The GEOMETRY data type is a system .NET common language runtime
(CLR) data type in SQL Server. This type represents data in a two-dimensional Euclidean
coordinate system.
The GEOGRAPHY Type: The GEOGRAPHY datatypes functions are the same as with
GEOMETRY. The difference between the two is that when you specify GEOGRAPHY, you are
usually specifying points in terms of latitude and longitude.
New Date and Time Datatypes: SQL Server 2008 introduces four new datatypes related to date
and time: DATE, TIME, DATETIMEOFFSET, and DATETIME2.
DATE: The new DATE type just stores the date itself. It is based on the Gregorian
calendar and handles years from 1 to 9999.
TIME: The new TIME (n) type stores time with a range of 00:00:00.0000000 through
23:59:59.9999999. The precision is allowed with this type. TIME supports seconds down
to 100 nanoseconds. The n in TIME (n) defines this level of fractional second precision,
from 0 to 7 digits of precision.
The DATETIMEOFFSET Type: DATETIMEOFFSET (n) is the time-zone-aware version
of a datetime datatype. The name will appear less odd when you consider what it really is:

a date + a time + a time-zone offset. The offset is based on how far behind or ahead you
are from Coordinated Universal Time (UTC) time.
The DATETIME2 Type: It is an extension of the datetime type in earlier versions of SQL
Server. This new datatype has a date range covering dates from January 1 of year 1
through December 31 of year 9999. This is a definite improvement over the 1753 lower
boundary of the datetime datatype. DATETIME2 not only includes the larger date range,
but also has a timestamp and the same fractional precision that TIME type provides
What are the Advantages of using CTE?
Using CTE improves the readability and makes maintenance of complex queries easy.
The query can be divided into separate, simple, logical building blocks which can be then
used to build more complex CTEs until final result set is generated.
CTE can be defined in functions, stored procedures, triggers or even views.
After a CTE is defined, it can be used as a Table or a View and can SELECT, INSERT,
UPDATE or DELETE Data.
How can we rewrite sub-queries into simple select statements or with joins?
Yes we can write using Common Table Expression (CTE). A Common Table Expression (CTE)
is an expression that can be thought of as a temporary result set which is defined within the
execution of a single SQL statement. A CTE is similar to a derived table in that it is not stored as
an object and lasts only for the duration of the query.
E.g.
USE AdventureWorks
GO
WITH EmployeeDepartment_CTE AS (
SELECT EmployeeID,DepartmentID,ShiftID
FROM HumanResources.EmployeeDepartmentHistory
)
SELECT ecte.EmployeeId,ed.DepartmentID, ed.Name,ecte.ShiftID
FROM HumanResources.Department ed
INNER JOIN EmployeeDepartment_CTE ecte ON ecte.DepartmentID = ed.DepartmentID
GO

What is CLR?
In SQL Server 2008, SQL Server objects such as user-defined functions can be created using
such CLR languages. This CLR language support extends not only to user-defined functions, but
also to stored procedures and triggers. You can develop such CLR add-ons to SQL Server using
Visual Studio 2008. (
What are synonyms?
Synonyms give you the ability to provide alternate names for database objects. You can alias
object names; for example, using the Employee table as Emp. You can also shorten names. This
is especially useful when dealing with three and four part names; for example, shortening
server.database.owner.object to object.
What is LINQ?
Language Integrated Query (LINQ) adds the ability to query objects using .NET languages. The

LINQ to SQL object/relational mapping (O/RM) framework provides the following basic
features:
Tools to create classes (usually called entities) mapped to database tables
Compatibility with LINQs standard query operations
The DataContext class, with features such as entity record monitoring, automatic SQL
statement generation, record concurrency detection, and much more
What is Isolation Levels?
Transactions specify an isolation level that defines the degree to which one transaction must be
isolated from resource or data modifications made by other transactions. Isolation levels are
described in terms of which concurrency side-effects, such as dirty reads or phantom reads, are
allowed.
Transaction isolation levels control:
Whether locks are taken when data is read, and what type of locks are requested.
How long the read locks are held.
Whether a read operation referencing rows modified by another transaction:
Blocks until the exclusive lock on the row is freed.
Retrieves the committed version of the row that existed at the time the statement or
transaction started.
Reads the uncommitted data modification.
What is use of EXCEPT Clause?
EXCEPT clause is similar to MINUS operation in Oracle. The EXCEPT query and MINUS
query returns all rows in the first query that are not returned in the second query. Each SQL
statement within the EXCEPT query and MINUS query must have the same number of fields in
the result sets with similar data types.
What is XPath?
XPath uses a set of expressions to select nodes to be processed. The most common expression
that youll use is the location path expression, which returns back a set of nodes called a node
set. XPath can use both an unabbreviated and an abbreviated syntax. The following is the
unabbreviated syntax for a location path:
/axisName::nodeTest[predicate]/axisName::nodeTest[predicate]
What is NOLOCK?
Using the NOLOCK query optimizer hint is generally considered good practice in order to
improve concurrency on a busy system. When the NOLOCK hint is included in a SELECT
statement, no locks are taken when data is read. The result is a Dirty Read, which means that
another process could be updating the data at the exact time you are reading it. There are no
guarantees that your query will retrieve the most recent data. The advantage to performance is
that your reading of data will not block updates from taking place, and updates will not block
your reading of data. SELECT statements take Shared (Read) locks. This means that multiple

SELECT statements are allowed simultaneous access, but other processes are blocked from
modifying the data. The updates will queue until all the reads have completed, and reads
requested after the update will wait for the updates to complete. The result to your system is
delay (blocking).
How would you handle error in SQL SERVER 2008?
SQL Server now supports the use of TRYCATCH constructs for providing rich error handling.
TRYCATCH lets us build error handling at the level we need, in the way we need to, by
setting a region where if any error occurs, it will break out of the region and head to an error
handler. The basic structure is as follows:
BEGIN TRY
<code>
END TRY
BEGIN CATCH
<code>
END CATCH
So if any error occurs in the TRY block, execution is diverted to the CATCH block, and the error
can be dealt.
What is RAISEERROR?
RaiseError generates an error message and initiates error processing for the session.
RAISERROR can either reference a user-defined message stored in the sys.messages catalog
view or build a message dynamically. The message is returned as a server error message to the
calling application or to an associated CATCH block of a TRYCATCH construct.
How to rebuild Master Databse?
Master database is system database and it contains information about running servers
configuration. When SQL Server 2005 is installed it usually creates master, model, msdb,
tempdb resource and distribution system database by default. Only Master database is the one
which is absolutely must have database. Without Master database SQL Server cannot be started.
This is the reason it is extremely important to backup Master database.
To rebuild the Master database, Run Setup.exe, verify, and repair a SQL Server instance, and
rebuild the system databases. This procedure is most often used to rebuild the master database
for a corrupted installation of SQL Server.
What is XML Datatype?
The xml data type lets you store XML documents and fragments in a SQL Server database. An
XML fragment is an XML instance that is missing a single top-level element. You can create
columns and variables of the xml type and store XML instances in them. The xml data type and
associated methods help integrate XML into the relational framework of SQL Server.
What is Data Compression?

In SQL SERVE 2008 Data Compression comes in two flavors:


Row Compression
Page Compression
Row Compression
Row compression changes the format of physical storage of data. It minimize the metadata
(column information, length, offsets etc) associated with each record. Numeric data types and
fixed length strings are stored in variable-length storage format, just like Varchar.
Page Compression
Page compression allows common data to be shared between rows for a given page. Its uses the
following techniques to compress data:
Row compression.
Prefix Compression. For every column in a page duplicate prefixes are identified. These
prefixes are saved in compression information headers (CI) which resides after page
header. A reference number is assigned to these prefixes and that reference number is
replaced where ever those prefixes are being used.
Dictionary Compression.
Dictionary compression searches for duplicate values throughout the page and stores them in CI.
The main difference between prefix and dictionary compression is that prefix is only restricted to
one column while dictionary is applicable to the complete page.
What is use of DBCC Commands?
The Transact-SQL programming language provides DBCC statements that act as Database
Console Commands for SQL Server. DBCC commands are used to perform following tasks.
Maintenance tasks on database, index, or filegroup.
Tasks that gather and display various types of information.
Validation operations on a database, table, index, catalog, filegroup, or allocation of
database pages.
Miscellaneous tasks such as enabling trace flags or removing a DLL from memory.
How to find tables without Indexes?
Run following query in Query Editor.
USE <database_name>;
GO
SELECT SCHEMA_NAME(schema_id) AS schema_name
,name AS table_name
FROM sys.tables
WHERE OBJECTPROPERTY(OBJECT_ID,'IsIndexed') = 0
ORDER BY schema_name, table_name;
GO

How to copy the tables, schema and views from one SQL Server to another?

There are multiple ways to do this.


1. Detach Database from one server and Attach Database to another server.
2. Manually script all the objects using SSMS and run the script on new server.
3. Use Wizard of SSMS. (Read More Here)
How to copy data from one table to another table?
There are multiple ways to do this.
1) INSERT INTO SELECT
This method is used when table is already created in the database earlier and data is to be
inserted into this table from another table. If columns listed in insert clause and select clause are
same, they are not required to list them.
2) SELECT INTO
This method is used when table is not created earlier and needs to be created when data from one
table is to be inserted into newly created table from another table. New table is created with same
data types as selected columns.
(Read More Here)
What is Catalog Views?
Catalog views return information that is used by the SQL Server Database Engine. Catalog
Views are the most general interface to the catalog metadata and provide the most efficient way
to obtain, transform, and present customized forms of this information. All user-available catalog
metadata is exposed through catalog views.
What is PIVOT and UNPIVOT?
A Pivot Table can automatically sort, count, and total the data stored in one table or spreadsheet
and create a second table displaying the summarized data. The PIVOT operator turns the values
of a specified column into column names, effectively rotating a table.
UNPIVOT table is reverse of PIVOT Table.
What is Filestream?
Filestream allows you to store large objects in the file system and have these files integrated
within the database. It enables SQL Server based applications to store unstructured data such as
documents, images, audios, videos etc. in the file system. FILESTREAM basically integrates the
SQL Server Database Engine with New Technology File System (NTFS); it basically stores the
data in varbinary (max) data type. Using this data type, the unstructured data is stored in the
NTFS file system and the SQL Server Database Engine manages the link between the Filestream
column and the actual file located in the NTFS. Using Transact SQL statements users can insert,
update, delete and select the data stored in FILESTREAM enabled tables.
What is Dirty Read ?
A dirty read occurs when two operations say, read and write occurs together giving the incorrect
or unedited data. Suppose, A has changed a row, but has not committed the changes. B reads the
uncommitted data but his view of the data may be wrong so that is Dirty Read.

What is SQLCMD?
sqlcmd is enhanced version of the isql and osql and it provides way more functionality than other
two options. In other words sqlcmd is better replacement of isql (which will be deprecated
eventually) and osql (not included in SQL Server 2005 RTM). sqlcmd can work two modes i)
BATCH and ii) interactive modes.
What is Aggregate Functions?
Aggregate functions perform a calculation on a set of values and return a single value. Aggregate
functions ignore NULL values except COUNT function. HAVING clause is used, along with
GROUP BY, for filtering query using aggregate values.
Following functions are aggregate functions.
AVG, MIN, CHECKSUM_AGG, SUM, COUNT, STDEV, COUNT_BIG, STDEVP,
GROUPING, VAR, MAX, VARP
What do you mean by Table Sample?
TABLESAMPLE allows you to extract a sampling of rows from a table in the FROM clause.
The rows retrieved are random and they are not in any order. This sampling can be based on a
percentage of number of rows. You can use TABLESAMPLE when only a sampling of rows is
necessary for the application instead of a full result set.
What is Row_Number()?
ROW_NUMBER() returns a column as an expression that contains the rows number within the
result set. This is only a number used in the context of the result set, if the result changes, the
ROW_NUMBER() will change.
What are Ranking Functions?
Ranking functions return a ranking value for each row in a partition. All the ranking functions
are non-deterministic. Different Ranking functions are:
ROW_NUMBER () OVER ([<partition_by_clause>] <order_by_clause>)
Returns the sequential number of a row within a partition of a result set, starting at 1 for the first
row in each partition.
RANK () OVER ([<partition_by_clause>] <order_by_clause>)
Returns the rank of each row within the partition of a result set.
DENSE_RANK () OVER ([<partition_by_clause>] <order_by_clause>)
Returns the rank of rows within the partition of a result set, without any gaps in the ranking.
What is the difference between UNION and UNION ALL?
UNION
The UNION command is used to select related information from two tables, much like the JOIN
command. However, when using the UNION command all selected columns need to be of the
same data type. With UNION, only distinct values are selected.
UNION ALL
The UNION ALL command is equal to the UNION command, except that UNION ALL selects
all values.
The difference between Union and Union all is that Union all will not eliminate duplicate rows,

instead it just pulls all rows from all tables fitting your query specifics and combines them into a
table.
What is B-Tree?
The database server uses a B-tree structure to organize index information. B-Tree generally has
following types of index pages or nodes:
root node: A root node contains node pointers to branch nodes which can be only one.
branch nodes: A branch node contains pointers to leaf nodes or other branch nodes which
can be two or more.
leaf nodes: A leaf node contains index items and horizontal pointers to other leaf nodes
which can be many.