SQL Server 2005

Published on March 2017 | Categories: Documents | Downloads: 56 | Comments: 0 | Views: 361
of 80
Download PDF   Embed   Report

Comments

Content

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 Warehouse and another project containing scripts to load the Data Warehouse

a Data

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 SMALLINT TINYINT BIGINT DECIMAL(p,[s]) Integer values between -2147483648(-2 ^31) to 2147483647(2^31 –1), which can be stored in 4 bytes Integer values between –32768(-2^15) to 32767(2^15 -1) , which can be stored in 2 bytes Non-Negative integers between 0 to 255, which can be stored in 1 byte. Integer values between -9223372036854775808(–2^63) to 9223372036854775807 (2^63 -1), which can be stored in 8 bytes. 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. Synonym for DECIMAL 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. Used for Floating-point values, similar to REAL. - 1.79E+308 to -2.23E308, 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) 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 Same as MONEY, but 4-byte decimal values. Values range from 214,748.3648 to 214,748.3647

NUMBER(p,[s]) REAL

FLOAT[(p)]

MONEY SMALLMONEY String Data Types CHAR[(n)] VARCHAR[(n)] NCHAR[(n)]

NVARCHAR[(n)] TEXT[(n)] NTEXT[(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. 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. 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 Unicode-String with varying length, between 0 to 4000 characters. Maximum value of n is 4000 Variable-length non-Unicode data with a maximum length of 2^311 (2,147,483,647) characters. Depending on the character string, the storage size may be less than 2,147,483,647 bytes. 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)] VARBINARY[(n)] IMAGE[(n)] BIT Fixed-length bit-string of n bytes. n is between 1 to 8000 Variable-length bit-string of upto n bytes. n is between 1 to 8000 Fixed-length bit-string of 2^31 - 1 bytes. 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) NVARCHAR(MAX) VARBINARY(MAX) They allow you to store upto 2^31 - 1 bytes of data. They are similar in behavior to Varchar, Nvarchar and Varbinary 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. 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.

SMALLDATETIME

SCALAR Functions Numeric Functions ABS(n) ACOS(n) ASIN(n) ATAN(n) ATN2(n,m) CEILING(n) COS(n) COT(n) DEGREES(n) EXP(n) FLOOR(n) LOG(n) LOG10(n) PI() POWER(x,y) RADIANS(n) RAND ROUND(n,p,t) Returns absolute value of a numeric value. ABS(-7.78)=7.78, ABS(7.87)=7.87 Calculates arc cosine of n. n and the resulting value are of type FLOAT Calculates arc sine of n. n and the resulting value are of type FLOAT Calculates arc tangent of n. n and the resulting value are of type FLOAT Calculates arc tangent of n/m .n, m and the resulting value are of type FLOAT Calculates smallest integer value greater than or equal to the specified n. Ceiling(4.88)=5, Ceiling(-4.88)= -4 Calculates the cosine of n. n and the resulting value are of type FLOAT Calculates the cotangent of n. n and the resulting value are of type FLOAT Converts radians to degrees. Degrees(PI()/2)=90.0. Degrees(0.75)=42.97 Calculates the value of e^n, where e=2.71828182845905. EXP(.75)=2.12, EXP(1)=2.71828182845905 Calculates largest integer value less than or equal to the specified n. Floor(4.88)=4 Calculates the natural logarithm of n to the base e. Calculates the logarithm of n to the base 10 Returns the value of pi(3.14) Calculates the value of x^y. POWER(3,3)=27, POWER(121,0.5)=11 Converts degrees to radians. RADIANS(90.0)=1.57 Returns a random number between 0 to 1 with a Float Data-type. 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. Returns +1, -1, 0 when n is Positive, Negative or Zero respectively. Calculates the Sine of n. n and the resulting value are of type FLOAT Calculates the square root of n. SQRT(100)=10 Returns the square of n Calculates the Tangent of n. n and the resulting value are of type FLOAT

SIGN(n) SIN(n) SQRT(n) SQUARE(n) TAN(n)

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() DATEPART(item, date) DATENAME(item, date) DATEDIFF(item, date1, date2) DATEADD(item, number, date) Returns the current system date and time Returns the specified part item of the specified date as an integer Returns the specified part item of the specified date as a character string Calculates the difference between the two dates in terms of the part item specified Adds the specified number of units to the specified part item of the specified date

SELECT GETDATE() SELECT DATEPART(MONTH,'2007-07-26'),DATEPART(MM,'2007-07-26'), DATEPART(QQ,'2007-0726'),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,'197607-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) CAST(a as type) CONVERT(type, a) CHAR(integer) CHARINDEX(s1, s2) DIFFERENCE(s1, s2) LOWER(string) UPPER(string) LTRIM(string) RTRIM(string) LEFT(string, n) RIGHT(string, n) SUBSTR(string, a,n) REPLICATE(string ,n) REVERSE(string) SPACE(n) SOUNDEX(string) STUFF(s1, a, n,s2) STR(f,l,d) NEWID() Returns the ascii value of the specified character Converts the specified expression/value ‘a’ to the specified data-type Same as Cast, parameters given differently. Returns the Character corresponding to the specified integer/ascii value Returns the start position of string s1 in the string s2. Returns 0 if s1 not found in 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 Converts the specified string to the lower case Converts the specified string to the upper case Returns the specified string after trimming the blank spaces to the left Returns the specified string after trimming the blank spaces to the right Returns the specified number of characters from the left of the given string Returns the specified number of characters from the right of the given string Returns from the position ‘a’ from the specified string specified n number of characters Replicates the specified string specified number of times Returns the reverse of the specified string Returns a string containing specified number of blank spaces 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 Replaces string s1 with n number of characters from the position a with the specified string s2 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 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() HOST_NAME() DB_ID(db_name) DB_NAME(db_id) USER_ID(user_name) USER_NAME(id) CURRENT_TIMESTAMP CURENT_USER SYSTEM_USER USER SUSER_SID(name) SUSER_SNAME(sid) OBJECT_ID(objectname) OBJECT_NAME(objid) DATALENGTH(z) ISNULL(expr, value) NULLIF(exp1, exp2) COALESCE(C1, C2, C3,C4) DATABASEPROPERTYEX( Database, property) COL_LENGTH(obj,col) COL_NAME(oid,sid) Returns the identifier of the host system Returns the name of the host Returns the identifier of the specified database Returns the name of the Database whose identifier db_id is passed as parameter Returns the identifier of the user_name Returns the name of the user whose id is passed as parameter Returns the Current Date ad Time Returns the name of the current user Returns the login ID of the current user Same as Current_user Returns the Security Identification Number(SID) of the user whose login name is passed Returns the login name of the user whose SID is passed as parameter Returns the identifier of the objectname Returns the name of the object whose objid is passed Returns the length in bytes of the expression z Returns the specified value, if the given expr is null, else returns expr Returns NULL if exp1 and exp2 are equal Returns the first non-null value from the expressions c1, c2, c3 and c4 Returns the current setting for the specified database option/property of the specified database Returns the length of the column col belonging to the database object obj(table/view) 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 @@CONNECTIONS @@VERSION @@SPID @@TOTAL_READ @@TOTAL_WRITE Returns the name of the server Returns the number of login attempts since starting the SQL Server Returns the version of SQL Software Returns the identifier of the server process Returns the total number of read operations since SQL Server was first started Returns the total number of write operations since SQL Server was

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

first started Returns the time in miliiseconds that SQL server has been idle since it was first started Returns the total CPU time in milliseconds used since starting SQL Server Returns the maximum number of connections to SQL Server Returns the current maximum number of bytes for text/image objects which can be returned by a SELECT statement Returns the name of the language that is currently used by SQL Server Returns the identifier of the language that is currently used by SQL Server 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’ 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 and

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 employee.empid=employee_hist.empid) empid=(select empid from employee_hist where

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, employee.empno=works.empno works.job from employee, works where

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 TABLEALIASNAME.COLUMNNAME

is

QUALIFIED

as

TABLENAME.COLUMNNAME

or

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 EMP.DEPTNO=DEPT.DEPTNO are displayed. nXm rows which satisfy the join condition

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

CREATE TABLE sal_grade(grade char(1), min_sal numeric, max_sal numeric) A B C D 1000 10001 20001 30001 10000 20000 30000 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 student.rollno=studmarks.rollno Inner join or Equi-join achieved by comparing the coulmns using where clause and

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 ='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 = 16,@msgtext = 'You are Wrong',@lang

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 nonclustered 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] view_name(coumn1 [ASC|DESC], coumn2 [ASC|DESC]) [INCLUDE(column1, …n)] INDEX index_name ON table_name|

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 datapages. 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.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 students.total=students.maths+students.science+students.English from students.rollno=inserted.rollno students where

inserted

set where

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 code tinyint, city varchar(50) ) varchar(50), grade tinyint, sal numeric(10,2),

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 1 a 2 b deptno secno 2000.00 10 3000.00 10

s1 s1

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

c d e f g h i j k l m n o p q r s t

4000.00 2000.00 4000.00 5000.00 4900.00 5500.00 1000.00 2000.00 4000.00 3000.00 2000.00 1500.00 5000.00 3000.00 1000.00 1000.00 2000.00 4000.00

10 10 20 20 20 20 20 20 30 30 30 30 30 30 40 40 40 40

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

8 6 15 7 3 11 5 20 12 16 2 1 4 13 19 10 14 17 18 9

h f o g c k e t l p b a d m s j n q r i

5500.00 5000.00 5000.00 4900.00 4000.00 4000.00 4000.00 4000.00 3000.00 3000.00 3000.00 2000.00 2000.00 2000.00 2000.00 2000.00 1500.00 1000.00 1000.00 1000.00

20 20 30 20 10 30 20 40 30 30 10 10 10 30 40 20 30 40 40 20

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

10 11 12 13 14 15 16 17 18 19 20

j k l m n o p q r s t

2000.00 4000.00 3000.00 2000.00 1500.00 5000.00 3000.00 1000.00 1000.00 2000.00 4000.00

20 30 30 30 30 30 30 40 40 40 40

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

select dense_rank() over(partition by deptno order by sal desc) as d_rank_sal, emp.* from emp d_rank_sal 1 2 3 3 1 2 3 4 5 6 1 2 3 3 4 5 1 2 empno ename sal 3 c 2 b 1 a 4 d 8 h 6 f 7 g 5 e 10 j 9 i 15 o 11 k 12 l 16 p 13 m 14 n 20 t 19 s deptno 4000.00 3000.00 2000.00 2000.00 5500.00 5000.00 4900.00 4000.00 2000.00 1000.00 5000.00 4000.00 3000.00 3000.00 2000.00 1500.00 4000.00 2000.00 secno 10 10 10 10 20 20 20 20 20 20 30 30 30 30 30 30 40 40 s2 s1 s1 s3 s2 s1 s2 s1 s3 s3 s2 s1 s1 s2 s2 s2 s3 s3

3 3

17 18

q r

1000.00 40 1000.00 40

s2 s2

select row_number() over(partition by deptno order by sal desc) as rownum, emp.* from emp rownum empno 1 2 3 4 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 ename sal 3 2 1 4 8 6 7 5 10 9 15 11 12 16 13 14 20 19 17 18 c b a d h f g e j i o k l p m n t s q r deptno secno 4000.00 3000.00 2000.00 2000.00 5500.00 5000.00 4900.00 4000.00 2000.00 1000.00 5000.00 4000.00 3000.00 3000.00 2000.00 1500.00 4000.00 2000.00 1000.00 1000.00 10 10 10 10 20 20 20 20 20 20 30 30 30 30 30 30 40 40 40 40 s2 s1 s1 s3 s2 s1 s2 s1 s3 s3 s2 s1 s1 s2 s2 s2 s3 s3 s2 s2

select row_number() over(partition by deptno order by deptno,secno) as dsrownum, emp.* from emp dsrownum 1 2 3 4 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 empno ename sal 1 a 2 b 3 c 4 d 5 e 6 f 7 g 8 h 9 i 10 j 11 k 12 l 13 m 14 n 15 o 16 p 17 q 18 r 19 s 20 t deptno 2000.00 3000.00 4000.00 2000.00 4000.00 5000.00 4900.00 5500.00 1000.00 2000.00 4000.00 3000.00 2000.00 1500.00 5000.00 3000.00 1000.00 1000.00 2000.00 4000.00 secno 10 10 10 10 20 20 20 20 20 20 30 30 30 30 30 30 40 40 40 40 s1 s1 s2 s3 s1 s1 s2 s2 s3 s3 s1 s1 s2 s2 s2 s2 s2 s2 s3 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 10 b 11000.00 2750.000000 4 4

10 10 20 20 20 20 20 20 30 30 30 30 30 30 40 40 40 40

c d e f g h i j k l m n o p q r s t

11000.00 2750.000000 11000.00 2750.000000 22400.00 3733.333333 22400.00 3733.333333 22400.00 3733.333333 22400.00 3733.333333 22400.00 3733.333333 22400.00 3733.333333 18500.00 3083.333333 18500.00 3083.333333 18500.00 3083.333333 18500.00 3083.333333 18500.00 3083.333333 18500.00 3083.333333 8000.00 2000.000000 8000.00 2000.000000 8000.00 2000.000000 8000.00 2000.000000

4 4 6 6 6 6 6 6 6 6 6 6 6 6 4 4 4 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 10 a 10 b 10 c 10 d 20 e 20 f 20 g 20 h 20 i 20 j 30 k 30 l 30 m 30 n 30 o 30 p 40 q 40 r 40 s 40 t 2000.00 3000.00 4000.00 2000.00 4000.00 5000.00 4900.00 5500.00 1000.00 2000.00 4000.00 3000.00 2000.00 1500.00 5000.00 3000.00 1000.00 1000.00 2000.00 4000.00 sumsal salperecnt 11000.00 18.181818181818181818181818 11000.00 27.272727272727272727272727 11000.00 36.363636363636363636363636 11000.00 18.181818181818181818181818 22400.00 17.857142857142857142857143 22400.00 22.321428571428571428571429 22400.00 21.875000000000000000000000 22400.00 24.553571428571428571428571 22400.00 4.464285714285714285714286 22400.00 8.928571428571428571428571 18500.00 21.621621621621621621621622 18500.00 16.216216216216216216216216 18500.00 10.810810810810810810810811 18500.00 8.108108108108108108108108 18500.00 27.027027027027027027027027 18500.00 16.216216216216216216216216 8000.00 12.500000000000000000000000 8000.00 12.500000000000000000000000 8000.00 25.000000000000000000000000 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 b a c d f e 3000.00 2000.00 4000.00 2000.00 5000.00 4000.00 deptno secno 10 10 10 10 20 20 s1 s1 s2 s3 s1 s1 d_rank_sal 2 3 1 3 2 4 ds_rank_sal 1 2 1 1 1 2

h g j i k l p m n q r t s

5500.00 4900.00 2000.00 1000.00 4000.00 3000.00 3000.00 2000.00 1500.00 1000.00 1000.00 4000.00 2000.00

20 20 20 20 30 30 30 30 30 40 40 40 40

s2 s2 s3 s3 s1 s1 s2 s2 s2 s2 s2 s3 s3

1 3 5 6 2 1 3 4 5 3 3 1 2

1 2 1 2 1 1 2 3 4 1 1 1 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 Research Research Research Accounting Accounting Accounting Accounting Marketing Marketinf Marketing Marketing EMP_CNT 5 10 5 5 10 6 6 6 10 3 5 BUDGET 50000 70000 65000 10000 40000 30000 40000 10000 40000 30000 40000 DATE_MONTH 2002-02-01 00:00:00.000 2002-01-01 00:00:00.000 2002-07-01 00:00:00.000 2002-07-01 00:00:00.000 2002-01-01 00:00:00.000 2002-01-01 00:00:00.000 2003-02-01 00:00:00.000 2003-07-01 00:00:00.000 2003-07-01 00:00:00.000 2003-01-01 00:00:00.000 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 2002 2003 January February 140000 50000 30000 80000 July 75000 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 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5 Employee Emp1 Emp2 Emp3 Emp4 Emp5 Emp1 Emp2 Emp3 Emp4 Emp5 Emp1 Emp2 Emp3 Emp4 Emp5 Emp1 Emp2 Emp3 Emp4 Emp5 Emp1 Emp2 Emp3 Emp4 Emp5 Orders 4 3 5 4 4 4 1 5 5 5 4 3 5 4 4 4 2 5 5 4 5 1 5 5 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

Sponsor Documents

Or use your account on DocShare.tips

Hide

Forgot your password?

Or register your new account on DocShare.tips

Hide

Lost your password? Please enter your email address. You will receive a link to create a new password.

Back to log-in

Close