Você está na página 1de 80

SQL Server Management Studio

The SQL Server administrator’s primary tool for interacting with the system is the SQL Server Management
Studio. Not only the Administrators, but also the end-users can use this tool to administer multiple servers,
develop databases, data backup and recovery, etc.

It can be used to manage SQL Sever 2005 systems, as well as, SQL Server 2000 and SQL Server 7
systems, but not SQL Server 6.5 or older SQL systems.

SQL Server Management Studio is made up of several component-windows, the major one’s being:

Registered Servers
It show the list of servers that you manage. You can add to it new servers or one or more existing
servers can be removed from the list. You can also use it to group common servers together into a
logical server group.

Right-click the window, and select the NEW-SERVER REGISTRATION/NEW-SERVER GROUP to


register a new SQL Server system or create a new Server Group.

Object Explorer
The Object Explorer window contains a tree view of all the database-objects in a server

To us the Object Explorer, click the Connect button on the Object-Explorer toolbar, select Database
Engine and select the name of the server and the connect authentication mode.

To work with the displayed objects, right-click the desired object and select an option from that
objects context-menu.

It allows you to easily create scripts for an entire database, or for a single database object. Expand
the Database folder in the Object Explorer and right-click a database. Select the Tasks option from
the context-menu , and then select the Generate Scripts.

Document Window
When you select an item in Object Explorer, information about that object is presented in a
document window called Summary Page. The Document window can also contain Query Editors
and Browser Windows.

Query Editor
It is the replacement for Query Analyser found in earlier versions. In the query-editor, you
can write and execute T-SQL scripts, MDX, DMX, XMLA queries or mobile queries.

Unlike the Query Analyser, the Query Editor can work either in the Connected or
Disconnected Mode. By default, it automatically connects to the server as soon as you opt
to create a new query.

To view the Query Window/Editor, press CTRL+N or Click the File Menu, New Option,
Query with Current Connection or Click the New Query button in the Standard Toolbar

Results Window
The results of the queries that are executed in the Query Editor are displayed in
the Result’s Window.

Messages Window
The message associated with the executed SQL statement is shown in the
message window

Browser Window
To view the Browser Window, click on the View menu, Web Browser option , Home. This
can be used to browse through Microsoft or other sites, as per requirement.

Solutions Explorer
It provides a Hierarchical tree view of the different projects and files in a solution. A solution
includes one or more projects, files and metadata that define the solution as a whole.

A project is a set of files that contain the connection information, query files, and other
miscellaneous and related metadata files.

The three types of projects you can have in the solutions explorer are :

1) SQL Server Scripts

They are used to group together Data Definition Language(DDL) queries which define the
objects in a database. Also used to group together related SQL Server Connections and
Transact-SQL Scripts.

2) Analysis Server Scripts


They contain MDX, DMX and XMLA scripts.
A typical use would be to have a one project containing scripts to create a Data
Warehouse and another project containing scripts to load the Data Warehouse

3) SQL Mobile Scripts


These projects are used to group together the connections and queries for a SQL Server
CE database. For a SQL Server CE Project, a connection object represents the
connection to the CE database.

Properties Window
This window allows you to view properties of files, projects, or solutions in SQL Server
Management Studio. If the properties window is not visible, then you can view it by
selecting Properties Window option from the View menu.

A Properties Dialog Box can also be invoked for the Database Objects, by right-clicking
the database object and selecting Properties from the Context-menu.
DATA TYPES
Numeric Data Types

INT Integer values between -2147483648(-2 ^31) to 2147483647(2^31 –1),


which can be stored in 4 bytes
SMALLINT Integer values between –32768(-2^15) to 32767(2^15 -1) , which can be
stored in 2 bytes
TINYINT Non-Negative integers between 0 to 255, which can be stored in 1 byte.
BIGINT Integer values between -9223372036854775808(–2^63) to
9223372036854775807 (2^63 -1), which can be stored in 8 bytes.
DECIMAL(p,[s]) Fixed-point decimal values. p is the specified precision, and s is the
decimal point digits from the right. They require 5 to 17 bytes of storage,
depending upon value of p. Maximum value of p is 38. Maximum value
of s must be equal to or lesser than that of p. That is (38,38). Default is
(18,0)
Example :Decimal(5,2) means values upto 999.99. Negative values also
allowed.
NUMBER(p,[s]) Synonym for DECIMAL
REAL Used for Floating-point values. Range of values is - 3.40E+38 to
-1.18E-38, 0 and 1.18E-38 to 3.40E+38. Thus, it stores 38
integer-digit values or 38 decimal-digit values or 38 digits in
the integer, as well as, 38 digits in the decimal part, in the
Exponential(raised to power of 10) form. Thus, maximum 38
digits before and/or after the decimal point.
Requires 4-bytes of storage.

FLOAT[(p)] Used for Floating-point values, similar to REAL. - 1.79E+308 to -2.23E-


308, 0 and 2.23E-308 to 1.79E+308. p is the precision, if p<25, then it is
stored as single precision(4 byte), and , if p>=25, then it is stored as
double precision(8 bytes)
MONEY To store monetary values. 8-byte decimal values, with the decimal value
rounded to 4 digits after the decimal point. Values range from
922,337,203,685,477.5808 to 922,337,203,685,477.5807
SMALLMONEY Same as MONEY, but 4-byte decimal values. Values range from -
214,748.3648 to 214,748.3647

String Data Types

CHAR[(n)] Fixed-length datatype to store a string, where n is the number of


characters inside the string. If n is omitted, then length string is
assumed to be 1. The maximum value of n can be 8000.
VARCHAR[(n)] String with varying length, between 1 to 8000 characters. The
number of bytes required is the length of the actual string stored
plus 2 bytes.
NCHAR[(n)] Fixed-length datatype to store UNICODE character data. Maximum
value of n is 4000. Each character stored occupies 2 bytes. Hence,
maximum 4000 characters. [Unicode is a 16-bit character
encoding method adopted by Microsoft Windows to store
characters which require 2-bytes storage space. It covers almost
all characters used in different languages like Greek, Hebrew, etc.,
written scripts, publishing characters, mathematical and technical
symbols used in computers.
Example :nchar(10) means maximum 10 characters with each
occupying 2-bytes, even if it is non-unicode. Thus , the size would
be 20 bytes of storage
NVARCHAR[(n)] Unicode-String with varying length, between 0 to 4000 characters.
Maximum value of n is 4000
TEXT[(n)] Variable-length non-Unicode data with a maximum length of 2^31-
1 (2,147,483,647) characters. Depending on the character string,
the storage size may be less than 2,147,483,647 bytes.
NTEXT[(n)] It can include single-byte and multi-byte characters. Each
character occupies 2-bytes, regardless of whether it is single-byte
or multi-byte. Variable-length Unicode data with a maximum length
of 2^30 - 1 (1,073,741,823) characters. Storage size, in bytes, is
two times the number of characters entered.

Use char when the sizes of the column data entries are consistent.
Use varchar when the sizes of the column data entries vary considerably.
Use varchar(max) when the sizes of the column data entries vary considerably, and the size might exceed
8,000 bytes. Max indicates that the maximum storage size is 2^31-1(2147483647) bytes.

BINARY Data Types

BINARY[(n)] Fixed-length bit-string of n bytes. n is between 1 to 8000


VARBINARY[(n)] Variable-length bit-string of upto n bytes. n is between 1 to 8000
IMAGE[(n)] Fixed-length bit-string of 2^31 - 1 bytes.
BIT Used for storing Boolean data type with 3 possible values : NULL,
TRUE or FALSE. Each value is stored in 1-bit.

LOB(Large Objects) Data Types

VARCHAR(MAX) They allow you to store upto 2^31 - 1 bytes of data. They are
NVARCHAR(MAX) similar in behavior to Varchar, Nvarchar and Varbinary
VARBINARY(MAX) datatypes. They allow you to store and retrieve large character
data, Unicode data, and Binary data respectively with more
efficiency then TEXT, NTEXT and IMAGE data types
respectively.

Date Data Types

DATETIME Stores values from January 1, 1753 to December 31, 9999.


Accuracy level is 300th of a second.
Values with the datetime data type are stored internally by the
Microsoft SQL Server 2005 Database Engine as two 4-byte
integers. The first 4 bytes store the number of days before or after
the base date: January 1, 1900. The base date is the system
reference date. The other 4 bytes store the time of day
represented as the number of milliseconds after midnight.

SMALLDATETIME Stores values from January 1, 1900 to June 6, 2079. Accuracy


level is upto minutes. The Database Engine stores smalldatetime
values as two 2-byte integers. The first 2 bytes store the number
of days after January 1, 1900. The other 2 bytes store the number
of minutes since midnight.
SCALAR Functions

Numeric Functions

ABS(n) Returns absolute value of a numeric value. ABS(-7.78)=7.78, ABS(7.87)=7.87


ACOS(n) Calculates arc cosine of n. n and the resulting value are of type FLOAT
ASIN(n) Calculates arc sine of n. n and the resulting value are of type FLOAT
ATAN(n) Calculates arc tangent of n. n and the resulting value are of type FLOAT
ATN2(n,m) Calculates arc tangent of n/m .n, m and the resulting value are of type FLOAT
CEILING(n) Calculates smallest integer value greater than or equal to the specified n.
Ceiling(4.88)=5, Ceiling(-4.88)= -4
COS(n) Calculates the cosine of n. n and the resulting value are of type FLOAT
COT(n) Calculates the cotangent of n. n and the resulting value are of type FLOAT
DEGREES(n) Converts radians to degrees. Degrees(PI()/2)=90.0. Degrees(0.75)=42.97
EXP(n) Calculates the value of e^n, where e=2.71828182845905. EXP(.75)=2.12,
EXP(1)=2.71828182845905
FLOOR(n) Calculates largest integer value less than or equal to the specified n. Floor(4.88)=4
LOG(n) Calculates the natural logarithm of n to the base e.
LOG10(n) Calculates the logarithm of n to the base 10
PI() Returns the value of pi(3.14)
POWER(x,y) Calculates the value of x^y. POWER(3,3)=27, POWER(121,0.5)=11
RADIANS(n) Converts degrees to radians. RADIANS(90.0)=1.57
RAND Returns a random number between 0 to 1 with a Float Data-type.
ROUND(n,p,t) Rounds the number n to the specified precision p. ROUND(5.4567,2)=5.46,
ROUND(5.4567,3)=5.457, ROUND(5.43,-1)=5, ROUND(84.56,-1)=85,
ROUND(345.4567,-1,1)=340. The third parameter(1) is used to cause a truncation
instead of rounding-off.
SIGN(n) Returns +1, -1, 0 when n is Positive, Negative or Zero respectively.
SIN(n) Calculates the Sine of n. n and the resulting value are of type FLOAT
SQRT(n) Calculates the square root of n. SQRT(100)=10
SQUARE(n) Returns the square of n
TAN(n) Calculates the Tangent of n. n and the resulting value are of type FLOAT
select abs(-5.767), abs(10.78);
select cos(1), sin(1), tan(1),cos(.1e1), sin(.1e1), tan(.1e1),cos(.1e-2), sin(.1e-2), tan(.1e-2);
select acos(1), asin(1), atan(1),acos(.1e1), asin(.1e1), atan(.1e1),acos(.1e-2), asin(.1e-2), atan(.1e-2);
select ceiling(4.88), ceiling(-4.88), ceiling(4), ceiling(-4), ceiling(4.001), ceiling(-4.0001);
select atn2(1.78,3.89), cot(.7e-9);
select floor(4.88), floor(-4.88), floor(4), floor(-4), floor(4.001), floor(-4.0001)
select degrees(0.75), degrees(pi()/2), degrees(pi()), RADIANS(42.97), RADIANS(90);
select log(4.67),log10(4.67), log(0.12),log10(0.12);
SELECT PI();
SELECT POWER(5,5),POWER(3,3),POWER(1.5,1.5), POWER(-1,-1);
sELECT RAND(), RAND(), RAND()
SELECT SQUARE(10), SQUARE(9.97), SQRT(100), SQRT(78.76556);
SELECT ROUND(10.57643,1), ROUND(10.4562,1), ROUND(10.4321,2), ROUND(10.786,0);
SELECT ROUND(10.57643,-1), ROUND(15.01,-1), ROUND(60.4562,-2), ROUND(10.4321,-2),
ROUND(1056.786,-3);
Or
SELECT cast(ROUND(10.57643,-1) as float), cast(ROUND(15.01,-1) as float), cast(ROUND(60.4562,-2) as
float), cast(ROUND(10.4321,-2) as float), cast( ROUND(1056.786,-3) as float), cast( ROUND(1556.786,-3)
as float)
To a nearer 10s, 100s or 1000s place
SELECT ROUND(10.57643,2,1),ROUND(10.57643,2,0), ROUND(10.4562,1,1),ROUND(10.4562,1,0),
ROUND(10.4321,2,1), ROUND(10.786,0,1);

DATE FUNCTIONS:

GETDATE() Returns the current system date and time


DATEPART(item, Returns the specified part item of the specified date as an integer
date)
DATENAME(item, Returns the specified part item of the specified date as a character string
date)
DATEDIFF(item, Calculates the difference between the two dates in terms of the part item specified
date1, date2)
DATEADD(item, Adds the specified number of units to the specified part item of the specified date
number, date)

SELECT GETDATE()
SELECT DATEPART(MONTH,'2007-07-26'),DATEPART(MM,'2007-07-26'), DATEPART(QQ,'2007-07-
26'),DATEPART(QUARTER,'2007-07-26'),DATEPART(YY,'2007-07-26'), DATEPART(YEAR,'2007-07-26');
SELECT DATEPART(DY,'2007-07-26'), DATEPART(DaY,'2007-07-26'),DATEPART(DD,'2007-07-26'),
DATEPART(DW,'2007-07-26'), DATEPART(WK,'2007-07-26');
SELECT DATEPART(HH,GETDATE()), DATEPART(HOUR,GETDATE()),DATEPART(MI,GETDATE()),
DATEPART(MINUTE,GETDATE()), DATEPART(SS,GETDATE()), DATEPART(SECOND,GETDATE()),
DATEPART(MS,GETDATE()), DATEPART(MILLISECOND,GETDATE())
SELECT DATENAME(MONTH, GETDATE()), DATENAME(DW,'2007-07-26'),
DATENAME(WEEKDAY,'2007-07-26')
select DATEDIFF(YEAR,'1976-07-26 23:30:48.986', GETDATE()), DATEDIFF(MM,'1976-07-26
23:30:48.986', GETDATE()), DATEDIFF(QQ,'1976-07-26 23:30:48.986', GETDATE()),
DATEDIFF(DD,'1976-07-26 23:30:48.986', GETDATE()), DATEDIFF(DY,'1976-07-26 23:30:48.986',
GETDATE()), DATEDIFF(DW,'1976-07-26 23:30:48.986', GETDATE()), DATEDIFF(WK,'1976-07-26
23:30:48.986', GETDATE()), DATEDIFF(HH,'1976-07-26 23:30:48.986', GETDATE()), DATEDIFF(MI,'1976-
07-26 23:30:48.986', GETDATE()), DATEDIFF(SS,'1976-07-26 23:30:48.986', GETDATE())
SELECT DATEADD(YEAR,3, GETDATE()), DATEADD(MM,3, GETDATE()), DATEADD(QQ,3,
GETDATE()), DATEADD(DD,3, GETDATE()), DATEADD(WK,3, GETDATE()), DATEADD(HH,3,
GETDATE()), DATEADD(MI,3, GETDATE()), DATEADD(SS,3, GETDATE())

STRING OR CHRACTER FUNCTIONS:

ASCII(character) Returns the ascii value of the specified character


CAST(a as type) Converts the specified expression/value ‘a’ to the specified data-type
CONVERT(type, a) Same as Cast, parameters given differently.
CHAR(integer) Returns the Character corresponding to the specified integer/ascii value
CHARINDEX(s1, s2) Returns the start position of string s1 in the string s2. Returns 0 if s1 not found in
s2
DIFFERENCE(s1, s2) RETURNS values 4,3,2,1,0 based on the similarity of the sounding of the two
strings. 0=completely dissimilar. 4=completely similar
LOWER(string) Converts the specified string to the lower case
UPPER(string) Converts the specified string to the upper case
LTRIM(string) Returns the specified string after trimming the blank spaces to the left
RTRIM(string) Returns the specified string after trimming the blank spaces to the right
LEFT(string, n) Returns the specified number of characters from the left of the given string
RIGHT(string, n) Returns the specified number of characters from the right of the given string
SUBSTR(string, a,n) Returns from the position ‘a’ from the specified string specified n number of
characters
REPLICATE(string ,n) Replicates the specified string specified number of times
REVERSE(string) Returns the reverse of the specified string
SPACE(n) Returns a string containing specified number of blank spaces
SOUNDEX(string) Returns a 4-charactered SOUNDEX code for the specified string which can be
used to find out the similarity between strings using the “DIFFERENCE”
FUNCTION
STUFF(s1, a, n,s2) Replaces string s1 with n number of characters from the position a with the
specified string s2
STR(f,l,d) Converts a integer or float and presents it as a string of l characters. The d
specifies number of decimals to be displayed from the float value
NEWID() Returns a unique 16-byte binary string which can be used to store values in a
column of type UNIQUEIDENTIFIER

SELECT ASCII('A'), CAST(7 AS FLOAT),CHAR(81), CHAR(567);


select 'Age is '+cast(10 as char(2))
Select rollno, ‘Age is :’ +cast(age as char(12)) from student
Select rollno, ‘Age is :’ +convert(char(12), age) from student
SELECT UPPER('i am a boy'), lower('LEARN SQL'), reverse('i am a boy'), replicate('he', 9);
select ltrim(' i am a boy '), rtrim(' i am a boy '), right('Hello',3), left('hello',3),
substring('hello', 2,3)
select space(10), str(10), str(10.12345,2), str(10.12345,5),str(10.12345,3), str(10.12345,1),
str(10.12345,5,2)
select 'abc'+space(5)+'hh', stuff('hello',1,3,'abc'), stuff('hello',1,3,'ab'), stuff('hello',1,3,'a') ,
stuff('hello',1,3,'abcde')
select soundex('hemant'), soundex('himant'),soundex('heman'), soundex('arun'), soundex('aroon'),
soundex('arunam')
select difference('hemant','hemant'), difference('hemant','himant'), difference('hemant','heman'),
difference('hemant','he'), difference('hemant','arun'), difference('tarun','varun')
select charindex('man','hemant'), charindex( 'Man','hemant'), charindex( 'mano','hemant')
select newid(), newid(), newid(), newid()
SYSTEM FUNCTIONS :

HOST_ID() Returns the identifier of the host system


HOST_NAME() Returns the name of the host
DB_ID(db_name) Returns the identifier of the specified database
DB_NAME(db_id) Returns the name of the Database whose identifier db_id is passed as
parameter
USER_ID(user_name) Returns the identifier of the user_name
USER_NAME(id) Returns the name of the user whose id is passed as parameter
CURRENT_TIMESTAMP Returns the Current Date ad Time
CURENT_USER Returns the name of the current user
SYSTEM_USER Returns the login ID of the current user
USER Same as Current_user
SUSER_SID(name) Returns the Security Identification Number(SID) of the user whose login
name is passed
SUSER_SNAME(sid) Returns the login name of the user whose SID is passed as parameter
OBJECT_ID(objectname) Returns the identifier of the objectname
OBJECT_NAME(objid) Returns the name of the object whose objid is passed
DATALENGTH(z) Returns the length in bytes of the expression z
ISNULL(expr, value) Returns the specified value, if the given expr is null, else returns expr
NULLIF(exp1, exp2) Returns NULL if exp1 and exp2 are equal
COALESCE(C1, C2, Returns the first non-null value from the expressions c1, c2, c3 and c4
C3,C4)
DATABASEPROPERTYEX( Returns the current setting for the specified database option/property of the
Database, property) specified database
COL_LENGTH(obj,col) Returns the length of the column col belonging to the database object
obj(table/view)
COL_NAME(oid,sid) Returns the name of the column belonging to the object oid with the identifier
sid

select host_id(), host_name()


select db_id('school'), db_id('master'), db_id('model'), db_id('tempdb'), db_id('northwind'), db_id('pubs'),
db_id('msdb')
select db_name(1), db_name(2), db_name(3), db_name(4), db_name(5), db_name(6), db_name(7)
select user_name(1), user_name(2), user_name(3), user_name(4), user_name(5)
select user_id('dbo'), user_id('guest'), user_id('ooooo')
select current_timestamp, getdate(), current_user, system_user, user
select suser_sid('ooooo'), suser_sid('HEMANT\Administrator'),
suser_sname(0xA27E4C6338D2F649B530E1E3FD0916FE),
suser_sname(0x0105000000000005150000005729024C32621F2A16C0EA32F4010000)
select object_id('table1'), object_name(389576426)
select datalength(shipname), datalength(freight) from orders
select isnull(region,'mumbai'), nullif(region, 'WA') from employees
select COALESCE(C1, C2, C3,C4) FROM TABLE1;
select databasepropertyex('northwind', 'status'), databasepropertyex('northwind', 'updateability')
SELECT COL_LENGTH('employee','empname'), COL_LENGTH('employee','empno')
SELECT COL_NAME(OBJECT_ID('Employee'), 1), COL_NAME(OBJECT_ID('Employee'), 2),
COL_NAME(OBJECT_ID('Employee'), 3), COL_NAME(OBJECT_ID('Employee'), 4),
COL_NAME(OBJECT_ID('Employee'), 5)

GLOBAL VARIABLES :

@@SERVERNAME Returns the name of the server


@@CONNECTIONS Returns the number of login attempts since starting the SQL Server
@@VERSION Returns the version of SQL Software
@@SPID Returns the identifier of the server process
@@TOTAL_READ Returns the total number of read operations since SQL Server was
first started
@@TOTAL_WRITE Returns the total number of write operations since SQL Server was
first started
@@IDLE Returns the time in miliiseconds that SQL server has been idle since it
was first started
@@CPU_BUSY Returns the total CPU time in milliseconds used since starting SQL
Server
@@MAX_CONNECTIONS Returns the maximum number of connections to SQL Server
@@TEXTSIZE Returns the current maximum number of bytes for text/image objects
which can be returned by a SELECT statement
@@LANGUAGE Returns the name of the language that is currently used by SQL
Server
@@LANGID Returns the identifier of the language that is currently used by SQL
Server
@@IO_BUSY Returns the used I/O time in milliseconds since starting the SQL
Server

SELECT @@SERVERNAME , @@CONNECTIONS, @@VERSION, @@SPID, @@TOTAL_READ,


@@TOTAL_WRITE, @@IDLE, @@CPU_BUSY, @@TEXTSIZE, @@MAX_CONNECTIONS,
@@LANGUAGE, @@LANGID, @@IO_BUSY

INSERT Command

create table table1(c1 numeric default 10, c2 varchar(10), c3 char(10) default 'xyz', c4 numeric(5,2))

insert into table1 values(100, 'Tom', 'Potter', 56.89)

insert table1 values(101, 'Harry', 'Potter', 89)

insert into table1(c1,c3) values(102, 'Potter')

insert into table1(c2,c4) values('Hary', 56.76)

insert into table1 values(103, 'Tom', default, 100)

insert into table1 values(109, 'Tom', default, 100+800)


insert into table1 values(default, 'Jerome', default, 200)

insert into table1(c2,c4) values('Brian', 500)

insert into table1 default values

This form of INSERT command inserts one row (or parts of it) into the specified Table or Simple View
subject to non-violation of constraints at the table-level. If a column is of datatype TIMESTAMP or has the
IDENTITY property, a value, which is automatically calculated by the system, is inserted

create table table2(c1 numeric, c2 varchar(10), c3 char(10), c4 numeric(5,2))

insert into table2(c1,c2) select c1, c2 from table1 where c1 between 102 and 104

insert into table2 select * from table1 where c1 between 102 and 104

UPDATE

Update table_name|view_name
Set col1=value, col2=value, …
From table_name1|view_name1, table_name2|view_name2
WHERE condition(s)

Update emp set sal=20000


As the where cluase is ommiteed all the rows are updated
Update emp set sal=20000 where deptno=10 and sal = 10000

If Jones is ill and on leave then the projid column for all his corresponding rows in the project table shoud be
set to NULL
Update project set projid=null where empno = (select empno from emp where empname=’jones’)

This can also be achieved using the FROM cluase of Update statement as follows :
Update project set projid=nul from emp, project where emp.empname=’jones’ and
project.empno=emp.empno

Update with case


Update emp set salary=CASE
When salary>=0 and salary<10000 then salary*1.2
When salary>=10000 and salary<20000 then salary*1.1
when salary is null then 1000
Else salary*1.5
End

Update emp set salary=CASE


When deptno=500 then salary*1.2
When deptno=510 then salary*1.1
when deptno is null then 1000
Else salary*1.5
End

DELETE

Delete table_name|view_name
FROM table_name1|view_name1, table_name1|view_name1,…
WHERE predicate

Delete table_name|view_name
WHERE condition(s)

delete orders
or
delete from orders
As WHERE cluase is ommitted all the rows are deleted

Delete from emp where sal>10000

If Jones is ill and on leave then the all his corresponding rows in the project table shoud be deleted
Delete from project where empno = (select empno from emp where empname=’jones’)

This can also be achieved using the FROM clause as follows :


delete project from emp, project where emp.empname=’jones’ and project.empno=emp.empno

TRUNCATE TABLE table_name normally provides a faster execution version of the delete statement
without a where clause. The Truncate has no WHERE clause. It works faster as it drops the contents of the
table page by page whereas delete does it row by row. Truncate does not place the modifications of a table
into the transaction log.

TRUNCATE TABLE Emp

Database and Files

All databases have one ‘primary’ data-file that has, by default, the same name(logical) as the corresponding
database. The physical name of this file is, by default, suffixed with the extension ‘.mdf’. Optionally, there
can be one or more secondary data files whose physical names are suffixed by the extension ‘.ndf’, by
default. Similarly, each database has one primary log-file, whose default name is dbname_log. Optionally,
there can be additional log files also. All the log files are suffixed by the extension ‘.ldf’. All the suffixes are
recommended extensions, and can be modified if required.

All the data files that are used to store a database’s data an be grouped to build filegroups. With filegropus,
you can locate different tables or indices on a specific file (or set of files).

SQL Sever supports two types of filegroups :

1) Primary filegroup which is impliciltly created by the system during the creation of the database. All
system tables are always in the primary filegroup, while user-defined tables can belong either to the primary
filegroup or to any user-defined filegroup.

2) User-defined filegroup must be explicitly created by and subsequently attached to the


corresponding database using necessary commands.

By default, the Primary filegroup is the default filegroup. You may change the default filegroup to any other
user-defined filegroup, if required. The default filegroup indicates the filegroup to be used when no filegroup
is specified as a part of table or index creation.

create database sample

Creates a database named ‘sample’ with default specifications. SQL Server creates two files for this
database by default. The logical name of the data file is ‘sample’ and it’s original size is 2MB. Similarly, the
logical name of the transaction log is ‘sample_log’, and it’s original size is 1MB.

The physical data file is ‘sample.mdf’ and it is by default created in the folder ‘C:\Program Files\Microsoft
SQL Server\MSSQL.1\MSSQL\DATA’. The physical log file is ‘sample_log.ldf’ and it is by default created in
the folder ‘C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA’.

create database projects


on (name=projects_dat,
filename='d:\projects.mdf',
size=10,
maxsize=100,
filegrowth=5)

creates a database named ‘projects’ with the given specifications for the data file. Uses default
specifications for the log file.

Logical names and folders could be specified thru the GUI method of creating the database, but physical
names coluld not be specified. But, thru the command method, you could even specify the physical names
also.

drop database projects


drops the database named ‘projects’.

create database projects


on (name=projects_dat,
filename='d:\projects.mdf',
size=10,
maxsize=100,
filegrowth=5)
log on
(name=projects_log,
filename='d:\projects.ldf',
size=40,
maxsize=100,
filegrowth=10)
Creates a database named ‘projects’. As the PRIMARY option is not specified, the first file is assumed as
primary-file. It has the logical name ‘projects_dat’ and is stored in the physical file ‘projects.mdf’ in the
specified folder ‘d:’. The original file-size is 10MB. Additional portions of 5MB of disk-storage are allocated
by the system, if needed.(KB, TB, MB suffixes can be used to specify kilobytes, terabytes or megabytes
respectively. The default is MB. Here the maxsize for the file is 100MB. If the maxsize is not specified or is
set to unlimited, the file will grow until the disk is full.

Similarly, for the single transaction-log file, options may be specified.

create database projects


on (name=projects_dat1,
filename='d:\projects1.mdf',
size=10,
maxsize=100,
filegrowth=5),
(name=projects_dat2,
filename='d:\projects2.mdf',
size=10,
maxsize=100,
filegrowth=5)
log on
(name=projects_log,
filename='d:\projects.ldf',
size=40,
maxsize=100,
filegrowth=10)
Here, we have specified more than one data file. But, the first data-file is the only PRIMARY data-file, and
the second data-file is a SECONDARY data-file, though it has the extension (.mdf), as extensions are just
recommended by SS, they have nothing to do with the type of file. Here both the data-files will belong to the
PRIMARY File-group, as there is no other Filegroup available so far. But the Primary data-file has to belong
to the Primary filegroup.

create database projects


on (name=projects_dat1,
filename='d:\projects1.mdf',
size=10,
maxsize=100,
filegrowth=5),
(name=projects_dat2,
filename='d:\projects2.mdf',
size=5,
maxsize=10,
filegrowth=2)
log on
(name=projects_log1,
filename='d:\projects1.ldf',
size=20,
maxsize=100,
filegrowth=10),
(name=projects_log2,
filename='d:\projects2.ldf',
size=10,
maxsize=10,
filegrowth=2)
Here, we have specified more than one data file and more tan one log file.
Alter database projects
Add file
(name=projects_dat3,
filename='d:\projects3.mdf',
size=10,
maxsize=100,
filegrowth=5),
(name=projects_dat4,
filename='d:\projects4.mdf',
size=1,
maxsize=10,
filegrowth=2)

Altering the database to add more data files.

Alter database projects


add log file
(name=projects_log3,
filename='d:\projects3.ldf',
size=40,
maxsize=100,
filegrowth=10),
(name=projects_log4,
filename='d:\projects4.ldf',
size=4,
maxsize=10,
filegrowth=2)

Altering the database to add more log files.

Alter database projects add filegroup fg1


Alter database projects add filegroup fg2
Altering a database to add file groups

Alter database projects


Add file
( name=projects_dat8,
filename='d:\projects8.mdf',
size=10,
maxsize=100,
filegrowth=5) to filegroup fg1
altering a a database to add a datafile to a specific filegroup

Alter database projects


Add file
( name=projects_dat10,
filename='d:\projects10.mdf',
size=10,
maxsize=100,
filegrowth=5),
(name=projects_dat11,
filename='d:\projects11.mdf',
size=1,
maxsize=10,
filegrowth=2) to filegroup fg2
altering a a database to add more than one datafile to a specific filegroup. Here both files get added to the
same filegroup. Data file(s) can be added to only one filegroup in one command.
Alter database projects remove file projects_dat5
To remove a datafile

alter database projects remove file projects_log2


To remove a log file

alter database projects remove file projects_dat1


Error, since the very first data file is the Primary data file and it cannot be removed.
Also, a datafile cannot be removed if it is not empty(that is it contains some data)

alter database projects remove file projects_log1


Error, since the very first log file is the Primary log file and it cannot be removed.

Alter database projects remove filegroup fg1


To remove a filegroup. A filegroup cannot be removed untill all it’s files have been removed. Thus, a
filegroup has to empty to remove it.

alter database projects modify file


(name=projects_dat7, newname =projetcs_dat77)
To change the name of a datafile

alter database projects modify file


(name=projects_dat10, newname =projetcs_log100, size=15, maxsize=101, filegrowth=7)
To change name and some other specifications of the data file

alter database projects modify file


(name=projects_log2, newname =projetcs_log22)
To change the name of a logfile

alter database projects modify file


(name=projects_log3, newname =projetcs_log300, size=16, maxsize=116, filegrowth=6)
To change name and some other specifications of the log file

create table table1( c1 numeric(5,2), c2 varchar(10)) on fg1


to create a table in a specific filegroup.

create table table2( c1 numeric(5,2), c2 varchar(10)) on "default"


to create a table in the default filegroup. Even if “default” is not specified, a table by default gets created in
the default filegroup.

Constraints:
Usually created at the same time as the table creation.
Can also be added to a table after the table creation
Can also be temporarily disabled and enabled.
Can be permanently dropped
Constraints can be of Column-level(defined with the definition of the columns) or table-level(defined after
the definition of all the columns, i.e., not with the definition of the columns)

Not Null
NULL values not allowed
Duplicate allowed
Any number of NOT NULL in a table
It is a column level constraint
No composite NOT NULL exists

create table table1( empno numeric(5), empname varchar(10) not null)

create table table2( empno numeric(5), empname varchar(10) not null default 'abc')
insert into table2 values(1,'tom');
insert into table2(empno) values(2);

create table table3(empno numeric, empname varchar(10) default ‘abc’)


insert into table3 values(1,'Tom')
insert into table3(empno) values(2)
insert into table3 values(3, null)
insert into table3 values(4,default )

create table table4(empno numeric, empname varchar(10))


alter table table4 alter column empname varchar(10) not null

Unique
Duplicates not allowed
NULL values allowed.
Composite Unique key allowed
However, no two rows can have NULL values. This applies to both individual, as well as, composite unique
keys.

create table table1( empno numeric(5) unique, empname varchar(10) not null default 'abc')
or
create table table1( empno numeric(5) constraint mycon1 unique, empname varchar(10) not null default
'abc')
In both the cases, it creates a constraint with a system-specified name. In 1 st case also creates a
unique,non-clustered index with a system-specified name. In the 2nd case creates unique,non-clustered
index with the name mycon1.

create table table2(empno numeric(5), empname varchar(10), unique(empno))


Here, it does not create a constraint as an object as such, but creates a unique,non-clustered index with a
system-specified name
Or
create table table2(empno numeric(5), empname varchar(10), constraint mycon unique(empno))
Here, it does not create a constraint as an object as such, but creates a unique,non-clustered index with the
name mycon.

create table student(std numeric(1), div char(1), rollno numeric(2), studname varchar(10), unique(std,div,
rollno))
To create a composite Unique key. Here, it does not create a constraint as an object as such, but creates a
unique,non-clustered index with a system-specified name

Or

create table student(std numeric(1), div char(1), rollno numeric(2), studname varchar(10), constraint sdr
unique(std,div, rollno))
To create a composite Unique key. Here, it does not create a constraint as an object as such, but creates a
unique,non-clustered index with the name sdr.
create table table1(c1 numeric, c2 char(10))
If size is not specofied for numeric column, it takes the maximum size as (18,0).

alter table table1 add unique(c1)


To add a unique constraint with the alter table command.
To drop the constraint :
alter table table1 drop constraint UQ__table1__1A14E395
Here, since constraint is not created as an object, you will have to drop the constraint with the name of the
uniqe, non-clustered index which was created and given a system-specified name. Also, there are two
underscores in the index name.
Or

alter table table1 add constraint abc unique(c1)


to drop the constraint :
alter table table1 drop constraint abc
Here, you will have to drop the constraint with the name of the uniqe, non-clustered index which was ‘abc’

To disable a constraint :
alter table table1 nocheck constraint abc

To re-enable a constraint :
alter table table1 check constraint abc

create table table4(empno numeric(3) not null unique, empname varchar(10))


or
create table table4(empno numeric(3) unique not null, empname varchar(10))
more than one constraint allowed on a single column

create table table4(empno numeric(3) constraint mycons unique not null, empname varchar(10))
Here, for the unique key, no constraint is created as such, but a unique, nonclustered index with the
specified name is created.

Create table table5(empno numeric(3) constraint mycon2 unique clustered, empname char(10))
Here, for the unique key, no constraint is created as such, but a unique, clustered index with the specified
name is created.
or
Create table table5(empno numeric(3) constraint mycon2 unique clustered not null , empname char(10))

By default, a unique key constraint creates a non-clustered index on the specified column(s). To create a
clustered inndex, it is needed to specify the keyword clustered.

Primary Key
Key that uniquely identifies each row of a table
Duplicate values not allowed
Null values not allowed
Recommended for every table
Can have a Composite PK
Null values not allowed for any column of the Composite PK.
Only one PK/Composite PK per table
PK can be defined at column level. CPK is always defined at table-level.

create table table2(c1 numeric primary key, c2 numeric)


creates a clustered index on the specified column with a system-specified name. Only one clustered index
allowed per table. By default, a clustered index is created when a Primary key is specified for the column(s)
of a table.
or
create table table2(c1 numeric constraint abc primary key, c2 numeric)
creates a clustered index on the specified column with the specified name

create table table1(c1 numeric(3) unique clustered, c2 numeric(3) primary key)


creates a clustered index on ciolumn c1 as the option clustered is specified with the unique key constraint.
Hence, a clustered index is also created on column c1. Therefore, the primary key constraint on column c2
will create a unique, non-clustered index as there can be only one clustered index per table
or
create table table1(c1 numeric(3) constraint a unique clustered, c2 numeric(3) constraint b primary key)
Here, again an index ‘a’ of type clustered and an index ‘b’ of type unique,non-clustered will be created as the
constraint names are specified.
Or
create table table3(c1 numeric primary key, c2 numeric unique clustered)
again the index on c1 will be of type non-clustered and the index on c2 will be of type clustered.

Create table emp(empno numeric(3) constraint xyz primary key nonclustered, empname varchar(20))
Here, primary key constraint is created on column empno, but as the option nonclustered is specified, the
index xyz which is created will be of type unique,nonclustered.

Create table stud(std numeric(2), div char(1), rollno numeric(3), studname varchar(25), primary
key(std,div,rollno))
Or
Create table stud(std numeric(2), div char(1), rollno numeric(3), studname varchar(25), constraint abcd
primary key(std,div,rollno))
To create a composite primary key on the specified columns. In the 1 st case the index is created with a
system-specified name, and in the 2nd case the index is created with the specified name. In both the cases,
the index is of type unique,clustered.
Or
Create table stud(std numeric(2), div char(1), rollno numeric(3), studname varchar(25), primary key
nonclustered(std,div,rollno))
To create a composite primary key on the specified columns which will create a unique, nonclustered index
with a system-specified name.

Create table table1(empno numeric(3) , empname char(10))


alter table table1 add primary key(empno)
Error : Cannot define PRIMARY KEY constraint on nullable column in table 'table1'.
Here, the alter table will not work since the column empno is of type nullable(allowing null values), and SQL
SERVER cannot create a PrimaryKey constraint on a column that is nullable. Hence
Create table table1(empno numeric(3) , empname char(10))
alter table table1 alter column empno numeric(3) not null
First modify the column empno to NOT NULL and then
alter table table1 add primary key(empno)

Create table table2(empno numeric(3) not null , empname char(10))


alter table table2 add primary key(empno)
Here, there will be no such problem.

Create table table3(empno numeric(3) , empname char(10))


alter table table1 alter column empno numeric(3) primary key
ERROR : This again gives an error, since SQL SERVER does not allow to alter a columns definition with
addition of constraints

Create table stud(std numeric(2), div char(1), rollno numeric(3), studname varchar(25))
alter table stud add primary key(std,div,rollno)
Error : Cannot define PRIMARY KEY constraint on nullable column in table 'stud'.

Foreign Key
create table dept(deptno numeric(3) primary key, deptname varchar(10))

create table emp(empno numeric(5), empname varchar(20), deptno numeric(3) references dept(deptno))

Foreign key refering to another column of another table where the referenced column is Primary key
create table dept(deptno numeric(3) unique, deptname varchar(10))

create table emp(empno numeric(5), empname varchar(20), deptno numeric(3) references dept(deptno))
Foreign key refering to another column of another table where the referenced column is Unique key

The coulmn to which the foreign key column refers must be Primary key or Unique key.

drop table dept


error : cannot drop table dept, since it is referenced by table emp

create table emp(empno numeric(3) primary key, empname varchar(10), mgrno numeric(3) references
emp(empno))
Foreign key refering to another column of the same table where the referenced column is Primary key or
Unique key

create table dept(deptno numeric(3) unique, deptname varchar(10))

create table emp(empno numeric(5) not null, empname varchar(20), deptno numeric(3))

alter table emp add foreign key(deptno) references dept(deptno), primary key(empno)

Foreign key created after table creation through the alter table command. Also, addition of more than one
constraint through a single alter command is allowed

create table table1(c1 numeric(3) unique, c2 numeric(4) references table1(c1))


create table table1(c1 numeric(3) unique, c2 numeric(2) references table1(c1))
create table table1(c1 numeric(3) unique, c2 char(3) references table1(c1))
create table table1(c1 numeric(3) unique, c2 varchar(3) references table1(c1))
create table table1(c1 char(3) unique, c2 varchar(3) references table1(c1))
Error : All the above commands will fail, since the datatype, as well as, the datasize of the Referencing
column and Referenced column must be the same.

create table table1(c1 numeric(3), c2 numeric(3), c3 numeric(3), c4 numeric(3), unique(c1,c2), foreign


key(c3,c4) references table1(c1,c2))
composite foreign key on columns (c3, c4) refering to a composite unique key(c1,c2) of the same table.

create table table1(c1 char(3), c2 numeric(3), c3 char(3), c4 numeric(3), unique(c1,c2), foreign key(c3,c4)
references table1(c1,c2))
Composite forein key

create table table1(c1 char(2), c2 numeric(3), c3 char(3), c4 numeric(3), unique(c1,c2), foreign key(c3,c4)
references table1(c1,c2))
create table table1(c1 numeric(3), c2 numeric(3), c3 numeric(3), c4 numeric(4), unique(c1,c2), foreign
key(c3,c4) references table1(c1,c2))
create table table1(c1 numeric(3), c2 numeric(3), c3 numeric(3), c4 char(3), unique(c1,c2), foreign
key(c3,c4) references table1(c1,c2))
error : since the dataytype, as well as, datasize of the first referencing coulmn must be the same as that of
the first referenced column and the dataytype, as well as, datasize of the second referencing coulmn must
be the same as that of the second referenced column

create table table1(c numeric(3), c1 numeric(3), c2 numeric(3), c3 numeric(3), c4 numeric(3), unique(c1,c2),


foreign key(c3,c4) references table1(c1,c2))
insert into table1(c, c1, c2) values(100, 1,1)
insert into table1(c, c1, c2) values(101, 1,2)
insert into table1(c,c1, c2) values(102, 1,3)
insert into table1(c,c1, c2) values(103, 2,1)
insert into table1(c,c1, c2) values(104, 2,2)
insert into table1(c,c1, c2) values(105, 2,4)
insert into table1(c,c1, c2) values(106, 3,2)
insert into table1(c,c1, c2) values(107, 3,NULL)
insert into table1(c,c1, c2) values(108, 6,null)
insert into table1(c,c1, c2) values(109, null,8)

update table1 set c3=3, c4=2 where c=101


allowed since (3,2) as a values for (c3,c4) is available in (c1,c2)

update table1 set c3=2, c4=3 where c=102


not allowed since (2,3) as a values for (c3,c4) is NOT available in (c1,c2)

update table1 set c3=2, c4=null where c=103


allowed

update table1 set c3=3, c4=null where c=104


allowed

update table1 set c3=null, c4=3 where c=103


allowed

update table1 set c3=null, c4=1 where c=104


allowed

update table1 set c3=null, c4=6 where c=105


allowed

update table1 set c3=8, c4=null where c=105


allowed
Thus, a value in (c3,c4) will look for an existing combined values of (c1,c2)

update table1 set c3=8, c4=6 where c=105


not allowed

update table1 set c3=6, c4=8 where c=106


not allowed

create table dept(deptno numeric(3) primary key, deptname varchar(10))


create table emp(empno numeric(3) primary key, empname varchar(10), deptno numeric(3) references
dept(deptno))
Here, you cannot update or delete records from the parent table who have 1 or more child records. You may
update or delete only those records from the parent table who currently do not have any child records.
Or
create table dept(deptno numeric(3) primary key, deptname varchar(10))

create table emp(empno numeric(3) primary key, empname varchar(10), deptno numeric(3) references
dept(deptno) on update no action on delete no action)
It is as good as telling SQL Server not to take any alternative course of action and hence just do not allow to
update or delete records from the parent table who have 1 or more child records.

create table dept(deptno numeric(3) primary key, deptname varchar(10))


create table emp(empno numeric(3) primary key, empname varchar(10), deptno numeric(3) references
dept(deptno) on delete cascade)
Records of child table are automatically deleted when corresponding record(s) from parent table are deleted.
But updation of parent key value having child records not allowed

create table dept(deptno numeric(3) primary key, deptname varchar(10))


create table emp(empno numeric(3) primary key, empname varchar(10), deptno numeric(3) references
dept(deptno) on update cascade)
Foreign key values in the child table are automatically updated to the values to which their corresponding
parent records are updated to. But, deletion of parent records having child records not allowed.

create table dept(deptno numeric(3) primary key, deptname varchar(10))


create table emp(empno numeric(3) primary key, empname varchar(10), deptno numeric(3) references
dept(deptno) on delete cascade on update cascade)
Records of child table are automatically deleted when corresponding record(s) from parent table are deleted.
Also, Foreign key values in the child table are automatically updated to the values to which their
corresponding parent records are updated to.

create table dept(deptno numeric(3) primary key, deptname varchar(10))


create table emp(empno numeric(3) primary key, empname varchar(10), deptno numeric(3) references
dept(deptno) on delete set null)
Foreign key values in the child table are automatically updated to null when the corresponding parent
record(s) are deleted. Updates to parent records having child records not allowed

create table dept(deptno numeric(3) primary key, deptname varchar(10))


create table emp(empno numeric(3) primary key, empname varchar(10), deptno numeric(3) references
dept(deptno) on delete set null on update set null)
Foreign key values in the child table are automatically updated to null when the corresponding parent
record(s) are deleted. Also, Foreign key values in the child table are automatically updated to null when the
corresponding parent record(s) referenced columns are updated

create table dept(deptno numeric(3) primary key, deptname varchar(10))


create table emp(empno numeric(3) primary key, empname varchar(10), deptno numeric(3) references
dept(deptno) on delete cascade on update set null)
Records of child table are automatically deleted when corresponding record(s) from parent table are deleted.
Also, Foreign key values in the child table are automatically updated to null when the corresponding parent
record(s) referenced columns are updated

create table dept(deptno numeric(3), deptname varchar(10))

create table emp(empno numeric(3) primary key, empname varchar(10), deptno numeric(3) default 1
references dept(deptno) on delete set default on update set default )

Foreign key values are set to the default value 1 when either the corresponding referenced column is
updated or the corresponding parent record is deleted. But, there must be a record in the parent table with
deptno=1, or else the parent updations and deletions will fail.

CHECK
create table table1(c1 numeric(3) check (c1 in(1,2,3)), c2 char check (c2 ='a'))
Column c1 will allow only (1,2,3) as legitimate values, and column c2 will only allow ‘a’ as a value. But,
NULL values are allowed in both cases, unless otherwise also specified as NOT NULL as follows :

create table table1(c1 numeric(3) not null check (c1 in(1,2,3)), c2 char not null check (c2 ='a'))

create table table1(c1 numeric(3) , c2 char(3))


alter table table1 add constraint con1 check (c1 in (1,2,3)), constraint con2 check (c2 in ('a','b', 'c'))
The alter table can be used to add check constraint after table creation

RETRIEVAL :

Select * from emp


--Will display all the columns from the table emp in the order in which they have been defined in the table.
As ther is no where clause mentioned, all the rows from the table emp are retrieved
Select empno, empname from emp;
--Will display the specific columns from the table emp in the order in which they have been mentioned in the
Select list of the Select command. As ther is no where clause mentioned, all the rows from the table emp are
retrieved
--The operation of specifying the columns in the SELECT LIST of a Select command is called
PROJECTION.

Select empno employeenumber, empname as employeename , empno 'employee number', empname as


"Employees Name" from emp;
--Aliases can be used for column names so that the aliases as used as the Column-headings to display
retrieved data. Alias names must be single words or else make use of single/double quotes.

select distinct deptno from emp;


-- To display only the distinct values for the specified column. That is it will display all the different values for
the specified column(Even NULL is considered as a Distinct value, if there are one or more records with null
values for the specified column)

select deptno from emp


select all deptno from emp
--If the DISTINCT clause is not given, the default is treated as ALL. Hence both the above have the same
meaning and output.

select distinct deptno, distinct empname from emp;


--Error: Since distinct keyword can be used with only one specific column

select empname, distinct deptno from emp;


--Error: since distinct keyword can be used with the first column in the select list

select distinct deptno, empname from emp;


--Here distinct looses it meaning, since the default ALL becomes applicable to empname, and hence all
values(that is values for all records) for the column empname are displayed, and alongwith them their
corresponding values for depto are also displayed. Thus distinct with a column looses it's maening when
more than one column is involved.

--The Where clause is used to define one or more conditions to limit the retrieval of only those rows that
satisfy the given criteria. The net result of the where clause ia a TRUE or FALSE that is tested for each row
to be returned. If TRUE then the row is returned, if FALSE, the rows is not returned.
select * from emp where empno>=3
select * from emp where empname='jairaj'

select * from emp where empname='jairaj' and empno>=3


select * from emp where empname='jairaj' or empno>=3
--More than one condition in the where clause can be specified and they have to be separated by the
Boolean operators : AND or OR. The WHERE cluase may include any number of the same or different
Boolean operators : NOT, AND, OR. NOT has the highest priority, followed by AND and then OR. Care
must ne taken of these priorities or else you might get logically wrong or unexpected results.

Select * from emp where empno=25 and empname='jairaj' or empname='saloni' and deptno=1
--Here the system evaluates both the AND operators first(from left to right), and then the OR operator is
evaluated

Select * from emp where ((empno=25 and empname='jairaj') or empname='saloni') and deptno=1
--Use of parenthesis changes the entire operation execution with all the expressions within parenthesis
being executed first in the sequence from left to right. The use of parenthesis is highly recommended, even
though it is not compulsory. It also improves readibility of the SELECT statement and possible errors are
also avoided.

Select * from emp where NOT deptno=20


--Use of Boolean operator NOT

Comparison Operators are :


= Equal to
!=(<>) Not Equal to
< Lesser than
> Greater than
<= Lesser than or Equal
>= Greater than or Equal
!> Not Greater than
!< Not lesser than

IN Operator
The IN operator can be used instead of a series of conditions separated by OR on a single column.
Select * from emp where empno IN (100,105,110)

To find out rows that are not equal to any of the listed values, use the NOT IN operator
Select * from emp where empno NOT IN (100,105,110)

BETWEEN Operator
To specify a range which determines the lower and upper bounds of qualifying values.
Select * from emp where sal BETWEEN 10000 and 20000
The Between operator searches for all the values in the range inclusively.

To find out the rows where the specified column does not fall within the specified range, use the NOT
BETWEEN operator
Select * from emp where sal NOT BETWEEN 10000 and 20000

IS NULL
NULL values cannot be directly compared using the comparison operator =. Comparison with NULL using =
operator will evaluate to false and return no rows. Comparison with NULL is done with the operator IS NULL
Select * from emp where deptno is null

To find rows that have got non-null values for a specific column, make use of IS NOT NULL
Select * from emp where deptno is not null
Or
Select * from emp where not deptno is null

LIKE operator
LIKE Operator is used for searching strings that follow a particular pattern. There are two patern matching
Operators
% represents 0 to n characters. _ represents only 1 character
select * from student where sname like 'd%'
select * from student where sname like '__m%'
select * from student where sname like '__m'
select * from student where sname like '__m__'

select * from student where sname like '[jrmv]%'


First chracter should be a j, r, m or v and followed by anything

select * from student where sname like '[jrmv]___'


4-charactered sname where First chracter should be a j, r, m or v

select * from student where sname like '_[a-j]%'


atleast 2-chractered sname where second character between a to j

select * from student where sname like '[a-jm-q]%'


n-charactered sname where first character is between a to j or m to q

select * from student where sname like '[a-jms]%'


n-charactered sname where first character is between a to j or m or s

select * from student where sname like '[^j]%'


n-charactered sname which do not begin with j
select * from student where sname like '[^j-ks]%'
n-charactered sname which do not begin with j to k or s

select * from student where sname like 'V/_%' escape '/'


to search sname where second character is an '_'. To search a string containing a wild card character use
the escape clause to specify the escape character and precede the _ or % with that escape character

select * from student where sname like 'V/____//%' escape '/'


To search sname where second character is an '_' and 6th character is a '/'. The escape character can also
be preceded by itself to search a string containing the escape character itself

GROUP or AGGREGATE Functions :


Group or Aggregate functions operate on a set of values(or rows) and return one value which is the
summarized value for that set of values. All group functions operate on a single argument that can be a
column or an expression. All Group functions ignore NULL values. Some of the Group functions SUM, AVG,
MAX, MIN, COUNT, VAR,STDEV, etc.

select sum(english), max(maths), min(maths), avg(english) from studmarks


will display the sum of english, maximum of maths, minimum of maths, average of english across all the
records in the table.

select sum(english), max(maths), min(maths), avg(english) from studmarks where test='t1'


will display the sum of english, maximum of maths, minimum of maths, average of english across all the
records in the table who satisfy the given condition(s)

select avg(isnull(maths,0)) from studmarks


isnull function allows us to make SQL consider a specific value in place of null values whenever null values
are encountered.

select sum(deptno), count(*), sum(deptno)/count(*), avg(deptno) from emp

select count(*) from studmarks


number of rows in a table

The Count() function returns a value of type INTEGER. Hence, if the return value exceeds the range of
INTEGER type, then make use of COUNT_BIG() function which returns a value of type BIGINT.

select count(total), count(all maths), count(distinct maths) from studmarks


count(column)/count(all column) shows number of non-null values, count(distinct column) shows number of
non-null distinct values in the column

select sum(maths), sum(all maths), sum(distinct maths) from studmarks


for group functions, the default is all. Hence (coulmn)/(all coulmn) gives same output. (distinct column)
makes the group function consider only non-null distinct values

When group functions are used without group by clause, the entire table(or records of the table which satisfy
the given condition(s)) are considered as a single set for calculating the aggregate/summarised value as per
the function given

Group Functions with GROUP BY clause


When group functions are used with a group by clause, the entire table(or records of the table which satisfy
the given condition(s)) are divided into subsets of rows for calculating the aggregate/summarised value as
per the function given
select tcode, max(age), min(age), avg(age), sum(age) from student group by tcode
Will display the tcode-wise maximum, minimum, average and sum of ages of students. A group is also
formed for tcode=null

select t.tname, max(s.age), min(s.age), avg(s.age), sum(s.age) from teacher t full outer join student s on
t.tcode=s.tcode group by t.tname
Group by can also be done in a join of two or more table. A group is also formed for students without a
teacher. And groups are also formed for each such teacher including teachers who do not have students
Grouping can also be done on the basis of more than one columns as follows
Select std, div, max(maths), avg(english) from students group by std, div

Conditions can be given with a HAVING clause to further filter the output of the GROUP By clause. Thus,
having clause gives us filtered summarised data, and comes into picture only after the group By clause
select rollno, sum(maths) from studmarks group by rollno having sum(maths)>100 and sum(maths)<300 and
avg(maths)>60

select std, sum(maths) from studmarks group by std having sum(maths)>100 and sum(maths)<300 and
avg(maths)>60 order by std desc
select std, sum(maths) from studmarks group by std having sum(maths)>100 and sum(maths)<300 and
avg(maths)>60 order by sum(maths) desc
Order by clause can be used as the last clause, if required

select sch, std, div, max(maths) from students group by sc, std, div with Rollup
Apart from the sum of marks for each DIV within each STD within each SCH(like the normal GROUP BY), it
will also show us the sum of marks for each STD within SCH, sum of marks for each SCH, and the Grand
sum for all the students.

Thus, ROLLUP does additional grouping considering the last column(nth column) as one column and the
remaining columns(1 to n-1 columns) as a single column

select sc, std, div, max(maths) from students group by sc, std, div with Cube
Apart from the sum of marks for each DIV within each STD within each SCH(like the normal GROUP BY), it
will also show us the sum of marks for each STD within SCH, sum of marks for each DIV within a SCH, sum
of marks for each DIV within a STD, sum of marks for each SCH, sum of marks for each STD, sum of marks
for each DIV and the Grand sum for all the students.

Thus, CUBE does additional grouping on all the combinations of the n columns involved

ORDER BY clause
To arrange the retrieved rows in the order of a particular column. The column in the order by clause need
not appear in the SELECT list. By default it arranges the rows in the ASCENDING order, hence specifying
ASC is optional. For descending the keyword is DESC. More than one column can be included in the
ORDER BY clause. DESC/ASC need to be mentioned separately for each column in the order by clause

Select * from emp order by empno


Select * from emp order by empno asc
Select * from emp order by empno desc
Select * from emp order by deptno, ename
Select * from emp order by deptno desc , ename
Select * from emp order by deptno desc, ename desc
Select deptno, sum(sal) from emp order by sum(sal) desc
Select deptno, empname from emp order by 2
In the order of 2nd column in the select list

Select top 1 deptno, avg(sal) from emp group by deptno order by 2

Select top 1 deptno, avg(sal) from emp group by deptno order by 2 desc

It sometimes becomes becessary to modify the representation of data as per some predefined codification.
Such a requirement would normally require some sort of programming technique. Instead the CASE
expression makes this possible without any need for programming.
There are two forms of CASE :
1)Simple CASE expression
Synatx :
CASE Expression
When value1 then result1
When value2 then result2
When value3 then result3
When valuen then resultn
Else resultn+1
End

The Else is optional


select empid, empname, case deptno when 10 then 'Accounts' when 20 then 'IT' when 30 then 'Welfare'
else 'marketing' end departmentname from employee

select empno, empname, case mgrno when 1 then 'Manager 1' when 2 then 'Manager 2' when 3 then
'Manager 3' when 4 then 'Manager 4' when 5 then 'Manager 5' else 'No Manager' end from employee

Here, the entire CASE expression has been given the alias ‘departmentname’

2)Searched CASE expression


CASE
When condition 1 then result1
When condition 2 then result2
When condition 3 then result3
When condition n then resultn
Else result n+1
End

The Else is optional

select empno, empname,


CASE
when sal>=0 and sal<=500 then 'Class 4' when sal>500 and sal<=1000 then 'Class 3' when sal>1000 and
sal<=10000 then 'Class 2' when sal>10000 then 'Class 1' else 'No salary' end "Salary class" from emp

SUBQUERIES
It is the concept of query within a query. The main query is called OUTER query and the subquery is called
the INNER or NESTED query.

There are two types of subqueries


1) Simple
Here, the inner query is evaluated first and the output of the inner query is used as parameter for
the outer query. The inner query is evaluated exactly once

2) Correlated
Here, for each row of the outer query the inner query is evaluated again and again. Thus, the inner
query is evaluated more than once.

Simple Subqueries
select * from emp where deptno=(select deptno from emp where empname='hemant')
To display all the rows where deptno is the same as that of ‘hemant’. Here we are assuming that there is
only person with empname=’hemant’. If the inner query returns no rows or null value, then in both cases the
outer qury returns no rows.

Select * from stud where std=(select std from stud where rollno=101) and div=(select div from stud where
rollno=101)

Select * from students where maths>(select maths from students where studname='Laxman')

Select rollno, firstname from students where maths=(select max(maths) from students);

Select deptno, min(sal) from emp group by deptno having min(sal)>(select min(sal) from emp where
deptno=20);

Multirow-Subqueries
If the inner query returns more than one row than comparison operators like =,<,> fail and will cause an
error. For inner queries returning more than one row we can use multirow comparison operators : IN, ANY or
ALL
select * from emp where deptno in (select deptno from emp where empname='jairaj')

select * from emp where sal<any(select sal from emp where deptno=20) and deptno<>20
or
select * from emp a where exists(select sal from emp b where b.deptno=20 and a.sal <b.sal) and
deptno<>20
or
select * from emp where sal<some(select sal from emp where deptno=20) and deptno<>20
SOME is the synonym for ANY

select * from emp where sal=any(select sal from emp where deptno=20) and (deptno<>20 )

select * from emp where sal<all(select sal from emp where deptno=20) and deptno<>20

<ANY means <Maximum


<ALL means<Minimum
>ANY means >Minimum
>ALL means >Maximum
=ANY is equivalent to in

SubQuery in the FROM Clause of the Main Query:


The result of a query is always a set rof rows and columns and hence can be treated as a table

Select * from (select * from emp where sal>=5000) as emp5000


Here, emp5000 is an alias table name for the result of the select statement in the FROM clause. Here, the
alias must be specified if a subquery is placed in the from of the main query

Creating a table from an existing table :


select * into employee3 from employee
select * into employee3 from employee where 1=1
In both the cases all the records from source table are copied into the target table

select * into employee3 from employee where 1=0


Only structure is copied, records are not copied

Subquery in INSERT to enable insertion of multiple rows


insert into employee3(empid, empname) select empid, empname from employee where deptno=10
or
insert into employee3 select * from employee where deptno=10

Subquery in UPDATE to enable updation of multiple rows

Assume there are 2 tables : Employees(containing employee’s details) and Projects(containg one record for
each project that an employee works on and an employee may work on more than one project)

Suppose Tom goes on long leave and hence is currently not working on any projects. Hence projid in
Projects table needs to be set to null for all records where empid is Tom’s empid

Update projects set projid=null where empid in (select empno from employees where ename=’Tom’)
Assuming there is only 1 tom, hence in place of IN you could even use =

Subquery in DELETE to enable deletion of multiple rows

Assume there are 2 tables : Employees(containing employee’s details) and Projects(containg one record for
each project that an employee works on and an employee may work on more than one project)
Suppose Tom resigns hence is not working on any projects. Hence, all rows in projects on which tom was
working need to be deleted.

Delete from projects where empid in (select empno from employees where ename=’Tom’)
Assuming there is only 1 tom, hence in place of IN you could even use =

Assume there are 2 tables : Employees(containing employee’s details) and Projects(containg one record for
each project that an employee works on and an employee may work on more than one project)

Correlated Subqueries :
Unlike a normal nest query, in a correlated sub query, the inner query is driven by the outer query. Each
time a row from the outer query is process, the inner query is evaluated

Select * from emp e where e.sal>(select avg(sal) from emp d where d.deptno=e.deptno)

Here for every row of e, the salary of employees is compared with the average salary from d calculated
department wise

To find out all the employees who work on the project ‘P3’

Select * from employees where empid in (select empno from projects where projno=’P3’)
Normal Query

Or

Select * from employees where ‘P3’ in (Select projno from projects where project.empno=emplyees.empid)
Correlated subquery

SubQuery Using Exists :


The Exists Operator returns TRUE, if the subquery returns at least one row.

To find out all employees who have at least one employee reporting to them

Select empid, empname, deptno from employee e where EXISTS( Select 'X' from employee where
mgrid=e.empid)

To find out all employees who have no employee reporting to them

Select empid, empname, deptno from employee e where NOT EXISTS( Select 'X' from employee where
mgrid=e.empid)

Correlated Update
Alter table emp add deptname varchar(10);

Update emp set deptname=(select deptname from dept where emp.deptno=dept.deptno)

Correlated DELETE
To delete rows from outer table based on rows of the inner table.

Suppose there are two tables : Employees and Employees_History. The Employees table contains details of
all current employees and Employees_History table contains rows of retired employees. Let us assume a
situation where due to some reasons some retired employees’s records are also present in the current
employees table and you have to delete all such records.

select * into employee_hist from employee where empid<=5


To create a new table from an existing table

Delete from employee where empid=(select empid from employee_hist where


employee.empid=employee_hist.empid)
Commom Table Expression
Create table freights
(orderid int not null,
orderdate datetime,
shippeddate datetime,
freight money,
price money)

insert into freights values(1111,'1.10.2005','1.20.2005',30.45, 200.25)


insert into freights values(2222,'2.11.2005','2.21.2005',89.25, 543.00)
insert into freights values(3333,'3.12.2005','3.22.2005',19.35, 120.25)
insert into freights values(4444,'4.13.2005','4.23.2005',9.99, 154.35)

To find all the orders whose prices are greater than the average of all prices for the year 2005, and whose
freight is greater than 1/10th of the average of all prices for the year 2005

Select * from freights where price>(select avg(price) from freights where year(orderdate)=’2005’) and
freight>(select avg(price) from freights where year(orderdate)=’2005’)/10

The above query contains two subqueries which are almost identical and hence the entire query becomes a
bit too lengthy. Also, the query-columns are calculated for each of it’s execution. One way to shorten the
query would have been to create a view conatining the inner query and then use it where-ever required. But
then we would have to create the view and then drop it after it’s use.
Instead we can write a Common Table Expression(CTE) using the WITH clause. The Non-recrursive form
of CTE can be used as an alternative to derived tables(Derived table is a table expression defined in the
FROM clause of a SELECT statement that exists for the duration of the query)

Syntax :
WITH cte_name(column_list) AS
(inner_query)
Outer_query

WITH price_calc(avg2005) as
(Select avg(price) from freights where year(orderdate)='2005')
Select * from freights where price>(select avg2005 from price_calc) and freight>(select avg2005 from
price_calc)/10

Thus we don’t have to create views and then drop it. Rather, the inner query definnes the Select statement
which specifies the result set of the CTE and then we can use the CTE in the outer query

WITH price_calc(avg2005) as
(Select avg(price) from freights where year(orderdate)='2005'),
Freight_calc(freight2005) as
(Select avg2005/10 from price_calc)
Select * from freights where price>(select avg2005 from price_calc) and freight>(select freight2005 from
freight_calc)
Here we have created one CTE from another CTE, which is also allowed

WITH price_calc(avg2005, freight2005) as


(Select avg(price), avg(price)/10 from freights where year(orderdate)='2005')
Select * from freights where price>(select avg2005 from price_calc) and freight>(select freight2005 from
price_calc)
Here we have created one CTE with 2 columns and used the 2 columns at required places in the main query

Union clause between 2 queries shows common records retrieved by the two queries once and uncommon
records once.
select * from employee1
union
select * from employee2
When records of the two tables are exactly the same that is exactly same values for all the columns and
exactly same number of rows, then the output will be exactly the same as one of the select commands
involved.
Make changes to the values of empname column in certain records of both the tables and then retry the
command to notice the difference. Then make changes to different columns of the two tables and then retry
the command again.
select * from employee1
union
select * from employee2

select empid, empname from employee1


union
select empid, empname from employee2
Thus, common records means the records of the two or n queries involved who have got exactly the same
values for all the columns involved in the SELECT list. Also, the queries involved must have same number of
columns in the SELECT list

Union ALL clause between 2 queries shows common records as many number of times as the number of
queries involved and uncommon records once.
select * from employee1
union all
select * from employee2

Intersect clause between 2 or more queries shows only the common records once, and does not display
uncommon records at all
select * from employee1
intersect
select * from employee2

Except clause between 2 queries shows records of the first query which are not present in the second query
select * from employee1
except
select * from employee2

select * from employee2


except
select * from employee1

IDENTITY column

CREATE TABLE itemmast1(


itemcode int IDENTITY(100,1) NOT NULL,
itemname varchar(50) ,
price smallmoney ,
CONSTRAINT PK_itemmast1 PRIMARY KEY clustered(itemcode) )

To select a column of type IDENTITY, you need not specify it's name, but can use the keyword
IDENTITYCOL in the SELECT statement
select identitycol from itemmast1

SELECT IDENT_SEED('itemmast1'), IDENT_incr('itemmast1'), ident_current('itemmast1')


This will show the start value(100), the increment value(1), and the last value which has been
assigned/generated(dpends upon how many rows have been inserted)

When the data type of a column is of type IDENTITY, values cannot be specified for such a column as the
values are autogenerated. If, however, you want to supply your own values for certain rows, then before
inserting the rows thru the insert command , the IDENTITY_INSERT option must be set to on using the
following statement
set identity_insert itemmast1 on;

insert into itemmast1(itemcode, itemname, price) values(105,'Pendrive', 500);


insert into itemmast1(itemcode, itemname, price) values(108,'Mouse pad', 5);
insert into itemmast1(itemcode, itemname, price) values(115,'CD', 12);
SELECT IDENT_SEED('itemmast1'), IDENT_incr('itemmast1'), ident_current('itemmast1')
This will show the start value(100), the increment value(1), and the largest/last value which has been
assigned/generated(115)

Also, when inserting values manually, you need to specify the column names in the braces after the table
name or else it will give you an error, since specifying values for columns of type identity requires that the
column name be explicitly mentioned.
That is
insert into itemmast1 values(118,'Floop', 12);
will give an error though it is syntactically right

Also when IDENTITY_INSERT is on for the specified table then again


insert into itemmast1(itemname, price) values('Floop', 12);
is not going to work, as it expects a value since IDENTITY_INSERT is on. But, if you enter values directly
into the table thru MS SQL Management studio, then it accepts, but not thru the insert command

set identity_insert itemmast1 off;


now the following command will work
insert into itemmast1(itemname, price) values('Floop', 12);

IDENTITY column will now start generating values considering the current largest value in the table and not
from where it left.

COMPUTE clause
It uses aggregate functions (min, max, sum, avg) to calculate sumarrised values that appaer as additional
rows in the result of the query. The result of the compute clause is not a table, but a report. Hence, the
compute clause does not belong to the Relational Model, which forms the basis of all RDBMS packages.

select * from emp compute min(sal), max(sal)


Here, one additioanl row contains columns min, max showing minimum and maximum of salaries
respectively

select * from emp compute min(sal) compute max(sal)


Here, one additioanl row contains column min showing minimum of salary and one more additional row
containing column max showing maximum of salary

select * from emp compute min(sal), max(sal) compute sum(sal), avg(sal)


Thus one additional row per compute clause and one column per aggregate function within a compute
clause

Compute clause has an optional BY option. BY defines the grouping form of the result. The option By
coumn_name is like the group by column_name. However, the ORDER BY is compulsory if COMPUTE BY
is used

select * from emp compute min(sal), max(sal) by deptno


Will give an error : A COMPUTE BY item was not found in the order by list. All expressions in the compute
by list must also be present in the order by list.

select * from emp order by deptno compute min(sal), max(sal) by deptno

select * from emp order by deptno, empname compute min(sal), max(sal) by deptno, empname

Temporary Tables

There are two types of temporary tables: local and global. Local temporary tables are visible only to their
creators during the same connection to an instance of SQL Server as when the tables were first created or
referenced. Local temporary tables are deleted after the user disconnects from the instance of SQL Server.
Global temporary tables are visible to any user and any connection after they are created, and are deleted
when all users that are referencing the table disconnect from the instance of SQL Server.
Create both the below mentioned tables and insert records into them thru the same connection
use projects
create table #emp1(empno numeric(3), empname varchar(10))

insert into #emp1 values(1,'Heena')


insert into #emp1 values(2,'Hetal')

select * from #emp1

create table ##emp1(empno numeric(3), empname varchar(10))

insert into ##emp1 values(1,'Hemant')


insert into ##emp1 values(2,'Jairaj')

select * from #emp1


select * from ##emp1
Records of bothe the table will be shown

Now, Click on File, New, Query with Current Connection/or click on the New Query button on the Standard
Toolbar
Now in this session
select * from #emp1
will fail
But
select * from ##emp1
will succeed

Again, Now, Click on File, New, Query with Current Connection to start one more new session
Now in this session
select * from #emp1
will fail
But
select * from ##emp1
will succeed

Now close all the Query Sessions, including the session in which the two temporary tables(lolcal and global
temporary tables were crreated), and then try the following :
select * from #emp1
will fail
But
select * from ##emp1
will fail

Computed Columns
Computed columns are by default virtual columns that are not physically stored in the table. Their values are
recalculated each time they are referenced in a query.

create table orders(


ordno numeric(3) primary key,
orderdate smalldatetime,
quantity numeric(3),
price numeric(3),
totalprice as quantity*price,
shipdate as dateadd(day,7, orderdate))

While inserting records do not specify values for the computed columns
insert into orders values(1,getdate(),5,10)
select getdate()+7
insert into orders values(1,getdate(),6,15,90,getdate()+7)
This will give an error saying : Column name or number of supplied values does not match table definition.

update orders set quantity=10 where ordno=1


see how changes are reflected in the table

create table orders1(


ordno numeric(3) primary key,
orderdate smalldatetime,
quantity numeric(3),
price numeric(3),
totalprice as quantity*price persisted,
shipdate as dateadd(day,7, orderdate))

With SQL 2005, the keyword PERSISTED can be used in the Create table or Alter table so that the
computed column is physically stored in the table. Also index can be created for a persisted computed
column.

Columns on the basis of which computed columns are build must belong to the same table. Default cannot
be applied to computed columns

Subqueries are advantageous over joins when you have to calculate an aggregate value on the fly and use
it in the outer query for comparison

Eg:
Select * from students where maths=(Select max(maths) from students)

Joins are advantageous over subqueries when the SELECT list contains columns from more than one table.

Eg:
Select employee.empno, employee.empname, works.job from employee, works where
employee.empno=works.empno

Here you cannot use a subquery since the subquery can only display columns from the outer table

JOINS

To join two or more table, you can use two different syntax forms :

ANSI Join Syntax


It was introduced in the SQL 92 standard and defines a join operation explicitly by using the corresponding
name for each type of join. It enhances the readability of the queries. The type of Join operation is
mentioned explicitly using appropriate keyworsd in the FROM clause. The keyword concerning the explicit
definition of the join are :

[INNER] JOIN
LEFT [OUTER] JOIN
RIGHTT [OUTER] JOIN
FULL [OUTER] JOIN
CROSS JOIN

SQL SERVER Join Syntax


It is the “old-style” synatx wheren each type of join operation is defined implicitly using the join-columns(that
is the columns on the basis of which the join is performed)

EQUI JOIN or INNER JOIN

ANSI
Select * from emp INNER Join dept on emp.deptno=dept.deptno
Select * from emp INNER Join dept on dept.deptno=emp.deptno
Positioning of columns in the ON cluase is not significant. In both cases columns of emp table are shown
and then the columns of dept table are shown. The * indicates all the columns from both the table involved in
the join.
Select * from dept INNER Join emp on dept.deptno=emp.deptno
Select * from dept Join emp on emp.deptno=dept.deptno

Select emp.*, dept.* from dept Join emp on emp.deptno=dept.deptno

Select empname,sal, deptname from dept Join emp on emp.deptno=dept.deptno


Select deptname, empname from dept Join emp on emp.deptno=dept.deptno

The result of an EQUI/INNER join is records that have identical values for one or more pairs of columns.
There can be more than one pair of columns as follows :

Select emp.*, dept.* from dept Join emp on emp.deptno=dept.deptno and dept.dcity = emp.ecity
Here, assuming that dcity indicates the city of a particular department and ecity indicates the city of an
employee. Thus, the query would mean all the employees who stay in the same city as that of their
respective department.

Further, filtering of records can be done as follows :


Select deptname, empname from dept Join emp on emp.deptno=dept.deptno where sal>1000
Select deptname, empname from dept Join emp on dept.deptno=emp.deptno and sal>1000

SQL SERVER
Select * from emp,dept where emp.deptno=dept.deptno
Select * from emp,dept where dept.deptno=emp.deptno
Select * from dept, emp where dept.deptno=emp.deptno
Select emp.*, dept.* from dept, emp where dept.deptno=emp.deptno
select empname,sal, deptname from dept, emp where dept.deptno=emp.deptno
Select * from dept,emp where emp.deptno=dept.deptno and dept.location = emp.address
Here, the type of connection between the two tables is specified in the WHERE clause using one or more
pairs of columns.

Further, filtering of records can be done as follows :


select empname,sal, deptname from dept, emp where dept.deptno=emp.deptno and sal>1000

The semantics of the corresponding join columns must be identical. That is both of them must have the
same logical meaning. It is not necessary that the corresponding join columns must have the same name.

The names of columns in the SELECT list or any other part of the query which involves columsn can be
QUALIFIED to avoid any possible ambiguity which will occur if the tables have columns with identical
names. A column name is QUALIFIED as TABLENAME.COLUMNNAME or
TABLEALIASNAME.COLUMNNAME

In an EQUI/INNER join, the following possible strategy is used to give you the output :
First of all, each row of EMP table is joined with each row of DEPT table. The result of this will be a table
with all the columns from both the tables and n X m rows, where n=number of rows from EMP and m=
number of rows from DEPT.

Secondly, all the rows from the above nXm rows which satisfy the join condition
EMP.DEPTNO=DEPT.DEPTNO are displayed.

CROSS JOIN OR CATESIAN PRODUCT


In the possible attempt for generating an EQUI/INNER, each row of EMP table is combined with each row
of DEPT table. This INTERMEDIATE result before considering the join of the columns is called the
CARTESIAN PRODUCT of the table sinvolved in the join.

ANSI
Select * from emp CROSS JOIN dept

SQL Server
Select * from emp, dept

If the WHERE cluase contains something other than the JOIN condition, the result is still a Cartesian
Product, but will show only those rows that satisfy the condition in the where clause :

Select * from emp cross join dept where sal>1000


Select * from emp, dept where sal>1000

THETA JOIN or Non-Equi Joins


Join columns need to be compared using the comparison operator (=). However, sometimes, the =
comparison operator cannot be used as you may not be searching for a match of values. Such type of joins
wherein you use a comparison operator other than =, are called NON-EQUI or THETA JOINS.

CREATE TABLE employee(empno numeric,ename char(10),salary numeric)

1 HH 1100
2 JJ 2100
3 KK 20000
4 LL 21000
5 OO 26000
6 II 30000
7 UU 35000
8 YY 39999
9 TT 40000
10 RR 45000
11 QQ NULL
12 BB 750

CREATE TABLE sal_grade(grade char(1), min_sal numeric, max_sal numeric)

A 1000 10000
B 10001 20000
C 20001 30000
D 30001 40000

ANSI
Select e.empno, e.ename, e.salary, j.grade from employee e join Sal_Grade j on e.salary BETWEEN
j.Min_Sal and j.Max_sal
SQL Server
Select e.empno, e.ename, e.salary, j.grade from employee e, Sal_Grade j where e.salary BETWEEN
j.Min_Sal and j.Max_sal

Here, all the employees are shown except 10,11,12 as they do not fall in any of the grades mentioned in the
table sal_grade

Suppsoe you want to know all the employee information and department information such that the address
of the employee alphabetically preceeds the location
ANSI
Select distinct empno from emp join dept on address<location order by empno
SQL Server
Select distinct empno from emp, dept where address<location order by empno

Here, if you don’t put distinct or include any other column you will get a cartesian product

If you want more than one column then :


ANSI
Select emp.*, dept.* from emp join dept on emp.deptno=dept.deptno and address<location order by empno

SQL Server
Select emp.*, dept.* from emp, dept where emp.deptno=dept.deptno and address<location order by empno

NATURAL JOIN
In SQL Server, the meaning of Natural join is that the SELECT list should not have repetitive columns, which
happens in an Equi/Inner join which is performed on the basis of one or more pairs of columns which may
have identical values for the pair(s) of columns involved in the join.

ANSI
SELECT s.*, st.english, st.maths, st.science FROM STUDENT s join STudentmarks st on s.rollno=st.rollno
and s.std=st.std and s.div=st.div

SQL SERVER
SELECT s.*, st.english, st.maths, st.science FROM STUDENT s, STudentmarks st where s.rollno=st.rollno
and s.std=st.std and s.div=st.div

The SELECT List of a natural join need not contain all non-identical columns, but it simply does not include
the redundant join columns

ANSI
SELECT s.name, st.english FROM STUDENT s join STudentmarks st on s.rollno=st.rollno and s.std=st.std
and s.div=st.div

SQL SERVER
SELECT s.name, st.english FROM STUDENT s, STudentmarks st where s.rollno=st.rollno and s.std=st.std
and s.div=st.div

Here the pairs of columns on the basis of which the join is performed are not unnecessarily repeated in the
SELECT list

SELF JOIN
Here, a table is joined to itself, whereby a single column of a table is compared to itself or one column of the
table is compared with another column of that very table. For this it becomes necessary to treat that single
table as two different tables and then considering them as two separate table perform the join between the
pair or pairs of columns. This can be accomplished by giving aliases to the table so that it can appear twice
in the FROM clause

ANSI
select t1.deptno, t1.deptname, t1.location from dept t1 join dept t2 on t1.location=t2.location and
t1.deptno<>t2.deptno

select ep.empname as BOSS, ec.empname as WORKER from employee1 ep join employee1 ec on


ec.mgrid=ep.empid

SQL SERVER
select t1.deptno, t1.deptname, t1.location from dept t1 , dept t2 where t1.location=t2.location and
t1.deptno<>t2.deptno

select ep.empname as BOSS, ec.empname as WORKER from employee1 ep, employee1 ec where
ec.mgrid=ep.empid

OUTER JOINS
In case of EQUI/INNER, THETA, NATURAL, SELF joins, the result always included rows from one table that
have corresponding rows in the other table. Thus only MATCHING rows from both sides are shown.
Sometimes it is necessary to show UNMATCHED rows in addition to the MATCHED rows. This is achieved
through OUTER Joins

Left Outer Join


ANSI
Select * from dept left outer join emp on dept.deptno=emp.deptno
Select * from dept left join emp on dept.deptno=emp.deptno

SQL SERVER
Select * from dept, emp where emp.deptno*=dept.deptno
The use of ‘*=’ and ‘=*’ are not compatible or disappreciated feature in SQL 2005. Hence make use of ANSI
standards only

Right Outer Join


ANSI
Select * from dept right outer join emp on dept.deptno=emp.deptno
Select * from dept right join emp on dept.deptno=emp.deptno

SQL SERVER
Select * from dept, emp where emp.deptno=*dept.deptno

Full Outer Join


ANSI
Select * from dept full outer join emp on dept.deptno=emp.deptno
Select * from dept full join emp on dept.deptno=emp.deptno

SQL Server
Select * from dept, emp where emp.deptno=*dept.deptno
union
Select * from dept, emp where emp.deptno*=dept.deptno

Joining 3 or more tables :


select * from teacher, student, studmarks where teacher.tcode=student.tcode and
student.rollno=studmarks.rollno
Inner join or Equi-join achieved by comparing the coulmns using where clause

select t.tname, s.sname, sm.english, sm.maths, sm.science from teacher t join student s on t.tcode=s.tcode
join studmarks sm on s.rollno=sm.rollno

select * from teacher t left outer join student s on t.tcode=s.tcode left outer join studmarks sm on
s.rollno=sm.rollno
Output of the first LOJ is further LOJoined with the studmarks table
select * from teacher t left outer join student s on t.tcode=s.tcode right outer join studmarks sm on
s.rollno=sm.rollno
Output of the first LOJ is further ROJoined with the studmarks table

select * from teacher t right outer join student s on t.tcode=s.tcode right outer join studmarks sm on
s.rollno=sm.rollno
Output of the first ROJ is further ROJoined with the studmarks table

select * from teacher t right outer join student s on t.tcode=s.tcode left outer join studmarks sm on
s.rollno=sm.rollno
Output of the first ROJ is further LOJoined with the studmarks table
select * from teacher t full outer join student s on t.tcode=s.tcode full join studmarks sm on s.rollno=sm.rollno
Output of the first FOJ is further FOjoined with the studmarks table

select * from teacher t full outer join student s on t.tcode=s.tcode left join studmarks sm on s.rollno=sm.rollno
Output of the first FOJ is further LOjoined with the studmarks table

select * from teacher t full outer join student s on t.tcode=s.tcode Right join studmarks sm on
s.rollno=sm.rollno
Output of the first FOJ is further ROjoined with the studmarks table
Transact SQL

If condition(s)
begin
statement1
statement2
end

If condition(s)
statement1

The If can have an optional Else as follows:


If condition(s)
begin
statement1
statement2
end
else
statement1

or

If condition(s)
begin
statement1
statement2
end
else
begin
statement3
statement 4
end

In the if section or in the else scetion there is only one statement, then the Begin...... End is not required.

If(select count(*) from emp where deptno=20 group by deptno)>3


print 'There are more than 3 employees in this department'
else
begin
print 'Following are employees in this department'
select * from emp where deptno=20
end

WHILE
The While statement repeatedly executes a statement or more than one statements(enclosed within a
begin… end) till the boolean expression evaluates to true. Thus, if the expression/condition is true, the
statement or block of statements is executed and then the expression/condition is checked again to
determine if the statement or block of statements should be executed again.

The block within the while statement can optionally contain one or more statements used to control the
execution of statements within the block : BREAK or CONTINUE. BREAK statement stops the execution of
the statements inside the block and starts execution of the statement immediately following this block.
CONTINUE statement stops only the current execution of statements in the block and starts the execution of
the block again
declare @a int, @b int
set @a=1
set @b=0
while(@a<=10)
begin
print @a
set @b=@b+@a
print @b
set @a=@a+1
end
To print numbers from 1 to 10 and their sum

declare @a int, @b int


set @a=1
set @b=0
while(@a<=10)
begin
print @a
set @b=@b+@a
if @b>30 break
print @b
set @a=@a+1
end
To print numbers from 1 to 10 and their sum, provided than the sum is less than 30
RETURN statement can be used in place of BREAK and has the same functionality inside a batch as the
BREAK

declare @a int
set @a=0
while(@a<10)
begin
set @a=@a+1
if(@a=5)
continue
print @a
end
To print numbers from 1 to 10 except 5

declare @a int, @b int


set @a=0
set @b=0
while(@a<10)
begin
set @a=@a+1
if(@a=5)
continue
print @a
set @b=@b+@a
print @b
end
To print numbers from 1 to 10 and their sum except 5

declare @a int, @b int


set @a=0
set @b=0
while(@a<10)
begin
set @a=@a+1
if(@a=5)
continue
print @a
set @b=@b+@a
if (@b>30 and @b<40)
continue
print @b
end
To print numbers from 1 to 10 and their sum except 5, and except sum >30 and sum<40
declare @a int, @b int
set @a=1
set @b=0
label1:
print 'printing going on....'
while(@a<=50)
begin
--if @a in (11,21,31,41) goto label1
print @a
set @b=@b+@a
print @b
set @a=@a+1
if @a in (11,21,31,41) goto label1
end

GOTO can exist within conditional control-of-flow statements, statement blocks, or procedures, but it cannot
go to a label outside the batch. GOTO branching can go to a label defined before or after GOTO.

declare @a int, @b int


set @a=1
set @b=0
WAITFOR TIME '10:46'
while(@a<=10)
begin
print @a
set @b=@b+@a
print @b
set @a=@a+1
end
Here, WAITFOR TIME '10:46', specifies at what time the execution should begin

declare @a int, @b int


set @a=1
set @b=0
WAITFOR delay '00:00:30'
while(@a<=10)
begin

print @a
set @b=@b+@a
print @b
set @a=@a+1
end

Here, WAITFOR DELAY '00:00:30', specifies that the execution should be delayed by 30 seconds

declare @a int, @b int


set @a=1
set @b=0

while(@a<=10)
begin
WAITFOR delay '00:00:10'
print @a
set @b=@b+@a
print @b
set @a=@a+1
end
This will not print values with an interval of 10 seconds as the logic looks, but will do the printing work
together after 10X10=100 seconds

sp_addmessage @msgnum= 50002, @severity = 16,@msgtext = 'You are Wrong',@lang


='us_english',@with_log = true, @replace='replace'

declare @a int, @b int


set @a=1
set @b=0
while(@a<=10)
begin
print @a
set @b=@b+@a
if @b>40
raiserror(50002,16,-1)
print @b
set @a=@a+1
end

declare @a int, @b int


set @a=1
set @b=0
while(@a<=10)
begin
print @a
set @b=@b+@a
if @b>40
raiserror(50009,16,-1)
print @b
set @a=@a+1
end

Expand “SQL Server Agent”, “Error Logs”. Double-click on “Current 2-11-2010” (this will display the Log File
Viewer window, which contains various types of error logs). Expand the error logs for “SQL Server”. Select
the check-box for “Current 2-11-2010”. On the right-side you will see the details of all the errors. Notice the
difference for 50002 and 50009 user-defined errors.

Raiseerror
Generates an error message and initiates error processing for the session.

Sp_addmessage is a system stored procedure that creates a user-defined error message with an error
number and severity level. Error number must be greater than 50000(Error numbers less than 50000 are
reserved for SQL Server System)
With sp_addmessage you specify the Error number, the Error message,Severity level, Language in which
the message is to be displayed, and @with_log is set to true so that user-defined error message is written to
the event log(as user-defined messages are by default not written to the log). @replace=’replace’ to
overwrite an existing user-defined message
Handling Events with TRY and CATCH Statements

SQL Server 2005 handles exceptions using the TRY and CATCH statements. An Exception is a problem or
an error that prevents the continuation of a program. With such a problem you cannot continue the program
processing. Hence, this problem will be directed to another part of the program wherein the problem will be
dealt with.

The TRY statement does the work of capturing the exception. Since any program consists of several
statements, we have a TRY block. When an error/exception occurs in the TRY block, the exception/error is
delivered to another part of the program which will handle the exception. This part of the program which will
handle the error/exception is denoted by the keyword CATCH and hence is called the CATCH block.

Consider an Example of DEPT table and EMP table, where deptno in EMP table is Foreign Key to Deptno
column in DEPT table.

Now consider the following Transaction which attempts to add 4 records to the Emp table :

Begin Transaction
insert into emp values(200,'a',30,500, 'xyz')
insert into emp values(201,'b',30,500, 'xyz')
insert into emp values(202,'c',33,500, 'xyz')
insert into emp values(203,'d',30,500, 'xyz')
Commit transaction

Suppose, 33 is not a valid deptno in the DEPT table. Then, the first two records are added and the 3rd
record will generate an error. But the processing of the block will continue and the 4 th record will also be
added.

Suppose, the situation is that either all 4 should be added or none of them should be added. This can be
handled using TRY and CATCH as follows :

Begin TRY
Begin Transaction
insert into emp values(300,'a',30,500, 'xyz')
insert into emp values(301,'b',30,500, 'xyz')
insert into emp values(302,'c',33,500, 'xyz')
insert into emp values(303,'d',30,500, 'xyz')
Commit transaction
print 'Transaction succeded'
End TRY
Begin CATCH
Rollback
Print 'Transaction failed..'
End CATCH

The output will be :


(1 row(s) affected)

(1 row(s) affected)
Transaction failed..

Here, the first 2 Inserts are executed, and hence in the output you will see “1 row(s) affected” twice. Then
the third Insert fails. As all the 4 statements are written inside the TRY block, an exception is raised or
thrown and the exception handler starts the CATCH block. The CATCH block rollsback all the statements
and prints an appropriate message.

Stored Procedure
Procedure to display employees with deptno=30
Create procedure p1
As
Select * from emp where deptno=30
To execute Procedure P1
execute p1

Procedure to display employees with deptno=30 and then employees with deptno=20
Create procedure p2
As
Select * from emp where deptno=30
Select * from emp where deptno=20

To execute Procedure P2
exec p2

Procedure to display employees with deptno=30 and then employees with deptno=20 and then call
procedure p1
Create procedure p3
As
Select * from emp where deptno=30
Select * from emp where deptno=20
exec p1

To execute Procedure P3
exec p3

To drop procedure p1
drop proc p1

Now, if you execute Procedure p3, it will execute the first two lines and display an error for the third line as it
cannot find p1
Exec p3

Now, if you create a procedure p4 as follows :


Create procedure p4
As
Select * from emp where deptno=30
Select * from emp where deptno=20
exec p1

It will still create p4, with an error message for the missing object p1 and will also allow you to execute it.
When executed it will again show an error message for the third line

create procedure myproc;1


as select * from emp

create procedure myproc;2


as select * from emp where deptno=20
The optionl sepecification number allows the owner to group procedures with the same name. This means
that all procedures with the same name but with different number create a group.

To execute grouped procedures


Exec myproc
Will execute the procedure myproc;1

To execute the procedure myproc;2


Exec myproc;2

create procedure p;10


as
print 'i am p10'
This will give an error, since first p;1 must be created and then p;10 or p;50, etc as follows :

create procedure p;1


as
print 'i am p1'

create procedure p;10


as
print 'i am p10'

create procedure p;2


as
print 'i am p2'

Cannot drop such procedure individually as


Drop procedure p;1
Drop procedure p;10
It will give you an error

You have to drop it as a group


Drop procedure p
Which will drop the entire group

This feature has a number of limitations and is marked by Microsoft as a depreciated feature, and hence will
be removed from future versions of MS SQL SERVER

alter procedure p2
As
Select * from emp where deptno=1

Drops the entire procedure p2 and creates it again with the above mentioned statement

Procedure with Parameters


create procedure pm1
@dept tinyint
as
select * from emp where deptno=@dept

To execute :
Exec pm1 10
Exec pm1 20
Exec pm1 30

But, this will give you an error :


Exec pm1

As the procedure pm1 expects a value for the INPUT parameter @dept

create procedure pm2


(@dept numeric(3) , @sal numeric)
as
select * from emp where deptno=@dept and sal >=@sal
select * from emp where deptno=@dept
select * from emp where sal >=@sal

Exec pm2 10, 1000


Exec pm2 20,3000
This procedure has to be executed with 2 parameters. Will generate an error if executed with no, 1 or 3
parameters

create procedure pm3


(@dept numeric(3)=10 , @sal numeric)
as
select * from emp where deptno=@dept and sal >=@sal
select * from emp where deptno=@dept
select * from emp where sal >=@sal

execute pm3 default, 3000


The procedure will take 10 as the default value(which has been specified in the header of the procedure)
and 3000 as value for @sal

But the folliwng will all generate errors


Exec pm3
Exec pm3 4000
exec pm3 10, default
An error occurs when the procedure expects a value for a parameter thast does not have a default defined
or either a parameter is missing or the default keyword is specified for a parameter which does not have a
default specified.

But this will work


Exec pm3 null, 1000

create procedure pm4


(@dept numeric(3)=1 , @sal numeric=1000)
as
select * from emp where deptno=@dept and sal >=@sal
select * from emp where deptno=@dept
select * from emp where sal >=@sal

All of the following will work:


exec pm4 20, 500
exec pm4 default, 3000
exec pm4 30, default
exec pm4 30
exec pm4
exec pm4 default
exec pm4 default, default
exec pm4 @sal=500, @dept=30
exec pm4 @dept=30 @sal=500

create procedure incr_sal(@incr INT=5)


as
select * from emp
Update emp set sal=sal+sal*@incr/100
select * from emp

exec incr_sal 10

exec incr_sal

exec incr_sal default

create procedure modi_dept(@old_dept numeric(2), @new_dept numeric(2))


as
update department set deptno =@new_dept where deptno=@old_dept
update employees set deptno =@new_dept where deptno=@old_dept

Asuming that there is no PK-FK relationship between the two tables, such a procedure can be used as part
of the maintenance of referential constraint. Such a procedure can be used inside the defintion of a trigger,
which actually maintains the referential constraint.

Asuming that there is a PK-FK relationship between the two tables, then at execution time, the above
procedure will give two errors(one for each update) as both of them will separately attempt to viloate the FK
constraint, and hence both the statements will be terminated separatrly and no changes will be made to
either table

create procedure delt_dept(@dep numeric(2), @ctr numeric OUTPUT)


as
Select @ctr=count(*) from employees where deptno=@dep
Delete from employees where deptno=@dep
Delete from department where deptno=@dep

This procedure has 1 input and 1 output parameter. Th keyword OUTPUT has to be specified for a
parameter to become an output mode parameter. When the mode is not specified, it becomes an INPUT
mode parameter.

EXEC delt_dept
EXEC delt_dept 10
Both will generate errors, since procedure has got 2 parameters and needs to be executed with 2
parameters. However, since 2nd parameter is of type OUTPUT, the procedure will throw(output) a value to
the EXEC command. To catch this output(thrown) value, we need a variable which will catch the
thrown(output value) as follows :

Declare @quant numeric


Exec delt_dept 20, @quant output
print @quant

Create procedure myproc1


@dept tinyint, @sal numeric
as
If @dept is NULL or @dept=0
Begin
Print 'Please enter a valid department number which is not ZERO'
Return --- TO BREAK OUT UNCONDITIONALLY
end

If @sal is NULL or @sal=0


Begin
Print 'Please enter a valid salary which is not ZERO'
Return
end
Select * from emp where deptno=@dept and sal>=@sal

exec myproc1 30, 2000

Procedure executed with parameters by Position


Passing only values without referencing to the parameters(@variablename) to which they are being passed
is called Passing values by position. The values must be passed in the order in which they are defined in the
create procedure statement.

Create procedure addemp


@vempno numeric(3),
@vempname varchar(10),
@vdeptno numeric(3),
@vsal numeric
as
set @vsal=@vsal/2
Insert into emp values(@vempno, @vempname, @vdeptno, @vsal)

exec addemp 301,'Tom', 30, 10000

Procedure executed with parameters by Reference


Here the sequence of values passed to the procedure is not important, but you need to know the parameter
names
exec addemp @vdeptno=20, @vsal=1000, @vempno=400, @vempname='Harry'

Recompile option with procedures

create procedure countstud


@howmany tinyint with recompile

create procedure countstud1


@howmany tinyint

Exec countstud1 70 with recompile

The optional recompile option can be given in the Procedure definition. If the recompile option is given in the
procedure definition, it ignores the existing execution plan and generates a new plan each time the
procedure is executed. This destroys an important benefit of stored procedure being able to use an existing
execution plan, but sometimes it becomes necessary to regenerate a new plan with each new execution as
the database objects that are used/referred in the stored procedure change very frequently or when the
parameters passed to the stored procedure vary very widely with almost all the executions.

The recompile option can also be used with the execution of a procedure so that a new execution plan is
generated only for that execution of the procedure. In this case it is assumed that there is no recompile
inside the definition of the procedure, otherwise the entire idea of executing the procedure with recompile
option becomes meaningless. Execution with recompile is required when for that very execution the
parameters are going to vary very widely as compared to other previous executions

Transactions in Stored Procedures :


Create procedure adddeptemp
@vdeptno numeric(3),
@vdeptname varchar(10),
@vempno numeric(3),
@vempname varchar(10),
@vsal numeric
as
insert into dept values(@vdeptno, @vdeptname)
Insert into emp values(@vempno, @vempname, @vdeptno, @vsal/2)

exec adddeptemp 40,'HR',400,'Dick', 10000


Suppose, there is already an employee with empno=400. Then the first INSERT succeeds, but the second
generates an error and hence only the second INSERT fails.

exec adddeptemp 40,'HR',401,'Dick', 10000


Suppose, there is already a department with deptno=40. Then the second INSERT succeeds, but the first
generates an error and hence only the first INSERT fails.

Suppose you want that either both should succeed or both should fail, you need to write them as a
transaction block and then either commit the transaction(that is commit both of them) or rollback the
transaction(rollback both of them)
Create procedure adddeptemp
@vdeptno numeric(3),
@vdeptname varchar(10),
@vempno numeric(3),
@vempname varchar(10),
@vsal numeric
as
begin transaction
insert into dept values(@vdeptno, @vdeptname)
If @@error <>0
Begin
print ' check the department'
Rollback tran
Return
End

Insert into emp values(@vempno, @vempname, @vdeptno, @vsal/2)


If @@error <>0
Begin
print ' check the employee'
Rollback tran
Return
End
commit transaction

The @@error system variable contains the error number of the latest transact sql statement. Hence, a value
of 0 means no error

Create procedure adddeptemp1


@vdeptname varchar(10),
@vempname varchar(10),
@vsal numeric
as
begin transaction
insert into dept(deptname) values(@vdeptname)
If @@error <>0
Begin
print 'check the department'
Rollback tran
Return
End

print @@identity

Insert into emp(empname, deptno, sal) values(@vempname, @@identity, @vsal/2)


If @@error <>0
Begin
print ' check the employee'
Rollback tran
Return
End
print @@identity

commit transaction

exec adddeptemp1 'Marketing','Amit',800

Stored – Functions or user-defined functions

create function myfunc


(@input int=0)
returns int
as
begin
return 2*@input
end

SQL Server functions do not support output mode of parameters, but return a signle data value. The
RETURNS clause defines the Data-type of the value returned by the user-defined functions. This data type
can be any if the standard data types supported by SQL and the TABLE data type. TIMESTAMP/
TEXT/IMAGE data types cannot be returned. UDFs whose return-type is a Scalar SQL data type are called
scalar-valued functions, and UDFs whose return-type is TABLE are called table-valued

select empno, empname, sal, dbo.myfunc(sal) from emp


or
declare @abc int
select @abc=dbo.myfunc(100)
print @abc
or
select dbo.myfunc(100)
or
select dbo.myfunc(sal) from emp

A UDF can be invoked in SQL statemsnt like SELECT, INSERT, UPDATE, DELETE. To invoke a UDF,
specify it’s name followed by parenthesis. Within the parenthesis, you can specify one or more arguments
that are passed to the INPUT parameters that are defined in the function header.
update emp set sal=dbo.myfunc(sal)

select empno, empname, sal from emp where dbo.myfunc(sal)<3000

delete from emp where dbo.myfunc(sal)<3000


insert into emp(empname, deptno,sal) values('Ram',500, dbo.myfunc(1000))

create function calcsalr(@percent int=10)


returns decimal(16,2)
begin
declare @newsal decimal(16,2)
select @newsal=sum(sal)+sum(sal)*@percent/100 from emp
return @newsal
end

select dbo.calcsalr(10)

This function calculates the salaray of all the employees in the emp table and shows an amount which is X%
more than the total salary of all the employees. But, this function is limited to the table emp only.

CREATE FUNCTION myfunc2 (@dcode int)


RETURNS TABLE
AS
RETURN (SELECT deptname, empname, sal from dept d, emp e
WHERE d.deptno= e.deptno and
e.deptno = @dcode)

select * from dbo.myfunc2(500)


The above function is used to display details of all the employees and their department names for those
employees who belong to a specific department. The input parameter @dcode accepts the department
number. Since the function is going to return one or more rows, it’s retutn type is not a scalar sql datatype
but it’s return type is TABLE. If the RETURN clause specifies table with no accompanying list of columns,
the function is called INLINE function. Inline function returns the result set of a select statement as a variable
of the TABLE datatype. The BEGIN-END block must be ommitted when the RETURN clause contains a
SELECT statement

create table employee(empno numeric primary key,


empname varchar(10),
mgrno numeric references employee(empno))

CREATE FUNCTION fn_FindReports (@InEmp numeric)


RETURNS @retFindReports TABLE (empid numeric primary key,
empname varchar(10) NOT NULL,
mgrid numeric)
/*Returns a result set that lists all the employees who report to given
employee directly or indirectly.*/
AS
BEGIN
DECLARE @RowsAdded int
-- table variable to hold accumulated results
DECLARE @reports TABLE
( empid numeric primary key,
empname varchar(10),
mgrid numeric,
processed tinyint default 0)
-- initialize @Reports with employees that report directly to the given employee
INSERT @reports
SELECT empno, empname, mgrno, 0
FROM employee
WHERE empno = @InEmp
SET @RowsAdded = @@rowcount

-- Adding employees who report indirectly to those added in the previous iteration
WHILE @RowsAdded > 0
BEGIN
/*Mark all employee records whose direct reports are going to be
found in this iteration with processed=1.*/
UPDATE @reports
SET processed = 1
WHERE processed = 0
-- Insert employees who report to employees marked 1.
INSERT @reports
SELECT e.empno, e.empname, e.mgrno, 0
FROM employee e, @reports r
WHERE e.mgrno=r.empid and e.mgrno <> e.empno and r.processed = 1
SET @RowsAdded = @@rowcount
/*Mark all employee records whose direct reports have been found
in this iteration.*/
UPDATE @reports
SET processed = 2
WHERE processed = 1
END

-- copy to the result of the function the required columns


INSERT @retFindReports
SELECT empid, empname, mgrid
FROM @reports
RETURN
END

SELECT * FROM fn_FindReports(3)

If the RETURN clause specifies a variable as of table-type with list of columns, the function is called
MULTISTATEMENT Table-valued function. There is also an internal variable of type table which can be
used to insert rows into the table variable which is specified in the RETURN clause
Clustered and Non-Clustered Indices

SQL Server allows only one Clustered Index per table, since the clustered index determines the physical
order of the data in a table. It is built for each table implicitly where you define the Primary Key using the
Primary Key constraint. Also, a clustered index in SQL Server is Unique by default-that is each data value
can appear only once in a column for which the clustered index is defined. If a clustered index is built on a
non-unique column, the database system will enforce uniqueness by adding a 4-byte identifier to the rows
that have duplicate values.

Non-clustered indexes do not change the physical order of the rows in a table. At the leaf-level, a non-
clustered index consists of an index-key plus a bookmark. For each nonclustered index, SQL Server creates
an additional index structure that is tored in the Index. The bookmark on a nonclustered index shows where
to find the row corresponding to the index key. The bookmark part of the index key can have two forms :
when the table is a HEAP and when the table is CLUSTERED. Heap is a table without a clustered index. In
case of a Heap, the bookmark is identical to the Row Identifier(RID), which contains of two parts : the
address of the physical block where the corresponding row is tored and the poistion of the rows inside the
block. In case of a clustered index, the bookmark of the non-clustered index shows the b-tree structure of
the table’s clustered index.

In case of a Heap, the traversing of the nonclustered index structure will be followed by the retrieval of the
row using the row-identifier. In case of a Cluster, searching for data using a nonclustered index could be
twofold : the traversal of the nonclustered index structure will be followed by the traversal of the
corresponding clustered index. Thus a nonclustered index should be created only when you are sure that
there will significant performance gains.

CREATE [UNQUE] [CLUSETRED|NONCLUSTERED] INDEX index_name ON table_name|


view_name(coumn1 [ASC|DESC], coumn2 [ASC|DESC])
[INCLUDE(column1, …n)]

An index can either be a single or a composite index. Single index has only one column, while a composite
index is built on more than one column and can contain maximum 16 columns

The UNIQUE option specfies that each data value can appear only once in the index column(s). If UNIQUE
is not specified , then duplicate values are allowed.

The CLUSTERED and NONCLUSTERED(default) option specifies a clustered and nonclustered index
respectively. Maximum of 249 nonclustered indexes allowed per table.
The INCLUDE option allows you to specify the nonkey columns(colums not mentioned in that particular
index) to be added to the existing columns of the nonclustered index. This can enhance performance as the
query-optimizer can locate all of the required data-values within the index and does not have to visit data-
pages. This is called “COVERED INDEX”.

The FIILFACTOR=n specifies the storage percentage for each index page, where n =1, ….., 100. If n=100,
each leaf index page will be 100 percent filled, and hence the existing index pages will have no space for
insertion of new rows. Hence FILLFACTOR=100 is only recommended for static tables. If Fillfactor is set to
a value between 1 and 99, it causes creation of a new index structure with leaf pages that are not
completely full. The bigger the value of fillfactor, the smaller the space that is left free on an index page.
Example a fillfactor=60 means that 40 percent of each leaf index page is left free for future UPDATE and
INSERT statements. When a page is split, the data will be distributed 50-50 between the two new pages.

PAD_INDEX option specifies the place to leave open/free on each intermediate index page of the B-tree.

IGNORE_DUP_KEY option should be used only to avoid the termination of long transactions which may
insert duplicate data in the indexed column(s). With this option enabled, an insert statement which attempts
to insert rows that violates the uniqueness, SQL Server returns a warning and does not insert the rows that
attempt to add the duplicate value. It ignores that row and continues with the others.

Each non-clustered index in a clustered table contains in it’s leaf nodes the corresponding values of the
table’s clustered index. For this reason, all the nonclustered indices must be rebuilt when a table’s clustered
index is dropped. The DROP_EXISTING option allows you to enhance performance when re-creating a
clustered index on a table that also has nonclustered indices.
IF the ONLINE option is activated, you can continue to make updates to the underlying data and perform
queries against the data, while the index is being created or dropped or rebuilt. In early versions of SQL
Server, such index operations held an exclusive lock on the underlying data and the associated indices
prevented modifications or queries until the index operation was complete.

The STATISTICS_NORECOMPUTE option specifies that the statistics of the specified index should not be
automatically recomputed.

ALLOW_ROW_LOCKS and ALLOW_PAGE_LOCKS specifies that the system uses row locks and page
locks respectively when the option is set to on.

The ON file_group option specifies the file group in which the specified index must be created.

The ASC/DESC options after the column name specifies whether the index is created on the
ascending/descending order of the column’s values. An index defined on the ascending order of column is
generally not usefull when you are searching values in the reverse order

create table emp1(empno numeric, empname char(10))

create index i_empno on emp1(empno)


Creates a non-unique non-clustered index

To drop and index :


drop index emp1.i_empno
This form will not be supported in future versions of SQL Server
or
drop index i_empno on emp1

create unique index i_empid_mgrid on employee_hist(empid,mgrid) WITH fillfactor=80


creates a Unique, nonclustered index. It is a composite index for the columns empid and mgrid. 80 percent
of each index leaf page should be filled

Creation of a unique index for a column or composite columns is not possible if the column or columns
already contain duplicate values. Also, after the creation of a unique index any attempt to insert or modify
existing data which will create a non-unique value is also rejected by the system

alter index i_empid_mgrid on employee_hist REBUILD


To Rebuild an index

alter index all on employee_hist REBUILD


To rebuild all the indexes on a table

Rebuilding an index drops and re-creates the index. This removes fragmentation, reclaims disk space by
compacting the pages based on the specified or existing fill factor setting, and reorders the index rows in
contiguous pages. When ALL is specified, all indexes on the table are dropped and rebuilt in a single
transaction.

alter index i_empid_mgrid on employee_hist REorganize


To reorganize an index

alter index all on employee_hist Reorganize


To reorganize all the indexes

Reorganizing an index uses minimal system resources. It defragments the leaf level of clustered and
nonclustered indexes on tables and views by physically reordering the leaf-level pages to match the logical,
left to right, order of the leaf nodes. Reorganizing also compacts the index pages. Compaction is based on
the existing fill factor value.

alter index i_empid_mgrid on employee_hist disable


To disable an index
alter index all on employee_hist disable
To disable all indexes

ALTER INDEX i_empid_mgrid on employee_hist REBUILD


To enable a disabled index

ALTER INDEX all on employee_hist REBUILD


To enable all disabled indexes

CREATE unique INDEX i_empid_mgrid on employee_hist(empid,mgrid) WITH DROP_EXISTING

Disabling an index prevents user access to the index, and for clustered indexes, to the underlying table data.
The index definition remains in the system catalog. Disabling a nonclustered index or clustered index on a
view physically deletes the index data. Disabling a clustered index prevents access to the data, but the data
remains unmaintained in the B-tree until the index is dropped or rebuilt. Use the ALTER INDEX REBUILD
statement or the CREATE INDEX WITH DROP_EXISTING statement to enable the index.

Primary Key, Candidate Key, Foreign Key and Indices


It is a column or group of columns whose values are different in each rows. All columns or groups of
columns that qualify to be the Primary Key are called CANDIDATE keys. Foreign key is a column or a group
of columns that refers for it’s values to another coulmn or group of columns that is a Unique/Primary key in
the same or another table.

There should be a UNIQUE index for each Primary key and each Candidate key of a table. Each column in
a Primary/Candidate key should have the NOT NULL constraint. You do not have to worry about Primary
key, as a unique index is automatically created for the Primary key and all the columns in a Primary key are
of type Not Null. Each foreign key should have a nonunique index as this significantly reduces execution
time needed for the corresponding join operations

Implied creation of unique indexes :


1) Primary key constraint creates a “Unique Clustered Index”. Hence no other clustered index can be
created on that table. A table can have only 1 clustered index and upto 249 non-clustered indexes.
Records in a table are always stored by the order of the existing clustered index

2) Unique key constraint creates a “Unique Index”


Thus, implicit indexes are always of type unique

Indexes created by the CREATE INDEX command are of type non-unique and non-clustered by default

create unique clustered index i_empid_mgrid on employee3(empid, mgrid)


Will create a unique clustered index on the specified coilumns

alter table employee3 add constraint con_empid primary key(empid)


Here, the Primary Key constraint will create a Unique non-clustered index, since there is already a clustered
index existing on the table

Guidelines for Creating Indices :


SQl server does not have any practical limitations concerning the number of indices. But each index uses a
certain amount of disk space, hence it is possible for the number of index pages to exceed the number of
data pages within a database.
Also, insertions and deletions of rows into a indexed table causes a lot of performance-loss, as the index
tree needs to be modified
If the WHERE clause in a Select statement contains a search condition with a single column, an index
should be created. The use of an index is highly recommedned when the selectivity of the condition is 5
percent or less. The column should not be indexed if the selectivity is consistently 80 percent or more, since
aditional I/O operations will be required for the existing index pages, which will eliminate any time saving
gained. In such a case, a table-scan will be faster and the SQL Server Optmizer will usually choose to use a
table-scan, thereby making the index useless.
If the search condition in a frequently used where clause contains one or more AND operators, it is
recommended to create a composite index that includes all the columns of the table mentioned in the
WHERE clause.
For joins, it is recommened that the join columns should be indexed. Join columns are mostly primary key of
one table and foreign key of another or same table.

JOIN V/s Correlated SubQuery


A query can be solved using one or more ways. Each join operation can be also solved using a
corresponding correlated subquery and vice versa. A join operation is considerably more effocient than the
coreesponding correlated subquery

To list all the employee-names working on project ‘p3’

Select empname from emp, project where emp.empno=proejct.empno and project.projno=’p3’


Or Select empname from emp where ‘p3’ in (select projno from project where emp.empno=proejct.empno)

In the 2nd case, for each employee the inner qury will be evaluated again and again. This happens as the
inner query in it’s where clause refers to emp.empno column which belongs to the table emp which is in the
FROM cluase of the outer query.
The join in the 1st case is much faster as it evaluates all the values of the column project.projno only once.

Like operator and Index


If the condition in the WHERE clause on a column does the comparison using the LIKE operator, and the
column has an index on it, then the search on the character string is performed using the index. But, if the
first position is based on a wild card, then the index is not used. This is because an index works by quickly
determining whether the requested value is greater than or lesser than the values at the various nodes of
the b-tree. Hence, this comparison cannot be done by the index if the very first position in the requested
value ids a wildcard character. Example, the following query cannot use an index on the column empname :

Select * from emp where empname like ‘_abc’


Or
Select * from emp where empname like ‘%es’

But the index will be used for

Select * from emp where empname like ‘A___’


Or
Select * from emp where empname like ‘Ab%’

Views
Views do not exist physically. Their content is not stored on the disk. Views are database objects that are
always derived from one or more base tables. The name of the view and the way the rows from the base
tables are retrieved is the only information about the view that is physically stored. Thus, views are virtual
tables.

The SELECT statement in a view cannot include ORDER BY, INTO or COMPUTE clauses. Also, temporary
tables cannot be referred in the query of the view.

CREATE VIEW view_name[column_list] WITH ENCRYPTION | SCHEMABINDING


AS select
WITH CHECK OPTION

Views can be used for different purposes :


To restrict the access of particular columns and/or rows of tables. Thus, views can be used for controlling
access to a particular part of one or more tables.
To hide the details of complicated queries. If database applications need queries that involve complicated
joins, the creation of corresponding views can simplify the use of such queries.
To restrict inserted and updated values to certain ranges using the WITH CHECK OPTION.

Create view v_emp as select * from emp where deptno=10


This specifies the selection of certain rows, that is, creates a Horizontal Subset from the base table emp.

Create view v_emp as select empno, empname, sal from emp


This specifies the selection of certain columns, that is, creates a Vertical Subset from the base table emp.
Create view v_emp as select empno, empname, sal from emp where deptno=10
This specifies the selection of certain columns of certain rows, that is, creates a Vertical-cum-Horizontal
Subset from the base table emp.

Simple views:
Derives data from a single table. Dose not contain functions or groups of data. Allows you to perform DML
operations.
create view v1 as select * from emp

select * from v1

insert into v1(empname,deptno,sal,address) values('rohan',500,8000, 'A')


Here empno is of type identity, hence cannot be supplied thru the view.

Hence
set identity_insert dbo.emp on
insert into v1(empno, empname,deptno,sal,address) values(5010,'r',500,8000, 'A')

delete from v1 where empno in (610,710)

update v1 set sal=5000 where empno=810


create view v2 as select * from emp where sal>=8000
select * from v2

insert into v2(empno, empname,deptno,sal,address) values(5050,'rajiv',500,9000, 'A')

select * from v2

insert into v2(empno, empname,deptno,sal,address) values(5060,'amit',500,7000, 'B')


Here, even though the salary is less than 8000, the records is still inserted into the base table emp. But, the
records is not available through the view, that is, the record cannot be retrieved through the view as this
view can retrieve only those records where sal>=8000

select * from v2

select * from emp


Assuming that rows with empno=3610 and 3710 are both retrievable through the view(that is their
sal>=8000). Rows which are retrievable through the view can be updated so that after the updation they
may not be retrievable through the view
update v2 set sal=10000 where empno=3610
update v2 set empname='Ram' where empno=5010

update v2 set sal=6000 where empno=3710

This row wont be retrievable through the view after this update command

Row which are not retrievable through the view cannot be updated.

Assume that both empno=810 and 1110 are having salaries less than 8000 and hence not available through
the view.

update v2 set sal=6000 where empno=810

update v2 set empname='Bharat' where empno=1110

Both these updations are not allowed


Only those records can be deleted through the view which are available/retrievable through the view
Assume empno 810 is retrievable and empnp 5050 is not retrievable through the view
delete from v2 where empno=810
record will be deleted
delete from v2 where empno=5050
record will not be deleted

create view V3 as select * from emp order by sal


Order by clause not allowwed in Views

Views can have different column-names from the columns in the base tables
create view V3(employee_no, employee_name) as select empno, empname from emp

create view v4 as select empno employee_no, empname employee_name from emp

Simple views support DML operations subject to non-violation of constraints at the base table

create view v9 as select * from emp where deptno=500 and salary>=8000 with check option

set identity_insert dbo.emp on

insert into v9(empno, empname, deptno, salary, address, spousename, abc) values(9010, 'Tom', 500, 9000,
'Andheri', 'Pamela', 30)
Allowed

insert into v9(empno, empnames, deptno, salary, addresss, spousenames, abc) values(9020, 'Tom', 500,
7000, 'Andheri', 'Pamela', 30)

insert into v9(empno, empnames, deptno, salary, addresss, spousenames, abc) values(9020, 'Tom', 510,
17000, 'Andheri', 'Pamela', 30)

insert into v9(empno, empnames, deptno, salary, addresss, spousenames, abc) values(9020, 'Tom', 510,
7000, 'Andheri', 'Pamela', 30)
None of the above 3 inserts are allowed, as they violate the conditions given with the WHERE clause given
with the definition of the view. Same logic applies to UPDATE
WITH CHECK OPTION ensures that only those insertions/updations will be allowed through the view such
that the inserted/updated rows can later be retrieved through the view

create view v999 as select empno, e.deptno, empnames, salary from emp e join dept d on
e.deptno=d.deptno

insert into v999(empno,e.deptno, empnames, salary) values(9090, 500,'Pat', 9000)


Even though the view conatins a join of thwo tables, this insert will be allowed as the select list of view
contains columns from only one table

create view v999 as select empno, deptno, empnames, salary from emp e join dept d on e.deptno=d.deptno
This will not create the view and will give an error as : Ambiguous column name 'deptno'

create view v999 as select empno, d.deptno, empnames, salary from emp e join dept d on
e.deptno=d.deptno
The view is created, but it will not support :
insert into v999(empno,d.deptno, empnames, salary) values(7070, 500,'Pat', 9000)
Insert will fail, as the insert affects multiple base tables

insert into v999(empno, empnames, salary) values(7070, 'Pat', 9000)


This will be allowed as it affects only one table

Similarly try for UPDATE and DELETE

Complex views :

Derives data from many tables. Contains functions or groups of data. Does not allow DML operations

create view v5 as select deptno, sum(sal) from emp group by deptno


This will give an error as a view is a virtual table and it’s columns though virtual columns must have valid
names. Here sum(sal) cannot be a column name and hence it has to be given an alias

create view v5 as select deptno, sum(sal) sumsal from emp group by deptno
insert into v5 values(500, 9000)
Will give an error as V6 contains a derived or constant field.

create view v6 as select empno+sal as abc from emp


insert into v6 values(5000)
Will give an error as V6 contains a derived or constant field.

Alter view v1 as select * from emp where deptno=20


Alter view is used to modify the definition of the view query. Alter view can be used to avoid reassigning
existing privileges for the view. Also, altering a view does not affect the stored procedures that depend on
the view. If you drop and recreate a view, stored procedures and/or applications that use the view will not
work properly, atleast in the time period between removing and re-creating the view

To Drop a view
Drop View v1

When a table is dropped, the views that are based on that table are not dropped, but all such views become
inaccessible

create view v10 as select * from studentmarks

select * from v10

drop table studentmarks

select * from v10


error saying Could not use view 'v10' because of binding errors.

create view v22 with schemabinding as select * from emp


Error since ‘*’ is not allowed in schema-bound objects.

create view v22 with schemabinding as select empno, empname, sal from emp
Error since when schemabinding is used the referenced table, views and functions must have two part
names as schemaname.object name as follows :
create view v22 with schemabinding as select empno, empname, sal from dbo.emp

An attempt to modify the structure of the referenced table, will give you warning messages saying that the
schemabinding of v22 will be removed. If you want to continue you may still go on and save the structural
changes you have made to it. Addition of new columns, modifications to columns which are not in the
SELECT list do not affect the schema-binding

INDEXED VIEWS
Views contain a query that acts as a filter. The SQL Server dynamically builds the result set from a query
that refers to a view. Dynamically means that the view always shows the updated content of the underlying
table. Building the result set dynamically can decrease performance, especially if the view with it’s select
statement proceseses many rows from one or more table. Also, if the view contains computations based on
one or more columns, the computations are performed each time you access the view, as the result set of a
view is build dynamically. If such view are frequently accesses in other queries, then you could significantly
increase performance by creating an index on the view.

Advantages
SQL Server allows to create indices on views and such views are called INDEXED or MATERIALISED
Views. When you create a unique clustered indexed view, the result set of the view(at the time the index is
created) is stored on the disk. Hence, all data modifications in the base table(s) will also be automatically
modified in the corresponding result set of the indexed view. After the creation of the unique clustered index
on the view, you may create any number of non-clustered indices on that view.

The most important advantage is that if a query does not explicitly refer to the indexed view, but contains a
column in the base table(s) which also exists in the index view, the SQL Optimizer estimates that using the
indexed view is the best choice and it chooes the view’s indices to solve that query

Queris that process many rows and contain join operations or aggregate functiions can gain performance
benefits if an indexed view is referred by the corresponding queries.

Creating an Indexed view :


Create view v200 with schemabinding as select empid, empname, mgrid, deptno from dbo.employee1

create unique clustered index abc on v200(empid, mgrid)

When can you create an index view :

View must refer to only base tables


The view and the referred tables must have the same owner and belong to the same database
View must be created with the Schemabinding option which binds the view to the underlying tables
The referenced UDFs must also be created with schemabinding option
The select statement of the view must not contain following clauses/options : DISTINCT, UNION,
COMPUTE, TOP, ORDER BY, MIN, MAX, COUNT, SUM(on a nullable expression), SUBQUERIES,
OUTER

Triggers
A Trigger is a collection of SQL statements that looks and acts like a stored procedure, but a trigger cannot
be called with the EXEC command. Triggers are activated or fired when a user tries to Insert, Update or
Delete data.

Triggers is a tool that is invoked when a particular action occurs on a particular table. The action of a trigger
can be on a INSERT, UPDATE or DELETE statement. SQL Server 2005 also allows you to define triggers
on DDL statements

CREATE TRIGGER [schema_name].trigger_name


On Table_name|view_name
[WITH dml_trigger_option]
FOR|AFTER|INSTEAD OF insert[,]UPDATE[,]DELETE
[With append]
As
Sql_statement | External name method_name

INSERT TRIGGER
They can be used to modify or even disallow a record being inserted.. Example : Insert Trigger could be
used to prevent users from entering records with salary less than 10000. Another use could be adding data
to the record being inserted, like adding the date when the record was inserted or adding the name of the
user inserting the record. It could even be used to cascade changes to some other tables in the database.

INSERT Triggers fire off(are executed) every time someone tries to create a new record in a table using the
INSERT Command. When a user tries to insert a new record into a table , SQL Server copies the new
record into the TRIGGER table(table in which user is attempting to add the new record) and also copies the
new record to a special table stored in the memory called the INSERTED table. Thus the new record being
inserted, exists in two tables : the TRIGGER table and the INSERTED table.

Example :

Create trigger INVUPDATE on ORDERS


For insert
As
Update p set p.instock=(p.instck-i.qty) from Products p join inserted I
On p.prodid=i.prodid

DELETE TRIGGER
They can be used to restrict the data that your users want to remove from a table. Example.: You may not
want your users to be able to remove records who belong to department=10 from the employees table. Or
you may also want to let your users delete records, but you want to update your management about the
records being deleted, the user who deleted the records and the time of deletion.

Ordinarily when a record is deleted, SQL Server removes that record from the table and the record is lost
permanently. With a DELETE trigger in place for a table, SQL Server moves the record being deleted to a
logical table called the DELETED table in the memory. Thus the record can still be referenced in your code
NOTE(DELETED, INSERTED tables are automatically purged of records after a transaction is complete, as
they are logical temporary tables in the memory)

Create trigger NODELETE10 on EMP


For delete
As
If (Select deptno from deleted)=10
Begin
Print ‘Cannot delete records from department 10’
Print ‘Transaction has been cancelled’
Rollback
End

UPDATE TRIGGERS
They are used to restrict UPDATE statements being issued by the users. Specifically designed to restrict the
existing data that your users can modify. Or may be allow the updations, but report the same to the
management or even update some other tables.

Update Triggers use both the temporary tables : INSERTED and DELETED. This is because an UPDATE
action is actually two separate actions : a delete followed by an insert. First the existing data is deleted and
then the new data is inserted. Thus the old record goes to the DELETED table and the new data goes to the
INSERTED table.

Create trigger CHECKSAL on emp


For Update
As
If (select sal from inserted)<(select sal from deleted)
Begin
Print ‘Cannot reduce salary’
Print Transaction is being cancelled’
Rollback
End

Create trigger CHECKPHONE on emp


For Update
As
If UPDATE(phone)
Begin
Print ‘Cannot change phone number’
Print Transaction is being cancelled’
Rollback
End

The 3 types of triggers can be combined. You can have an INSERT, UPDATE trigger or INSERT, DELETE
trigger or UPDATE, DELETE trigger or all three together.

Tp prevent modification of rows of department 10


Create Trigger nomod10 on EMP
For update, delete
As
If (Select deptno from deleted)=10
Begin
Print 'Cannot modify employees in this department'
Print 'Transaction is being rolled back'
Rollback
End

RECURSIVE TRIGGERS
Those triggers that update other tables can cause triggers on those tables to fire. Such triggers are called
RECURSIVE triggers. In MS SQL Server, recursive triggers are disabled by default. In case you want to
enable it, right click on the database, select properties, and in the options tab, check the box next to
“RECURSIVE TRIGGERS”/ or set it to TRUE

create trigger t8 on students


for update
as
print 'update fired'
If update(maths) or update(science)
Begin
select 'maths or science marks updated for rollno: '+cast(inserted.rollno as char(12)) from inserted
update students set students.total=students.maths+students.science+students.English from inserted where
students.rollno=inserted.rollno
end
if (select students.maths from students, deleted where students.rollno=deleted.rollno)<>
(select deleted.maths from students, deleted where students.rollno=deleted.rollno)
begin
print 'maths marks changed'
end
if (select students.science from students, deleted where students.rollno=deleted.rollno)<>
(select deleted.science from students, deleted where students.rollno=deleted.rollno)
begin
print 'science marks changed'
end

create trigger t9 on students


for update
as
print 'update fired'
If update(maths) or update(science)
Begin
if (select inserted.maths from inserted, students where students.rollno=inserted.rollno)>100
begin
print 'maths marks cannot be greater than 100'
rollback
end

else
begin
if (select inserted.science from inserted, students where
students.rollno=inserted.rollno)>100
begin
print 'science marks cannot be greater than 100'
rollback
end
else
begin
print 'maths or science have been updated'
update students set
students.total=students.maths+students.science+students.English from inserted where
students.rollno=inserted.rollno
end
end

end

create trigger enctrig on students with encryption


for delete as
print ‘record deleted’

Select a.name,b.text from sysobjects a, syscomments b where a.id=b.id and a.name='enctrig'

The AFTER and INSTEAD OF are two additional options which you can define for a trigger. FOR is the
synonym for AFTER. AFTER triggers fire after the triggering event occurs. INSTEAD OF triggers are
executed instead of the corresponding triggering event. AFTER triggers can be created only on tables.
INSTEAD OF triggers can be created on both tables and views.

Multiple triggers can be created for each table and for each modification action
(INSERT, UPDATE, DELETE. ) By default there is no specific order in which multiple triggers for a particular
modification action.

When creating a triggered action, you may require to use the values of columns before or after the effect of
the triggering statement. For this, two virtual tables are used. The structure of thes tables is equivalent to
the structure of the table for which the trigger is specified. For each delete statement that triggered an action
, the DELETED table is created. For each insert statement that triggered an action, the INSERTED table is
created. An update is trated as a as a delete followed by an insert, hance for each update statement that
triggers an action, the DELETED and then the INSERTED tables are created. The DELETED table contains
copies of rows that are deleted from the triggered table. The INSERTED table contains copies of rows that
are inserted into the triggered table. For an update operation, the data before modification goes to the
DELETED table and the data after modification goes to the INSERTED table

AFTER Triggers
After triggers fire after the triggering event has been processed. An AFTER trigger can be specified by
using the AFTER or FOR resrrved keyword. After trigger can be created on base tables.

Creation of an audit trail of activities using AFTER trigger:

create table audit_emp_sal


(empno numeric, user_name varchar(20), time datetime, sal_old numeric, sal_new numeric)

create trigger edit_sal


on emp
after update
as
if update(sal)
begin
declare @sal_old numeric
declare @sal_new numeric
declare @emp_no numeric
set @sal_old=(select sal from deleted)
select @sal_new=(select sal from inserted)
set @emp_no=(select empno from deleted)
insert into audit_emp_sal values(@emp_no, user_name(), getdate(), @sal_old, @sal_new)
end

In the above trigger, the IF UPDATE() is very important as we are interested in tracking chages only to the
sal column in emp. If the IF UPDATE(sal) is not used then the trigger block will get executed for
modifications to any column of emp table. And in that case, if sal is not modified, then in the audit table
values of sal_old and sal_new will be the same.
Implementing business logic using AFTER trigger:

create trigger check_sal


on emp
after update
as
if update(sal)
begin
if (select sal from inserted)> (select sal from deleted)*2
begin
print 'Cannot increase at this rate'
rollback transaction
end
else
begin
print 'salary changed'
end
end

Implementing Referential Integrity Constraint using AFTER trigger


create trigger ref_intgr_deptno
on emp after insert, update
as
if update(deptno)
begin
if (select dept.deptno from dept, inserted where dept.deptno=inserted.deptno) is null
begin
print 'no such department number'
rollback transaction
end
else
print 'department allowed'
end

Trigger names must be unique across tables/views

create trigger ref_intgr_deptno1


on dept after update
as
if update(deptno)
begin
if (select count(*) from emp, deleted where emp.deptno=deleted.deptno) >0
begin
print 'no such updation allowed'
rollback transaction
end
else
print 'department is updated'
end

create trigger ref_intgr_deptno2


on dept after delete
as
--if update(deptno)
begin
if (select count(*) from emp, deleted where emp.deptno=deleted.deptno) >0
begin
print 'no such deletion allowed'
rollback transaction
end
else
print 'department is deleted'
end

INSTEAD OF TRIGGERS
They are fired instead of the triggering event. They are executed after the corresponding INSERTED and
DELETED tables are created, but before any integrity constraint or any other action is performed.

They can be created on tables as well as views

create table t1(c1 numeric, c2 numeric, c3 as c1*c2 persisted constraint abc check (c3<50))

Here, c3 is a computed column, hence you can neither insert values into it thurough the insert command,
nor can you update it through the update comand

Also
Only UNIQUE or PRIMARY KEY constraints can be created on computed columns, while CHECK,
FOREIGN KEY, and NOT NULL constraints require that computed columns be persisted.

create trigger t2 on t1 instead of insert


as
declare @c1 numeric
declare @c2 numeric
declare @c3 numeric
set @c1=(select c1 from inserted)
set @c2=(select c2 from inserted)
set @c3=(select c3 from inserted)
if @c3>=50
print @c3
print 'not allowed'

In this case, the message “NOT ALLOWED” is displayed and not the error of the check constraint which
prooves that instead of triggers are executed after the corresponding INSERTED and DELETED tables are
created, but before any integrity constraint or any other action is performed.
Hence, the INSTEAD OF trigger could also be used for constraint checking, and hence, in this case even
the following table structure would have done :
create table t1(c1 numeric, c2 numeric, c3 as c1*c2)

Create table myemp(empno numeric(18, 0), empname varchar(50), grade tinyint, sal numeric(10,2),
code tinyint, city varchar(50) )

Create view vmyemp as select empno, empname, grade,code from myemp

create trigger mytrig1 on vmyemp instead of insert


as
declare @empno numeric
declare @empname varchar(50)
declare @grade tinyint
declare @code tinyint
declare @sal numeric(10,2)
declare @city varchar(50)
set @empno=(select empno from inserted)
set @empname=(select empname from inserted)
set @grade=(select grade from inserted)
set @code =(select code from inserted)
set @sal=CASE
When @grade=1 then 1000
When @grade=2 then 2000
When @grade=3 then 3000
When @grade=4 then 4000
Else 500
End
set @city=CASE
When @code=10 then 'mumbai'
When @code=20 then 'Kolkatta'
When @code=30 then 'Chennai'
When @code=40 then 'Bengaluru'
Else 'India'
End
Insert into myemp values(@empno, @empname, @grade, @sal, @code, @city)

Now insert the following records through the view


Insert into vmyemp values(1,’shailesh’, 1,10)
Insert into vmyemp values(2,’mahesh’, 3,20)
Insert into vmyemp values(3,’tom’, null,null)
Insert into vmyemp values(4,’dick’, 5,50)

FIRST and LAST Triggers


SQL Server allows multiple triggers to be created for each table or view for an action like INSERT,UPDATE
and DELETE. However, their order of execution is arbitary. Using the system stored procedure
sp_settriggerorder, you can specify which of the multiple triggers of type AFTER for a particular modification
action(Insert, Update, Delete) should be executed FIRST or LAST.

insert into orders(orderid, price, quantity, orddate) values(5,100,2,'12/29/2007')

create trigger ot4 on orders after insert as


print 'i am fourth'

EXECUTE sp_settriggerorder @triggername ='ot4', @order='last',@stmttype='insert'

There can be only one FIRST and one LAST after trigger on a table. The sequence in which the other
AFTER triggers on that very table will be executed is undefined. As the INSTEAD of triggers are fired before
the modification is done to the underlying table, INSTEAD OF triggers cannot be specified as FIRST or
LAST.

SQL Server 2005 allows you to define triggers for DDL events as follows :
Create Trigger dp_trig
On database
For DROP_TRIGGER
As print ‘You are dropping a trigger. Not allowed’
Rollback

Drop trigger ot1

Create Trigger cr_tabl


On database
For create_table
As print 'You are creating a table'

create table t10(c1 numeric)

Create Trigger dp_tabl


On database
For drop_table
As print 'You are dropping a table. Not allowed'
Rollback

drop table t10

CREATE TRIGGER safety


ON DATABASE
FOR DROP_TABLE, ALTER_TABLE
AS
PRINT 'You cannot drop or later tables!'
ROLLBACK

To enable/disable trigger s:
disable trigger ot1 on orders
enable trigger ot1 on orders

disable trigger all on orders


enable trigger all on orders

disable trigger dp_tabl on database


enable trigger dp_tabl on database

disable trigger all on database


enable trigger all on database

drop trigger safety on database


OLAP Extensions in T-SQL
SQL : 1999 was the first standard that provided solutions for data analysis. This part of the SQL 1999
standard is called SQL/OLP(OnLine Analytical Processing).

SQL Server offers many extensions to the SELECT statement that can be used for Decision Support
Operations. SQL extensions that are implemented in SQL Server 2005 for Business Intelligence can be
divided into 4 groups :

CUBE and ROLLUP operators


Thay are used to add summary rows to the result of a SELECT statement with the
GROUP BY clause

Ranking Functions
Thay generally return a number that specifies the rank of the current row among all rows
and that belongs to the specified group

TOP n clause
It provides retrieval of the first n rows of a query result(usually sorted using some criteria)

PIVOT and UNPIVOT relational operators


Thay can be used to manipulate table-va;ued expressions

ROLLUP and CUBE operators

The Group By clause is used to group together rows that have the same or common value for the
column/columns placed in the Group By clause in order to retrieve some aggregated/consolidated value for
each such group of rows.

Consider a table having score of maths for students of different divisions of different standards of
different schools

select sclcode, std, div, max(maths) from students group by sclcode, std, div with Rollup

ROLLUP does additional grouping considering the last column(nth column) as one column and the
remaining columns(1 to n-1 columns) as a single column, and then repeats the process for columns 1 to
columns n-1

Apart from the sum of marks for each DIV within each STD within each SCH(like the normal
GROUP BY), it will also show us the sum of marks for each STD within each SCH, sum of marks for each
SCH, and the Grand sum for all the students.

The group hierarchy using ROLLUP is determined by the order in which the columns are specified
in the group by clause
select sclcode, std, div, max(maths) from students group by sclcode, std, div with Cube

Apart from the sum of marks for each DIV within each STD within each SCH(like the normal
GROUP BY), it will also show us the sum of marks for each STD within SCH, sum of marks for each DIV
within a SCH, sum of marks for each DIV within a STD, sum of marks for each SCH, sum of marks for each
STD, sum of marks for each DIV and the Grand sum for all the students.

Thus, CUBE does additional grouping on all the combinations of the n columns involved in the
Group By clause

Ranking Functions
SQL Server 2005 defines four functions that are categorised as ranking functions, i.e., functions that return a
ranking value for each row in a partition group

Concider the following table :


Empno ename sal deptno secno
1 a 2000.00 10 s1
2 b 3000.00 10 s1
3 c 4000.00 10 s2
4 d 2000.00 10 s3
5 e 4000.00 20 s1
6 f 5000.00 20 s1
7 g 4900.00 20 s2
8 h 5500.00 20 s2
9 i 1000.00 20 s3
10 j 2000.00 20 s3
11 k 4000.00 30 s1
12 l 3000.00 30 s1
13 m 2000.00 30 s2
14 n 1500.00 30 s2
15 o 5000.00 30 s2
16 p 3000.00 30 s2
17 q 1000.00 40 s2
18 r 1000.00 40 s2
19 s 2000.00 40 s3
20 t 4000.00 40 s3

RANK
The rank function returmns a number that specifies the rank of the row among all the rows

select rank() over(order by sal desc)as rank_sal, emp.* from emp

rank_sal empno ename sal deptno secno


1 8 h 5500.00 20 s2
2 6 f 5000.00 20 s1
2 15 o 5000.00 30 s2
4 7 g 4900.00 20 s2
5 3 c 4000.00 10 s2
5 11 k 4000.00 30 s1
5 5 e 4000.00 20 s1
5 20 t 4000.00 40 s3
9 12 l 3000.00 30 s1
9 16 p 3000.00 30 s2
9 2 b 3000.00 10 s1
12 1 a 2000.00 10 s1
12 4 d 2000.00 10 s3
12 13 m 2000.00 30 s2
12 19 s 2000.00 40 s3
12 10 j 2000.00 20 s3
17 14 n 1500.00 30 s2
18 17 q 1000.00 40 s2
18 18 r 1000.00 40 s2
18 9 i 1000.00 20 s3

This example uses the OVER clause : over(order by sal desc) to sort the result set by the sal column in the
descending order.

The RANK function uses logical aggregation. In other words, if 2 or more rows in a resultset are tied(have a
same value in the ordering column), they will have the same rank. The row with the subsequent ordering will
have a rank that is one plus the number of ranks that precede the row. For this reason, the RANK function
displays gaps if two or more rows have the same ranking.

DENSE_RANK
This function is similar to the RANK() fucntion, except that it returns no gap if two or more ranking values are
equal and thus belong to the same ranking.

select dense_rank() over(order by sal desc) as d_rank_sal, emp.* from emp

d_rank_sal empno ename sal deptno secno


1 8 h 5500.00 20 s2
2 6 f 5000.00 20 s1
2 15 o 5000.00 30 s2
3 7 g 4900.00 20 s2
4 3 c 4000.00 10 s2
4 11 k 4000.00 30 s1
4 5 e 4000.00 20 s1
4 20 t 4000.00 40 s3
5 12 l 3000.00 30 s1
5 16 p 3000.00 30 s2
5 2 b 3000.00 10 s1
6 1 a 2000.00 10 s1
6 4 d 2000.00 10 s3
6 13 m 2000.00 30 s2
6 19 s 2000.00 40 s3
6 10 j 2000.00 20 s3
7 14 n 1500.00 30 s2
8 17 q 1000.00 40 s2
8 18 r 1000.00 40 s2
8 9 i 1000.00 20 s3

ROW_NUMBER
This function returns the sequential number of a row within a result set, starting at 1 for the first row.

select row_number() over(order by sal desc) as rownum, emp.* from emp

rownum empno ename sal deptno secno


1 8 h 5500.00 20 s2
2 6 f 5000.00 20 s1
3 15 o 5000.00 30 s2
4 7 g 4900.00 20 s2
5 3 c 4000.00 10 s2
6 11 k 4000.00 30 s1
7 5 e 4000.00 20 s1
8 20 t 4000.00 40 s3
9 12 l 3000.00 30 s1
10 16 p 3000.00 30 s2
11 2 b 3000.00 10 s1
12 1 a 2000.00 10 s1
13 4 d 2000.00 10 s3
14 13 m 2000.00 30 s2
15 19 s 2000.00 40 s3
16 10 j 2000.00 20 s3
17 14 n 1500.00 30 s2
18 17 q 1000.00 40 s2
19 18 r 1000.00 40 s2
20 9 i 1000.00 20 s3

select row_number() over(order by deptno,secno) as dsrownum, emp.* from emp


dsrownum empno ename sal deptno secno
1 1 a 2000.00 10 s1
2 2 b 3000.00 10 s1
3 3 c 4000.00 10 s2
4 4 d 2000.00 10 s3
5 5 e 4000.00 20 s1
6 6 f 5000.00 20 s1
7 7 g 4900.00 20 s2
8 8 h 5500.00 20 s2
9 9 i 1000.00 20 s3
10 10 j 2000.00 20 s3
11 11 k 4000.00 30 s1
12 12 l 3000.00 30 s1
13 13 m 2000.00 30 s2
14 14 n 1500.00 30 s2
15 15 o 5000.00 30 s2
16 16 p 3000.00 30 s2
17 17 q 1000.00 40 s2
18 18 r 1000.00 40 s2
19 19 s 2000.00 40 s3
20 20 t 4000.00 40 s3

The OVER clause is used in the above examples to determine the ordering of the resultset. This clause is
not used only for ordering. Generally, the OVER clause is used to divide the result set produced by the
FROM clause into groups(partitions) using the PARTITION BY, and the apply the ranking function to
each such partition separately as follows :

select rank() over(partition by deptno order by sal desc)as rank_sal, emp.* from emp

rank_sal empno ename sal deptno secno


1 3 c 4000.00 10 s2
2 2 b 3000.00 10 s1
3 1 a 2000.00 10 s1
3 4 d 2000.00 10 s3
1 8 h 5500.00 20 s2
2 6 f 5000.00 20 s1
3 7 g 4900.00 20 s2
4 5 e 4000.00 20 s1
5 10 j 2000.00 20 s3
6 9 i 1000.00 20 s3
1 15 o 5000.00 30 s2
2 11 k 4000.00 30 s1
3 12 l 3000.00 30 s1
3 13 m 2000.00 30 s2
5 14 n 1500.00 30 s2
1 20 t 4000.00 40 s3
2 19 s 2000.00 40 s3
3 17 q 1000.00 40 s2
3 18 r 1000.00 40 s2

select dense_rank() over(partition by deptno order by sal desc) as d_rank_sal, emp.* from emp

d_rank_sal empno ename sal deptno secno


1 3 c 4000.00 10 s2
2 2 b 3000.00 10 s1
3 1 a 2000.00 10 s1
3 4 d 2000.00 10 s3
1 8 h 5500.00 20 s2
2 6 f 5000.00 20 s1
3 7 g 4900.00 20 s2
4 5 e 4000.00 20 s1
5 10 j 2000.00 20 s3
6 9 i 1000.00 20 s3
1 15 o 5000.00 30 s2
2 11 k 4000.00 30 s1
3 12 l 3000.00 30 s1
3 16 p 3000.00 30 s2
4 13 m 2000.00 30 s2
5 14 n 1500.00 30 s2
1 20 t 4000.00 40 s3
2 19 s 2000.00 40 s3
3 17 q 1000.00 40 s2
3 18 r 1000.00 40 s2

select row_number() over(partition by deptno order by sal desc) as rownum, emp.* from emp

rownum empno ename sal deptno secno


1 3 c 4000.00 10 s2
2 2 b 3000.00 10 s1
3 1 a 2000.00 10 s1
4 4 d 2000.00 10 s3
1 8 h 5500.00 20 s2
2 6 f 5000.00 20 s1
3 7 g 4900.00 20 s2
4 5 e 4000.00 20 s1
5 10 j 2000.00 20 s3
6 9 i 1000.00 20 s3
1 15 o 5000.00 30 s2
2 11 k 4000.00 30 s1
3 12 l 3000.00 30 s1
4 16 p 3000.00 30 s2
5 13 m 2000.00 30 s2
6 14 n 1500.00 30 s2
1 20 t 4000.00 40 s3
2 19 s 2000.00 40 s3
3 17 q 1000.00 40 s2
4 18 r 1000.00 40 s2

select row_number() over(partition by deptno order by deptno,secno) as dsrownum, emp.* from emp

dsrownum empno ename sal deptno secno


1 1 a 2000.00 10 s1
2 2 b 3000.00 10 s1
3 3 c 4000.00 10 s2
4 4 d 2000.00 10 s3
1 5 e 4000.00 20 s1
2 6 f 5000.00 20 s1
3 7 g 4900.00 20 s2
4 8 h 5500.00 20 s2
5 9 i 1000.00 20 s3
6 10 j 2000.00 20 s3
1 11 k 4000.00 30 s1
2 12 l 3000.00 30 s1
3 13 m 2000.00 30 s2
4 14 n 1500.00 30 s2
5 15 o 5000.00 30 s2
6 16 p 3000.00 30 s2
1 17 q 1000.00 40 s2
2 18 r 1000.00 40 s2
3 19 s 2000.00 40 s3
4 20 t 4000.00 40 s3

The main difference between the use of GROUP BY clause and the grouping using the PARTITION BY
clause of the OVER clause is that OVER clause displays each of the rows from a group(partition)
separately, while the GROUP BY clause displays only one row for each group as follows :

select deptno,ename,sum(sal) over(partition by deptno) as sumsal, avg(sal) over(partition by deptno) as


avgsal, count(sal) over(partition by deptno) as countsal from emp

deptno ename sumsal avgsal countsal


10 a 11000.00 2750.000000 4
10 b 11000.00 2750.000000 4
10 c 11000.00 2750.000000 4
10 d 11000.00 2750.000000 4
20 e 22400.00 3733.333333 6
20 f 22400.00 3733.333333 6
20 g 22400.00 3733.333333 6
20 h 22400.00 3733.333333 6
20 i 22400.00 3733.333333 6
20 j 22400.00 3733.333333 6
30 k 18500.00 3083.333333 6
30 l 18500.00 3083.333333 6
30 m 18500.00 3083.333333 6
30 n 18500.00 3083.333333 6
30 o 18500.00 3083.333333 6
30 p 18500.00 3083.333333 6
40 q 8000.00 2000.000000 4
40 r 8000.00 2000.000000 4
40 s 8000.00 2000.000000 4
40 t 8000.00 2000.000000 4

Following query calculates the percentage of the salary of each employee in relation to the total salary of the
corresponding partition(department)

select deptno,ename,sal,sum(sal) over(partition by deptno) as sumsal, sal/sum(sal) over(partition by deptno)


* 100 as salpercent from emp

deptno ename sal sumsal salperecnt


10 a 2000.00 11000.00 18.181818181818181818181818
10 b 3000.00 11000.00 27.272727272727272727272727
10 c 4000.00 11000.00 36.363636363636363636363636
10 d 2000.00 11000.00 18.181818181818181818181818
20 e 4000.00 22400.00 17.857142857142857142857143
20 f 5000.00 22400.00 22.321428571428571428571429
20 g 4900.00 22400.00 21.875000000000000000000000
20 h 5500.00 22400.00 24.553571428571428571428571
20 i 1000.00 22400.00 4.464285714285714285714286
20 j 2000.00 22400.00 8.928571428571428571428571
30 k 4000.00 18500.00 21.621621621621621621621622
30 l 3000.00 18500.00 16.216216216216216216216216
30 m 2000.00 18500.00 10.810810810810810810810811
30 n 1500.00 18500.00 8.108108108108108108108108
30 o 5000.00 18500.00 27.027027027027027027027027
30 p 3000.00 18500.00 16.216216216216216216216216
40 q 1000.00 8000.00 12.500000000000000000000000
40 r 1000.00 8000.00 12.500000000000000000000000
40 s 2000.00 8000.00 25.000000000000000000000000
40 t 4000.00 8000.00 50.000000000000000000000000

You may use several columns from a table to build different partitioning schemas in a query as follows :

select ename, sal,deptno,secno, dense_rank() over(partition by deptno order by sal desc) as d_rank_sal,
dense_rank() over(partition by deptno,secno order by sal desc) as ds_rank_sal from emp

ename sal deptno secno d_rank_sal ds_rank_sal


b 3000.00 10 s1 2 1
a 2000.00 10 s1 3 2
c 4000.00 10 s2 1 1
d 2000.00 10 s3 3 1
f 5000.00 20 s1 2 1
e 4000.00 20 s1 4 2
h 5500.00 20 s2 1 1
g 4900.00 20 s2 3 2
j 2000.00 20 s3 5 1
i 1000.00 20 s3 6 2
k 4000.00 30 s1 2 1
l 3000.00 30 s1 1 1
p 3000.00 30 s2 3 2
m 2000.00 30 s2 4 3
n 1500.00 30 s2 5 4
q 1000.00 40 s2 3 1
r 1000.00 40 s2 3 1
t 4000.00 40 s3 1 1
s 2000.00 40 s3 2 2

TOP n
This clause specifies the first n rows of the query result that are to be retrieved

select top 5 emp.* from emp


Will show the first 5 rows entered into the table

select top 5 emp.* from emp order by sal desc


Will show the top 5 highest paid employees

The TOP n clause is a part of the SELECT list and is written in front of all the column names in the SELECT
list. The TOPn clause can also be used with the additional PECENT option, in which case the first n percent
of the rows are retrieved from the result set.

select top 30 percent emp.* from emp


Will show the first 30 perecent rows entered into the table

select top 40 percent emp.* from emp order by sal desc


Will show the top 40 percent highest paid employees

The additional option WITH TIES specifies that additional rows will be retrieved from the query result if they
have the same value in the ORDER BY column(s) as the last row that belongs to the displayed set. The
WITH TIES option can be used only with the ORDER BY clause.

SQL Server 2005 allows you to use the TOP n clause with the update, delete and insert statements

update top(6) emp set sal=100

update top(4) emp set sal=100 where sal in (select top 10 sal from emp order by sal asc)

delete top(2) from emp

delete top(10) percent from emp where sal in (select top 50 percent emp.sal from emp order by sal desc)

Create a table emp11 which is structurally same as that of emp table as follows :
CREATE TABLE emp11( empno numeric(5, 0) NULL, ename varchar(50)NULL, sal numeric(10, 2) NULL,
deptno numeric(3, 0) NULL, secno char(4) NULL
)

insert top(5) into emp11 select top 10 emp.* from emp order by sal desc

select * from emp11


PIVOT
PIVOT rotates rows into columns by turning the unique values from one column in the expression into
multiple columns in the output, and performs aggregations where necessary on any remaining column
values that are desired in the final output.

Create the following table and add the given rows :

CREATE TABLE project_dept(


dept_name char(20) NOT NULL,
emp_cnt int NOT NULL,
budget float NULL,
date_month datetime NULL
)

DEPT_NAME EMP_CNT BUDGET DATE_MONTH


Research 5 50000 2002-02-01 00:00:00.000
Research 10 70000 2002-01-01 00:00:00.000
Research 5 65000 2002-07-01 00:00:00.000
Accounting 5 10000 2002-07-01 00:00:00.000
Accounting 10 40000 2002-01-01 00:00:00.000
Accounting 6 30000 2002-01-01 00:00:00.000
Accounting 6 40000 2003-02-01 00:00:00.000
Marketing 6 10000 2003-07-01 00:00:00.000
Marketinf 10 40000 2003-07-01 00:00:00.000
Marketing 3 30000 2003-01-01 00:00:00.000
Marketing 5 40000 2003-02-01 00:00:00.000

Create the project_dept_pivot table from the project_dept table as follows :


select *, month(date_month) as month, year(date_month) as year into project_dept_pivot from project_dept

select [1] as January, [2] as February, [7] July FROM


(Select budget, month from project_dept_pivot) p2
PIVOT
(SUM(budget)
FOR month IN([1],[2],[7])) as p

January February July


170000 130000 125000

select year, [1] as January, [2] as February, [7] July FROM


(Select budget, year, month from project_dept_pivot) p2
PIVOT
(SUM(budget)
FOR month IN([1],[2],[7])) as p

YEAR January February July


2002 140000 50000 75000
2003 30000 80000 50000

Select budget, year, month from project_dept_pivot

This means that the unique values returned by the PIVOT COLUMN MONTH column themselves become
fields in the final result set. As a result, there is a column for each MONTH number specified in the pivot
clause - in this case the month values 1,2 and 7. The BUDGET column serves as the VALUE COLUMN,
against which the columns returned in the final output, called the grouping columns, are grouped. In this
case, the grouping columns are aggregated by the SUM function.

UNPIVOT
UNPIVOT performs almost the reverse operation of PIVOT, by rotating columns into rows.

CREATE TABLE pvt (VendorID int, Emp1 int, Emp2 int, Emp3 int, Emp4 int, Emp5 int)

INSERT INTO pvt VALUES (1,4,3,5,4,4)


INSERT INTO pvt VALUES (2,4,1,5,5,5)
INSERT INTO pvt VALUES (3,4,3,5,4,4)
INSERT INTO pvt VALUES (4,4,2,5,5,4)
INSERT INTO pvt VALUES (5,5,1,5,5,5)

SELECT VendorID, Employee, Orders


FROM
(SELECT VendorID, Emp1, Emp2, Emp3, Emp4, Emp5
FROM pvt) p
UNPIVOT
(Orders FOR Employee IN
(Emp1, Emp2, Emp3, Emp4, Emp5)
)AS unpvt

VendorID Employee Orders


1 Emp1 4
1 Emp2 3
1 Emp3 5
1 Emp4 4
1 Emp5 4
2 Emp1 4
2 Emp2 1
2 Emp3 5
2 Emp4 5
2 Emp5 5
3 Emp1 4
3 Emp2 3
3 Emp3 5
3 Emp4 4
3 Emp5 4
4 Emp1 4
4 Emp2 2
4 Emp3 5
4 Emp4 5
4 Emp5 4
5 Emp1 5
5 Emp2 1
5 Emp3 5
5 Emp4 5
5 Emp5 5

Here the UNPIVOT COLUMNS Emp1, Emp2, Emp3, Emp4 and Emp5 are converted into Rows under the
Column Heading EMPLOYEE and the values of the UNPIVOT COLUMNS Emp1, Emp2, Emp3, Emp4
and Emp5 are stored under the head ORDERS
In This Article we will see how to create trigger in SQL
server 2005.

Types of Triggers

Triggers are of 3 types in SQL Server 2005:


1. DML Triggers
. AFTER Triggers
. INSTEAD OF Triggers
2. DDL Triggers
3. CLR Triggers

Note:DDL and CLR Triggers cannot work in SQL Server 2000


DML Trigger:-These Trigger is fired only when INSERT, UPDATE, and DELETE
Statement occurs in table.

Explanation on DML Trigger:


Let us create a Table and insert some records in that Table.
1) After Triggers:
After Triggers can be created in 3 ways.
1) After INSERT
2) After UPDATE
3) After DELETE

1) creating After INSERT Trigger:-

Syntax:
create trigger triggername
on tablename
AFTER INSERT
As
[SQL Statement/PRINT command]
GO

Eg:
create trigger afterinsert_trigger
on emp
AFTER INSERT
as
PRINT 'AFTER TRIGGER EXECUTED SUCESSFULLY'
GO

When you execute the afterinsert_trigger it gives message as 'The


Command(s) created successfully'
You can see the is trigger is created.
Now insert one record in a emp table. You can see the trigger will be fired
automatically when the row is inserted in a table successfully.

Creating AFTER UPDATE TRIGGER:-

create trigger afterupdate_trigger

on emp

AFTER UPDATE
as

PRINT 'AFTER UPDATE TRIGGER EXECUTED SUCESSFULLY'

GO

Creating AFTER DELETE TRIGGER:

Create trigger afterdelete_trigger

On emp

AFTER DELETE

as

PRINT 'AFTER DELETE TRIGGER EXECUTED SUCESSFULLY'

GO
Instead Of Update Trigger

Creating INSTEAD OF UPDATE TRIGGER:-

create trigger insteadofupdate_trigger


on emp
INSTEAD OF UPDATE
as
PRINT 'INSTEAD OF UPDATE TRIGGER EXECUTED SUCESSFULLY'
GO

Instead of Delete Trigger

Creating INSTEAD OF DELETE TRIGGER:-

create trigger insteadofdelete_trigger


on emp
INSTEAD OF DELETE
as
PRINT 'INSTEAD OF DELETE TRIGGER EXECUTED SUCESSFULLY'
GO

HOW TO Drop a Trigger?

Syntax: DROP TRIGGER [triggername]

Eg: DROP TRIGGER afterinsert_trigger

Você também pode gostar