The main advantage of stored procedure is, to execute T-SQL statements in less time than the similar set of T-SQL statements is executed individually. The reason to take less time is that the query execution plan for the stored procedures is already stored in the "sys.procedures" system defined view.
The recompilation process of stored procedure is like as compilation process and also reduce Sql Server performance. Stored procedure with recompilation option was introduced in Sql Server 2005. We should recompile stored procedure in following cases
- Changing to the schema (means adding/dropping columns, constraints, rules, index, trigger etc) of the tables or referenced table(s) or view(s).
- Updating the statistics used by the execution plan of stored procedure
We have two options for stored procedure recompilation
Recompile option at the time of Creation
In this we create a stored procedure with RECOMPILE option. When we call this procedure than every time this procedure will be recompile before executing.- CREATE PROCEDURE usp_InsertEmployee
- WITH RECOMPILE
- @flag bit output,-- return 0 for fail,1 for success
- @EmpID int,
- @Name varchar(50),
- @Salary int,
- @Address varchar(100)
- AS
- BEGIN
- BEGIN TRANSACTION
- BEGIN TRY
- Insert into Employee(EmpID,Name,Salary,Address) Values(@EmpID,@Name,@Salary,@Address);
- set @flag=1;
- commit TRANSACTION;
- END TRY
- BEGIN CATCH
- rollback TRANSACTION;
- set @flag=0;
- END CATCH
- END
- Declare @flag bit
- --Now Execute this procedure. Every time this procedure will be recompiled
- EXEC usp_InsertEmployee @flag output,1,'Deepak',14000,'Noida'
- if @flag=1
- print 'Successfully inserted'
- else
- print 'There is some error'
Recompile option at the time of Execution
In this we call a stored procedure with RECOMPILE option. Hence this stored procedure will be compiled only when we use RECOMPILE option at the time of calling. This is the best option for stored procedure recompilation.- CREATE PROCEDURE usp_InsertEmployee
- @flag bit output,-- return 0 for fail,1 for success
- @EmpID int,
- @Name varchar(50),
- @Salary int,
- @Address varchar(100)
- AS
- BEGIN
- BEGIN TRANSACTION
- BEGIN TRY
- Insert into Employee(EmpID,Name,Salary,Address) Values(@EmpID,@Name,@Salary,@Address);
- set @flag=1;
- commit TRANSACTION;
- END TRY
- BEGIN CATCH
- rollback TRANSACTION;
- set @flag=0;
- END CATCH
- END
- Declare @flag bit
- --Now Execute this procedure with RECOMPILE option, if you want to recompile its execution plan
- EXEC usp_InsertEmployee @flag output,2,'Jitendra',15000,'Noida' WITH RECOMPILE
- if @flag=1
- print 'Successfully inserted'
- else
- print 'There is some error'
Note
- Creating the stored procedure by using "WITH RECOMPILE" option force the SQL Server to recompile the stored procedure every time when it is called.
- Call the stored procedure by using "WITH RECOMPILE" option in the EXEC command.
- Altering the procedure will cause the SQL Server to create a new execution plan
- If SQL Server is restarted or stopped then all the execution plans will be flush from server cache and recreated when the stored procedure is executed after restarting the server.
- The "Sp_recompile" system defined stored procedure can be called to refresh the query execution plan for a particular stored procedure
ursor allow us to retrieve data from a result set in singleton fashion means row by row. Cursor are required when we need to update records in a database table one row at a time. I have already explained the basic of cursor.
A Cursor impacts the performance of the SQL Server since it uses the SQL Server instances' memory, reduce concurrency, decrease network bandwidth and lock resources. Hence it is mandatory to understand the cursor types and its functions so that you can use suitable cursor according to your needs.
You should avoid the use of cursor. Basically you should use cursor alternatives like as WHILE loop, sub queries, Temporary tables and Table variables. We should use cursor in that case when there is no option except cursor.
Types of Cursors
Static Cursors
A static cursor populates the result set at the time of cursor creation and query result is cached for the lifetime of the cursor. A static cursor can move forward and backward direction. A static cursor is slower and use more memory in comparison to other cursor. Hence you should use it only if scrolling is required and other types of cursors are not suitable.No UPDATE, INSERT, or DELETE operations are reflected in a static cursor (unless the cursor is closed and reopened). By default static cursors are scrollable. SQL Server static cursors are always read-only.Dynamic Cursors
A dynamic cursor allows you to see the data updation, deletion and insertion in the data source while the cursor is open. Hence a dynamic cursor is sensitive to any changes to the data source and supports update, delete operations. By default dynamic cursors are scrollable.Forward Only Cursors
A forward only cursor is the fastest cursor among the all cursors but it doesn't support backward scrolling. You can update, delete data using Forward Only cursor. It is sensitive to any changes to the original data source.There are three more types of Forward Only Cursors.Forward_Only KEYSET, FORWARD_ONLY STATIC and FAST_FORWARD.A FORWARD_ONLY STATIC Cursor is populated at the time of creation and cached the data to the cursor lifetime. It is not sensitive to any changes to the data source.A FAST_FORWARD Cursor is the fastest cursor and it is not sensitive to any changes to the data source.Keyset Driven Cursors
A keyset driven cursor is controlled by a set of unique identifiers as the keys in the keyset. The keyset depends on all the rows that qualified the SELECT statement at the time of cursor was opened. A keyset driven cursor is sensitive to any changes to the data source and supports update, delete operations. By default keyset driven cursors are scrollable.
SQL SERVER – Examples of Cursors
- CREATE TABLE Employee
- (
- EmpID int PRIMARY KEY,
- EmpName varchar (50) NOT NULL,
- Salary int NOT NULL,
- Address varchar (200) NOT NULL,
- )
- GO
- INSERT INTO Employee(EmpID,EmpName,Salary,Address) VALUES(1,'Mohan',12000,'Noida')
- INSERT INTO Employee(EmpID,EmpName,Salary,Address) VALUES(2,'Pavan',25000,'Delhi')
- INSERT INTO Employee(EmpID,EmpName,Salary,Address) VALUES(3,'Amit',22000,'Dehradun')
- INSERT INTO Employee(EmpID,EmpName,Salary,Address) VALUES(4,'Sonu',22000,'Noida')
- INSERT INTO Employee(EmpID,EmpName,Salary,Address) VALUES(5,'Deepak',28000,'Gurgaon')
- GO
- SELECT * FROM Employee
Static Cursor - Example
- SET NOCOUNT ON
- DECLARE @Id int
- DECLARE @name varchar(50)
- DECLARE @salary int
- DECLARE cur_emp CURSOR
- STATIC FOR
- SELECT EmpID,EmpName,Salary from Employee
- OPEN cur_emp
- IF @@CURSOR_ROWS > 0
- BEGIN
- FETCH NEXT FROM cur_emp INTO @Id,@name,@salary
- WHILE @@Fetch_status = 0
- BEGIN
- PRINT 'ID : '+ convert(varchar(20),@Id)+', Name : '+@name+ ', Salary : '+convert(varchar(20),@salary)
- FETCH NEXT FROM cur_emp INTO @Id,@name,@salary
- END
- END
- CLOSE cur_emp
- DEALLOCATE cur_emp
- SET NOCOUNT OFF
Dynamic Cursor - Example
- --Dynamic Cursor for Update
- SET NOCOUNT ON
- DECLARE @Id int
- DECLARE @name varchar(50)
- DECLARE Dynamic_cur_empupdate CURSOR
- DYNAMIC
- FOR
- SELECT EmpID,EmpName from Employee ORDER BY EmpName
- OPEN Dynamic_cur_empupdate
- IF @@CURSOR_ROWS > 0
- BEGIN
- FETCH NEXT FROM Dynamic_cur_empupdate INTO @Id,@name
- WHILE @@Fetch_status = 0
- BEGIN
- IF @name='Mohan'
- Update Employee SET Salary=15000 WHERE CURRENT OF Dynamic_cur_empupdate
- FETCH NEXT FROM Dynamic_cur_empupdate INTO @Id,@name
- END
- END
- CLOSE Dynamic_cur_empupdate
- DEALLOCATE Dynamic_cur_empupdate
- SET NOCOUNT OFF
- Go
- Select * from Employee
- -- Dynamic Cursor for DELETE
- SET NOCOUNT ON
- DECLARE @Id int
- DECLARE @name varchar(50)
- DECLARE Dynamic_cur_empdelete CURSOR
- DYNAMIC
- FOR
- SELECT EmpID,EmpName from Employee ORDER BY EmpName
- OPEN Dynamic_cur_empdelete
- IF @@CURSOR_ROWS > 0
- BEGIN
- FETCH NEXT FROM Dynamic_cur_empdelete INTO @Id,@name
- WHILE @@Fetch_status = 0
- BEGIN
- IF @name='Deepak'
- DELETE Employee WHERE CURRENT OF Dynamic_cur_empdelete
- FETCH NEXT FROM Dynamic_cur_empdelete INTO @Id,@name
- END
- END
- CLOSE Dynamic_cur_empdelete
- DEALLOCATE Dynamic_cur_empdelete
- SET NOCOUNT OFF
- Go
- Select * from Employee
Forward Only Cursor - Example
- --Forward Only Cursor for Update
- SET NOCOUNT ON
- DECLARE @Id int
- DECLARE @name varchar(50)
- DECLARE Forward_cur_empupdate CURSOR
- FORWARD_ONLY
- FOR
- SELECT EmpID,EmpName from Employee ORDER BY EmpName
- OPEN Forward_cur_empupdate
- IF @@CURSOR_ROWS > 0
- BEGIN
- FETCH NEXT FROM Forward_cur_empupdate INTO @Id,@name
- WHILE @@Fetch_status = 0
- BEGIN
- IF @name='Amit'
- Update Employee SET Salary=24000 WHERE CURRENT OF Forward_cur_empupdate
- FETCH NEXT FROM Forward_cur_empupdate INTO @Id,@name
- END
- END
- CLOSE Forward_cur_empupdate
- DEALLOCATE Forward_cur_empupdate
- SET NOCOUNT OFF
- Go
- Select * from Employee
- -- Forward Only Cursor for Delete
- SET NOCOUNT ON
- DECLARE @Id int
- DECLARE @name varchar(50)
- DECLARE Forward_cur_empdelete CURSOR
- FORWARD_ONLY
- FOR
- SELECT EmpID,EmpName from Employee ORDER BY EmpName
- OPEN Forward_cur_empdelete
- IF @@CURSOR_ROWS > 0
- BEGIN
- FETCH NEXT FROM Forward_cur_empdelete INTO @Id,@name
- WHILE @@Fetch_status = 0
- BEGIN
- IF @name='Sonu'
- DELETE Employee WHERE CURRENT OF Forward_cur_empdelete
- FETCH NEXT FROM Forward_cur_empdelete INTO @Id,@name
- END
- END
- CLOSE Forward_cur_empdelete
- DEALLOCATE Forward_cur_empdelete
- SET NOCOUNT OFF
- Go
- Select * from Employee
Keyset Driven Cursor - Example
- -- Keyset driven Cursor for Update
- SET NOCOUNT ON
- DECLARE @Id int
- DECLARE @name varchar(50)
- DECLARE Keyset_cur_empupdate CURSOR
- KEYSET
- FOR
- SELECT EmpID,EmpName from Employee ORDER BY EmpName
- OPEN Keyset_cur_empupdate
- IF @@CURSOR_ROWS > 0
- BEGIN
- FETCH NEXT FROM Keyset_cur_empupdate INTO @Id,@name
- WHILE @@Fetch_status = 0
- BEGIN
- IF @name='Pavan'
- Update Employee SET Salary=27000 WHERE CURRENT OF Keyset_cur_empupdate
- FETCH NEXT FROM Keyset_cur_empupdate INTO @Id,@name
- END
- END
- CLOSE Keyset_cur_empupdate
- DEALLOCATE Keyset_cur_empupdate
- SET NOCOUNT OFF
- Go
- Select * from Employee
- -- Keyse Driven Cursor for Delete
- SET NOCOUNT ON
- DECLARE @Id int
- DECLARE @name varchar(50)
- DECLARE Keyset_cur_empdelete CURSOR
- KEYSET
- FOR
- SELECT EmpID,EmpName from Employee ORDER BY EmpName
- OPEN Keyset_cur_empdelete
- IF @@CURSOR_ROWS > 0
- BEGIN
- FETCH NEXT FROM Keyset_cur_empdelete INTO @Id,@name
- WHILE @@Fetch_status = 0
- BEGIN
- IF @name='Amit'
- DELETE Employee WHERE CURRENT OF Keyset_cur_empdelete
- FETCH NEXT FROM Keyset_cur_empdelete INTO @Id,@name
- END
- END
- CLOSE Keyset_cur_empdelete
- DEALLOCATE Keyset_cur_empdelete
- SET NOCOUNT OFF
- Go Select * from Employee
No comments:
Post a Comment