Está en la página 1de 18

New Features in SQL Server 2008

1) Variable declaration allows initialization:


2005:
DECLARE @COUNT INT
SET @COUNT =100
2008:
DECLARE @COUNT INT =100
2) Insert multiple rows using single INSERT Statement
2005:
INSERT INTO dbo.Employee VALUES(1,'Basavaraj')
INSERT INTO dbo.Employee VALUES(2,'Shashank')
INSERT INTO dbo.Employee VALUES(3,'Monty')
2008:
INSERT INTO dbo.Employee VALUES(1,'Basavaraj') ,
(2,'Shashank'),(3,'Monty')
3) Arithmetic Assignment Operators
Operator Usage
Description
+=
SET @x+=@y
Same as: SET
-=
SET @x-=@y
Same as: SET
*=
SET @x*=@y
Same as: SET
/=
SET @x/=@y
Same as: SET
%=
SET @x%=@y
Same as: SET

@x
@x
@x
@x
@x

=
=
=
=
=

@x
@x
@x
@x
@x

+
*
/
%

@y
@y
@y
@y
@y

Example:
DEClARE @x INT =2 ,@y INT = 2
SET @x+=@y
SELECT @x as x,@y as y
Result:
x
y
----------- ----------4
2
4) Table-Valued Parameters in Sql Server:
This is a new feature intorduced in Sql Server 2008. Table-Valued
Parameters provides option for the Client Applications to pass multiple
rows of Data to Stored Procedure.Prior to this, if we were needed to
pass multiple rows of Data from client application to Sql Server, then
we use to model the input data as xml and pass it to the stored
procedure and in Stored Procedure convert this xml to a table
variable/temporary table.
5) MERGE Statement
6) Sparse Column
Sparse Column is one more new feature introduced in SQL SERVER
2008. Storing a null value in a sparse column doesnt take any space,
but storing a non-null value in sparse column takes 4 bytes extra space
than the non-sparse columns of the same data type.
7) Date and Time Data Types
Date, Time, DateTime2 etc are the new date and time data type
introduced in SQL SERVER 2008.
Ex:
Select getdate()
For Date time
Select Sysdatetime()
-> For Datetime2(7)
8) XML Implementation

9)Data Encrypting

How to increase Procedure Performance :


Include SET NOCOUNT ON statement: With every SELECT and DML statement,
the SQL server returns a message that indicates the number of affected
rows by that statement. This information is mostly helpful in debugging
the code, but it is useless after that. By setting SET NOCOUNT ON, we
can disable the feature of returning this extra information. For stored
procedures that contain several statements or contain Transact-SQL
loops, setting SET NOCOUNT to ON can provide a significant performance
boost because network traffic is greatly reduced.
CREATE PROC dbo.ProcName
AS
SET NOCOUNT ON;
--Procedure code here
SELECT column1 FROM dbo.TblTable1
-- Reset SET NOCOUNT to OFF
SET NOCOUNT OFF;
GO

Use schema name with object name: The object name is qualified if used
with schema name. Schema name should be used with the stored procedure
name and with all objects referenced inside the stored procedure. This
help in directly finding the complied plan instead of searching the
objects in other possible schema before finally deciding to use a cached
plan, if available. This process of searching and deciding a schema for
an object leads to COMPILE lock on stored procedure and decreases the
stored procedures performance. Therefore, always refer the objects with
qualified name in the stored procedure like
SELECT * FROM dbo.MyTable -- Preferred method
-- Instead of
SELECT * FROM MyTable -- Avoid this method
--And finally call the stored procedure with qualified name like:
EXEC dbo.MyProc -- Preferred method
--Instead of
EXEC MyProc -- Avoid this method

Do not use the prefix sp_ in the stored procedure name: If a stored
procedure name begins with SP_, then SQL server first searches in the
master database and then in the current session database. Searching in
the master database causes extra overhead and even a wrong result if
another stored procedure with the same name is found in master database.
Use IF EXISTS (SELECT 1) instead of (SELECT *): To check the existence
of a record in another table, we uses the IF EXISTS clause. The IF
EXISTS clause returns True if any value is returned from an internal
statement, either a single value 1 or all columns of a record or
complete recordset. The output of the internal statement is not used.
Hence, to minimize the data for processing and network transferring, we
should use 1 in the SELECT clause of an internal statement, as shown
below:

IF EXISTS (SELECT 1 FROM sysobjects


WHERE name = 'MyTable' AND type = 'U')

Use the sp_executesql stored procedure instead of the EXECUTE statement.


The sp_executesql stored procedure supports parameters. So, using the
sp_executesql stored procedure instead of the EXECUTE statement improve
the re-usability of your code. The execution plan of a dynamic statement
can be reused only if each and every character, including case, space,
comments and parameter, is same for two statements. For example, if we
execute the below batch:
DECLARE @Query VARCHAR(100)
DECLARE @Age INT
SET @Age = 25
SET @Query = 'SELECT * FROM dbo.tblPerson WHERE Age = ' + CONVERT(VARCHAR(3),@Ag
e)
EXEC (@Query)

If we again execute the above batch using different @Age value, then the
execution plan for SELECT statement created for @Age =25 would not be
reused. However, if we write the above batch as given below,
DECLARE @Query NVARCHAR(100)
SET @Query = N'SELECT * FROM dbo.tblPerson WHERE Age = @Age'
EXECUTE sp_executesql @Query, N'@Age int', @Age = 25

the compiled plan of this SELECT statement will be reused for different
value of @Age parameter. The reuse of the existing complied plan will
result in improved performance.
Try to avoid using SQL Server cursors whenever possible: Cursor uses a
lot of resources for overhead processing to maintain current record
position in a recordset and this decreases the performance. If we need
to process records one-by-one in a loop, then we should use the WHILE
clause. Wherever possible, we should replace the cursor-based approach
with SET-based approach. Because the SQL Server engine is designed and
optimized to perform SET-based operation very fast. Again, please note
cursor is also a kind of WHILE Loop.
Keep the Transaction as short as possible: The length of transaction
affects blocking and deadlocking. Exclusive lock is not released until
the end of transaction. In higher isolation level, the shared locks are
also aged with transaction. Therefore, lengthy transaction means locks
for longer time and locks for longer time turns into blocking. In some
cases, blocking also converts into deadlocks. So, for faster execution
and less blocking, the transaction should be kept as short as possible.
Use TRY-Catch for error handling: Prior to SQL server 2005 version code
for error handling, there was a big portion of actual code because an
error check statement was written after every t-sql statement. More code
always consumes more resources and time. In SQL Server 2005, a new
simple way is introduced for the same purpose. The syntax is as
follows:BEGIN TRY
--Your t-sql code goes here
END TRY
BEGIN CATCH

--Your error handling code goes here


END CATCH

(OR)
1- use SET NOCOUNT ON
2- avoid using UNION statements
3- use WITH (NOLOCK) with each SELECT statement
4- avoid using NESTED Select statements
5- use #temp tables
6- avoid renaming tables in SELECT statements, for example SELECT * FROM
tblClients C

Difference between Truncate and Delete in SQL


Truncate and Delete both are used to delete data from the table. These both command will
only delete data of the specified table, they cannot remove the whole table data structure.Both
statements delete the data from the table not the structure of the table.

TRUNCATE is a DDL (data definition language) command whereas DELETE is a DML


(data manipulation language) command.

You can use WHERE clause(conditions) with DELETE but you can't use WHERE clause
with TRUNCATE .
You cann't rollback data in TRUNCATE but in DELETE you can rollback data.TRUNCATE
removes(delete) the record permanently.
A trigger doesnt get fired in case of TRUNCATE whereas Triggers get fired in DELETE
command.
If tables which are referenced by one or more FOREIGN KEY constraints then
TRUNCATE will not work.
TRUNCATE resets the Identity counter if there is any identity column present in the
table where delete not resets the identity counter.
Delete and Truncate both are logged operation. But DELETE is a logged operation on a
per row basis and TRUNCATE logs the DE allocation of the data pages in which the
data exists.
TRUNCATE is faster than DELETE.

Difference between Stored procedure and User Functions


In many situation you can do the same task using either a stored procedure or a function.
Fundamental difference between Stored procedure vs User Functions:

Procedure may return none or more values. Function must always return one value
either a scalar value or a table.
Procedure have input, output parameters. Functions have only input parameters.
Stored procedures are called independently by EXEC command whereas Functions are
called from within SQL statement.
Functions can be called from procedure. Procedures cannot be called from function.
Exception can be handled in Procedure by try-catch block but try-catch block cannot
be used in a function.(error-handling)
Transaction management possible in procedure but not in function

Difference between Primary Key and Unique Key

Both Primary Key and Unique Key give uniqueness of the column on which they are
defined.

By default Unique Key creates a nonclustered index whereas Primary Key creates a
clustered index on the column.
A Primary key value cannot be NULL whereas Unique Key allows only one NULL.

Data Types:

nchar and nvarchar can store Unicode characters.


char and varchar cannot store Unicode characters.
char and nchar are fixed-length which will reserve storage space for number of
characters you specify even if you don't use up all that space.
varchar and nvarchar are variable-length which will only use up spaces for the
characters you store. It will not reserve storage like char or nchar.
1. Set NOCOUNT ON
Stops the message indicating the number of rows affected by a Transact-SQL
statement from being returned as part of the results.

Syntax
SET NOCOUNT { ON | OFF }

Remarks
When SET NOCOUNT is ON, the count (indicating the number of rows affected
by a Transact-SQL statement) is not returned. When SET NOCOUNT is OFF, the
count is returned.
2. Set IDENTITY_INSERT TableName ON

Syntax
SET IDENTITY_INSERT [ database. [ owner. ] ] { table } { ON | OFF }

Arguments
database
Is the name of the database in which the specified table resides.
owner
Is the name of the table owner.
Table
Is the name of a table with an identity column.
Ex: SET IDENTITY_INSERT products ON
GO
-- Attempt to insert an explicit ID value of 3
INSERT INTO products (id, product) VALUES(3, 'garden shovel')
3.
4.
5.
6.
7.
8.
9.

@@identity SELECT @@IDENTITY


ident_current(table name),
scope_identity,
@@rowcount
@@error
Identity(seed,increment)
RaiseError for user defined message

Row Number & Rank:

SELECT p.FirstName, p.LastName


,ROW_NUMBER() OVER (ORDER BY a.PostalCode) AS "Row Number"
,RANK() OVER (ORDER BY a.PostalCode) AS Rank
,DENSE_RANK() OVER (ORDER BY a.PostalCode) AS "Dense Rank"
,NTILE(4) OVER (ORDER BY a.PostalCode) AS Quartile
,s.SalesYTD, a.PostalCode
FROM Sales.SalesPerson AS s
INNER JOIN Person.Person AS p
ON s.BusinessEntityID = p.BusinessEntityID
INNER JOIN Person.Address AS a
ON a.AddressID = p.BusinessEntityID
WHERE TerritoryID IS NOT NULL
AND SalesYTD <> 0;
Queries:

Merge Query: (Without using cursors)


MERGE InventoryMaster AS im
USING
(SELECT InventoryID, Descr FROM NewInventory) AS src
ON
im. InventoryID = src. InventoryID WHEN MATCHED THEN
UPDATE SET im.Descr = src.Descr
WHEN NOT MATCHED THEN
--when not matched and src.desc is not
null
INSERT (InventoryID, Descr) VALUES (src. InventoryID, src.Descr);
Delete Duplicate Data:
Delete from dbo.HR_REC_Personal
WHERE dbo.HR_REC_Personal.%%physloc%%
NOT IN (SELECT MIN(b.%%physloc%%)
FROM dbo.HR_REC_Personal b where b.U_Stat_flg = 'A'
GROUP BY b.HR_REC_Id) and U_Stat_flg = 'A';
(Or)
delete dup from(select ROW_NUMBER() over(partition by id order by id)
cnt from emp) dup where dup.cnt>1
Create New Table from already Existing table:
SELECT * INTO Bak_coal_agrtaxdet FROM Coal_Agrtaxdet;
Find the data rownumber wise:
select row_number() over(order by empname) rownum, e.* from emp e order
by empid
top 3 salaries:
select top(3) e.sal,e.* from emp e order by e.sal desc
top 3rd one salary:
select top(1) sal from (select top(3) e.sal from emp e order by e.sal
desc) e order by sal asc
(or)
select * from emp e1 where 2=(select count(distinct(e2.sal)) from emp e2
where e2.sal>e1.sal)

Rank wise:
select rank() over(order by sal desc) ranks,e.* from emp e order by sal
desc
Populate the number from 1 to 10:
select level from emp connect by level<=10
Dense rank:
select dense_rank() over(order by sal asc) ranks,e.* from emp e order by
sal asc
Lessthan averase salary for each dept:
select e.empno,e.ename,e.sal,deptno from emp e where e.sal<=(select
avg(e1.sal) from emp e1 where e.deptno=e1.deptno group by e1.deptno)
order by e.deptno
How to get multiple row values with comma separate in single column:
select replace(''''|| RTRIM(XMLAGG(XMLELEMENT(e,rep_emp_code || ' ' ||
','|| ' ')).EXTRACT('//text()'),','),' ','''')||'''' AS REP_EMP_CODE
from auditee where aud_code='PSRH'
Stuff Function in SQL:
SELECT STUFF('abcdef', 2, 3, 'ijklmn');
Output: aijklmnef
Partition:
select employee_name, salary, rank() OVER (PARTITION BY department ORDER BY salary)
from employees where department = 'Marketing'
who are the employees in each reporting manager:
select distinct e.empid,e.empname,e.rptmgr from emp e,emp e1 where
e.rptmgr=e1.empno
-- Get Current Session ID
SELECT @@SPID AS Current_SessionID
-- Create Temp Table and insert three thousand rows
CREATE TABLE #TempTable (Col1 INT)
INSERT INTO #TempTable (Col1)
SELECT TOP 3000 ROW_NUMBER() OVER(ORDER BY a.name)
FROM sys.all_objects a
CROSS JOIN sys.all_objects b
GO
-- Create Table Variable and insert three thousand rows
DECLARE @temp TABLE(Col1 INT)
INSERT INTO @temp (Col1)
SELECT TOP 3000 ROW_NUMBER() OVER(ORDER BY a.name)
FROM sys.all_objects a
CROSS JOIN sys.all_objects b
-- Clean up
DROP TABLE #TempTable

Rollup
SELECT CASE WHEN (GROUPING(Item) = 1) THEN 'ALL'

ELSE ISNULL(Item, 'UNKNOWN')


END AS Item,
CASE WHEN (GROUPING(Color) = 1) THEN 'ALL'
ELSE ISNULL(Color, 'UNKNOWN')
END AS Color,
SUM(Quantity) AS QtySum
FROM Inventory
GROUP BY Item, Color WITH ROLLUP
Item
-------------------Chair
Chair
Chair
Table
Table
Table
ALL

Color
-------------------Blue
Red
ALL
Blue
Red
ALL
ALL

QtySum
-------------------------101.00
210.00
311.00
124.00
223.00
347.00
658.00

Data access mode = Table or view fast load Or


Table name or view name variable fast load,
If you check option "Keep identity" then you can map a IDENTITY column. Keep
identity: Specify whether to copy identity values when data is loaded. This property
is available only with the fast load Or Table name or view name variable fast
load option.
The default value of this property is false (Unchecked) which means you can not map
IDENTITY Column.
In your ETL Package If you have checked option "Keep identity" and once load
completed then you want to enable IDENTITY Column properties then you need to
execute "SET IDENTITY_INSERT Schema_Name.Table_Name OFF".
For Example:
This example creates a table with an identity column and shows how the SET
IDENTITY_INSERT setting can be used to fill a gap in the identity values caused by a
DELETE statement.
-- Create products table.
CREATE TABLE products (id int IDENTITY PRIMARY KEY, product varchar(40))
GO
-- Inserting values into products table.
INSERT INTO products (product) VALUES ('screwdriver')
INSERT INTO products (product) VALUES ('hammer')
INSERT INTO products (product) VALUES ('saw')
INSERT INTO products (product) VALUES ('shovel')
GO
-- Create a gap in the identity values.
DELETE products
WHERE product = 'saw'
GO

SELECT *
FROM products
GO
-- Attempt to insert an explicit ID value of 3;
-- should return a warning.
INSERT INTO products (id, product) VALUES(3, 'garden shovel')
GO
-- SET IDENTITY_INSERT to ON.
SET IDENTITY_INSERT products ON
GO
-- Attempt to insert an explicit ID value of 3
INSERT INTO products (id, product) VALUES(3, 'garden shovel').
GO
SELECT *
FROM products
GO
-- Drop products table.
DROP TABLE products
GO

Date Formats:
CONVERT(VARCHAR(19),GETDATE())
CONVERT(VARCHAR(10),GETDATE(),10)
CONVERT(VARCHAR(10),GETDATE(),110) only for Date
CONVERT(VARCHAR(11),GETDATE(),6)
CONVERT(VARCHAR(11),GETDATE(),106)
CONVERT(VARCHAR(24),GETDATE(),113) Date and Time
CONVERT(VARCHAR(5),GETDATE(),114)for Time OR 108 ALSO 100 for AM or PM
Convert(date,01-Oct-2013,106)
Sy: select replace(convert(varchar(24),getdate(),113),' ','-') date

select replace(convert(varchar(11),getdate(),106),' ','-') date


Value
(century yy)

Value
(century yyyy)

Input/Output

Standard

0 or 100

mon dd yyyy hh:miAM (or PM)

Default

101

mm/dd/yy

USA

102

yy.mm.dd

ANSI

103

dd/mm/yy

British/French

104

dd.mm.yy

German

105

dd-mm-yy

Italian

106

dd mon yy

107

Mon dd, yy

108

hh:mm:ss

9 or 109

mon dd yyyy hh:mi:ss:mmmAM (or PM)

Default+millisec

10

110

mm-dd-yy

USA

11

111

yy/mm/dd

Japan

12

112

yymmdd

ISO

13 or 113

dd mon yyyy hh:mi:ss:mmm (24h)

14

114

hh:mi:ss:mmm (24h)

20 or 120

yyyy-mm-dd hh:mi:ss (24h)

21 or 121

yyyy-mm-dd hh:mi:ss.mmm (24h)

126

yyyy-mm-ddThh:mi:ss.mmm (no spaces)

ISO8601

130

dd mon yyyy hh:mi:ss:mmmAM

Hijiri

131

dd/mm/yy hh:mi:ss:mmmAM

Hijiri

convert(varchar(7), <date_field>, 120)


because 120 results in 'yyyy-MM-dd' which is varchar(10)
using varchar(7) will display only year and month
example:
select convert(varchar(7), <date_field>, 120), COUNT(*)
from <some_table>
group by convert(varchar(7), <date_field>, 120)
order by 1

Common Table Expressions(CTE)


Cursors
This temporary work area is used to store the data retrieved from the database, and
manipulate this data. A cursor can hold more than one row, but can process only one row at a
time. The set of rows the cursor holds is called the active set.
There are two types of cursors in PL/SQL:

Implicit cursors
These are created by default when DML statements like, INSERT, UPDATE, and
DELETE statements are executed. They are also created when a SELECT statement that
returns just one row is executed.

Explicit cursors
They must be created when you are executing a SELECT statement that returns more
than one row. Even though the cursor stores multiple records, only one record can be
processed at a time, which is called as current row. When you fetch a row the current row
position moves to next row.
Both implicit and explicit cursors have the same functionality, but they differ in the way
they are accessed.
To work with cursors you must use the following SQL statements:
DECLARE CURSOR
OPEN
FETCH
CLOSE
The following example demonstrates the basic use of a read-only cursor within an SQL
procedure:
CREATE PROCEDURE sum_salaries(OUT sum INTEGER)
LANGUAGE SQL
BEGIN
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE p_sum INTEGER;
DECLARE p_sal INTEGER;
DECLARE c CURSOR FOR SELECT SALARY FROM EMPLOYEE;
SET p_sum = 0;
OPEN c;
FETCH FROM c INTO p_sal;
WHILE(SQLSTATE = '00000') DO
SET p_sum = p_sum + p_sal;
FETCH FROM c INTO p_sal;
END WHILE;
CLOSE c;
SET sum = p_sum;
END%

About TL:

Role as Team member, Gathering requirements and analysis for new


applications and enhancement of existing modules (Windows or Web).
Supporting to FAS (Financial Accounting System), PRR (Payment Release
Request), BMS (Budget Monitoring System), TAX Module, TA Bill, SMTS
applications for respective departments.
Giving technical support to all site people on our business applications.
Providing ad-hoc reports on requirement basis.
Time line support given to team members whenever they are required.
Fortunately or UN officially, Indirectly I have two member team and could
able to guide them, motivate them, resolve their issues if they stuck
anywhere in logic.

Indexes
Triggers : Instead, After Triggers

Tempary Tables
Hash Tables
Functions
Common Table Expressions
---------------------------------------------------------------------------You can turn autocommit ON by setting implicit_transactions OFF:
SET IMPLICIT_TRANSACTIONS OFF
When the setting is ON, it returns to implicit transaction mode. In implicit transaction mode,
every change you make starts a transactions which you have to commit manually.
Maybe an example is clearer. This will write a change to the database:
SET IMPLICIT_TRANSACTIONS ON
UPDATE MyTable SET MyField = 1 WHERE MyId = 1
COMMIT TRANSACTION
This will not write a change to the database:
SET IMPLICIT_TRANSACTIONS ON
UPDATE MyTable SET MyField = 1 WHERE MyId = 1
ROLLBACK TRANSACTION
The following example will update a row, and then complain that there's no transaction to
commit:
SET IMPLICIT_TRANSACTIONS OFF
UPDATE MyTable SET MyField = 1 WHERE MyId = 1
ROLLBACK TRANSACTION
Like Mitch Wheat said, autocommit is the default for Sql Server 2000 and up.
System Variables:
@@error

Error number

@@identity

Latest identity value of newly inserted record

@@language

Language currently in use

@@max_connections

Maximum connections allowed to the server

@@rowcount

Number of records affected by last command

@@rowcount

Number of rows affected by last statement

@@servername
@@version

SQL Server name


Version number of SQL Server

Other system information is returned from scalar functions:


DB_NAME()

Database Name

SUSER_SNAME()

NT User Name

USER_NAME()

SQL Server User Name

sp_helpdb

Details of the databases defined on the server.

sp_helpdb pubs

Details of the pubs database.

sp_help authors

Provides details on any database object.

sp_helptext byroyalry

Provides the text of a stored procedure.

sp_depends authors

Details of all objects that debend on the specified


object.

sp_changeowner

Change the owner of an object (usually to dbo).

sp_rename

Rename an object.

Bulk Insert:
BULK INSERT TmpStList FROM '"+@PathFileName+"'
'"",""')

WITH (FIELDTERMINATOR =

Triggers:
In Orcle:
create or replace
TRIGGER "ACCTS".TR_USERS AFTER INSERT ON SLMST
FOR EACH ROW
BEGIN
if :new.typ = 5 then
insert into sale.users(user_id,pwd,uname,loc,rights,stat) values
(:new.code,:new.code,:new.name,0,'USER','N');
end if;
END;
In Sqlserver:
1. After Triggers
2. Instead of Triggers
After Insert Trigger
1.

-- Create trigger on table Employee_Demo for Insert statement

2. CREATE TRIGGER trgAfterInsert on Employee_Demo


3. FOR INSERT
4. AS

declare

@empid

int,

@empname

decimal(10,2), @audit_action varchar(100);

varchar(55),

@empsal

5. select @empid=i.Emp_ID from inserted i;


6. select @empname=i.Emp_Name from inserted i;
7. select @empsal=i.Emp_Sal from inserted i;
8. set

@audit_action='Inserted

Record

--

After

Insert

Trigger.';

insert

into

Employee_Demo_Audit(Emp_ID,Emp_Name,Emp_Sal,Audit_Action,Audit_Tim
estamp)
9. values (@empid,@empname,@empsal,@audit_action,getdate());
10. PRINT 'AFTER INSERT trigger fired.'

After Update Trigger


1.

-- Create trigger on table Employee_Demo for Update statement

2. CREATE TRIGGER trgAfterUpdate ON dbo.Employee_Demo


3. FOR UPDATE
4. AS
5. declare @empid int, @empname varchar(55), @empsal decimal(10,2),
@audit_action varchar(100);
6. select @empid=i.Emp_ID from inserted i;
7. select @empname=i.Emp_Name from inserted i;
8. select @empsal=i.Emp_Sal from inserted i; if update(Emp_Name)
9.

set @audit_action='Update Record --- After Update Trigger.';

10. if update (Emp_Sal)


11.

set @audit_action='Update Record --- After Update Trigger.';

12. insert
intoEmployee_Demo_Audit(Emp_ID,Emp_Name,Emp_Sal,Audit_Action,Audit
_Timestamp)
13. values (@empid,@empname,@empsal,@audit_action,getdate());
14. PRINT 'AFTER UPDATE trigger fired.'

After Delete Trigger


1.

-- Create trigger on table Employee_Demo for Delete statement

2. CREATE TRIGGER trgAfterDelete ON dbo.Employee_Demo


3. FOR DELETE
4. AS
5. declare @empid int, @empname varchar(55), @empsal decimal(10,2),
@audit_action varchar(100); select @empid=d.Emp_ID FROM deleted d;

6. select @empname=d.Emp_Name from deleted d;


7. select @empsal=d.Emp_Sal from deleted d;
8. select @audit_action='Deleted -- After Delete Trigger.';
9. insert

into

Employee_Demo_Audit

(Emp_ID,Emp_Name,Emp_Sal,Audit_Action,Audit_Timestamp)
10. values (@empid,@empname,@empsal,@audit_action,getdate());
11. PRINT 'AFTER DELETE TRIGGER fired.'

Instead of Insert Trigger


1.

-- Create trigger on table Employee_Demo for Insert statement

2. CREATE TRIGGER trgInsteadOfInsert ON dbo.Employee_Demo


3. INSTEAD OF Insert
4. AS
5. declare

@emp_id

int,

@emp_name

varchar(55),

@emp_sal

decimal(10,2), @audit_action varchar(100);


6. select @emp_id=i.Emp_ID from inserted i;
7. select @emp_name=i.Emp_Name from inserted i;
8. select @emp_sal=i.Emp_Sal from inserted i;
9. SET @audit_action='Inserted Record -- Instead Of Insert Trigger.';
10. BEGIN
11.

BEGIN TRAN

12.

SET NOCOUNT ON

13.

if(@emp_sal>=1000)

14.

begin

15.

RAISERROR('Cannot Insert where salary < 1000',16,1); ROLLBACK;


end

16.

else begin Insert into Employee_Demo (Emp_Name,Emp_Sal) values


(@emp_name,@emp_sal);

Insert

into

Employee_Demo_Audit(Emp_ID,Emp_Name,Emp_Sal,Audit_Action,Audit_Tim
estamp)
values(@@identity,@emp_name,@emp_sal,@audit_action,getdate());
17.

COMMIT;

18.

PRINT 'Record Inserted -- Instead Of Insert Trigger.'

19. END

Instead of Update Trigger


1.

-- Create trigger on table Employee_Demo for Update statement

2. CREATE TRIGGER trgInsteadOfUpdate ON dbo.Employee_Demo


3. INSTEAD OF Update
4. AS
5. declare

@emp_id

int,

@emp_name

varchar(55),

@emp_sal

decimal(10,2), @audit_action varchar(100);


6. select @emp_id=i.Emp_ID from inserted i;
7. select @emp_name=i.Emp_Name from inserted i;
8. select @emp_sal=i.Emp_Sal from inserted i;
9. BEGIN
10.

BEGIN TRAN

11. if(@emp_sal>=1000)
12.

begin

13.

RAISERROR('Cannot Insert where salary < 1000',16,1); ROLLBACK;


end

14.

else begin

15.

insert

into

Employee_Demo_Audit(Emp_ID,Emp_Name,Emp_Sal,Audit_Action,Audit_Tim
estamp)
values(@emp_id,@emp_name,@emp_sal,@audit_action,getdate());
16.

COMMIT;

17.

PRINT 'Record Updated -- Instead Of Update Trigger.'; END

Instead of Delete Trigger


1.

-- Create trigger on table Employee_Demo for Delete statement

2. CREATE TRIGGER trgAfterDelete ON dbo.Employee_Demo


3. INSTEAD OF DELETE
4. AS
5. declare @empid int, @empname varchar(55), @empsal decimal(10,2),
@audit_action varchar(100); select @empid=d.Emp_ID FROM deleted d;
6. select @empname=d.Emp_Name from deleted d;
7. select @empsal=d.Emp_Sal from deleted d;
8. BEGIN TRAN if(@empsal>1200) begin
9.
10.

RAISERROR('Cannot delete where salary > 1200',16,1);


ROLLBACK;

11.

end

12.

else begin

13.

delete from Employee_Demo where Emp_ID=@empid;

14.

COMMIT;

15.

insert

into

Employee_Demo_Audit(Emp_ID,Emp_Name,Emp_Sal,Audit_Action,Audit_Tim
estamp)
16.

values(@empid,@empname,@empsal,'Deleted --

Instead Of

Delete

Trigger.',getdate());
17.

PRINT 'Record Deleted -- Instead Of Delete Trigger.' end END

Procedures with out put parameters:


Syntax in Oracle:
create or replace PROCEDURE MAT_SELECT(SPSPEC IN nvarchar2, RESULTS OUT
SYS_REFCURSOR)
IS
BEGIN
OPEN RESULTS FOR select EXCELSNO,
SNO,SHIPMENTNO,PCKAGENO,BBUNO,L2,L3,KKSNO,PARTNAME,L2PCKLSTNO
PAKINGLIST_NO,DRAWINGNO,SPEC,QTY,ENGQTY Engineer_Qty,L3REMARKS Remarks
from SELFLEARN.MAT_L3MASTER where SPEC=SPSPEC;
RETURN;
END MAT_SELECT;

Syntax in SQl:
Alter PROCEDURE GetstudentnameInOutputVariable
(
@studentid INT,
--Input parameter , Studentid of the student
@studentname VARCHAR (200) OUT, -- Output parameter to collect the student name
@StudentEmail VARCHAR (200)OUT
-- Output Parameter to collect the student email
)
AS
BEGIN
SELECT @studentname= Firstname+' '+Lastname,
@StudentEmail=email FROM tbl_Students WHERE studentid=@studentid
END

ALTER PROCEDURE [dbo].[sp_web_orders_insert]


(
@userId int = default,
@custId int = default,
@orderDate datetime = default,
@orderTotal money = default,
@order_ID INT output,
@orderReferenceOutput varchar(50) output
)
AS
SET NOCOUNT OFF;

INSERT INTO [web_orders] ([user_ID], [cust_ID], [orderDate], [orderTotal]) VALUES


(@userId, @custId, @orderDate, @orderTotal);
SELECT @order_ID = @@IDENTITY
RETURN @order_ID
SELECT @orderReferenceOutput = 'PLC' + REPLICATE('0', (7 - LEN((select
MAX(order_ID) from web_orders)))) + CAST((select(max(order_ID)+1) from
web_orders) AS VARCHAR(5))
RETURN @orderReferenceOutput

Functions:
Syntax in Oracle:
create or replace FUNCTION FUN_PTYCR(SLCD VARCHAR2) RETURN NUMBER AS
TDS NUMBER(15,2);
TDS1 NUMBER(15,2);
BEGIN
TDS:=0;
select NVL(sum(tds),0) INTO TDS1 from rep_ptycr where v_no in(select v_no from
rep_ptycr where slcode=SLCD); --pcode= slcd;
TDS:=TDS+ tds1;
RETURN TDS;
END FUN_PTYCR;

Syntax in Sql:
CREATE FUNCTION dbo.ufnGetInventoryStock(@ProductID int)
RETURNS int
AS
-- Returns the stock level for the product.
BEGIN
DECLARE @ret int;
SELECT @ret = SUM(p.Quantity)
FROM Production.ProductInventory p
WHERE p.ProductID = @ProductID
AND p.LocationID = '6';
IF (@ret IS NULL)
SET @ret = 0;
RETURN @ret;
END;