Tuesday, March 10, 2020

CTE (common table expression) In Depth

CTE (common table expression) and Updatable CTE you will understand this in this article by sagar jaybhay in depth.





CTE (common table expression)





CTE Introduced in the SQL server 2005.





CTE is
like a temporary result set which is defined within the execution of the
current context or execution scope of single select, insert, update delete and
create view statement.





It is
similar to a derived table and it is not stored as an object like other objects
in the SQL server.





Remember CTE table is created with the keyword.





with CTEtable
as
(
select d.Department_Name as deptname, COUNT(e.empid) as empcount from Department as d
join Employee as e on d.DepartmentID=e.DepartmentID
group by d.Department_Name
)
select * from CTEtable
where
empcount>100;








CTE
CTE




In the above query, we didn’t mentioned the column name if your inner query is given distinct column name then there is no need to define column name else you need to define like shown below





with CTEtable(deptname,empcount)
as
(
select d.Department_Name as deptname, COUNT(e.empid) as empcount from Department as d
join Employee as e on d.DepartmentID=e.DepartmentID
group by d.Department_Name
)
select * from CTEtable
where
empcount>100;




CTE with column name defined
CTE with column name defined




In the
above query, you specify 2 columns so remember you need to specify the columns
that select query is returning if our inner select query returning 3 columns
then you need to specify these 3 columns in CTE.





CTE is
only referenced by select, insert, update and delete statement immediately
follows the CTE expression.





In this, With clause, you can create multiple CTE tables.





with CTEtable(deptname,empcount)
as
(
select d.deptname as deptname, COUNT(e.id) as empcount from tbldept as d
join tblEmp as e on d.deptid=e.deptid
group by d.deptname
),
tblnew_hr(deptname,id)
as
(
select d.deptname,e.id from tblEmp e join tbldept d on
e.deptid=d.deptid
)
select * from CTEtable
union
select * from tblnew_hr





Multiple CTE
Multiple CTE




Updatable CTE





It is
possible to update the CTE the answer to this is Yes or No.





If your CTE is based on a single table then you can update using CTE. Which in turn update the underlying table.





with update_cte
as
(
select id, name, salary from tblEmp
)

update update_cte set salary=5555 where id =2

select * from tblEmp;




Updatable CTE
Updatable CTE




If CTE is based on more than one table and updates affect only the base table then this is possible.





with update_mul_cte
as
(
select e.id,d.deptname,e.geneder from tblEmp e join tbldept d on e.deptid=d.deptid
)

update update_mul_cte set geneder='male' where id=2;
select * from tblEmp;




Multiple CTE Update
Multiple CTE Update




But if you are going to update data in both tables which are present in CTE it will throw an error.





with update_mul_cte
as
(
select e.id,d.deptname,e.geneder from tblEmp e join tbldept d on e.deptid=d.deptid
)

update update_mul_cte set geneder='male',deptname='fff' where id=2;
select * from tblEmp;




Update Multiple Table CTE Error




Below is
an error that is thrown by it.





Msg 4405,
Level 16, State 1, Line 11





View or function 'update_mul_cte' is not updatable because the modification affects multiple base tables.










GitHub Profile :- https://github.com/Sagar-Jaybhay






Working With Multiple Tables In MVC By Sagar Jaybhay

Monday, March 9, 2020

Insted Of Trigger Table Variable Derived Table

Insted Of Trigger Table Variable Derived Table about this you will able to understand in this article By Sagar Jaybhay In SQL Server.





Before read this article read below article First to better understanding.





Part 1: - https://sagarjaybhay.com/what-is-triggers-in-sql-sagar-jaybhay-part-1/





Part 2:-https://sagarjaybhay.com/update-trigger-instead-of-trigger-sagar-jaybhay/





Insted Of Trigger





Instead Of Update Trigger





Instead of an update trigger is similar to instead of insert trigger. It is fire when we are going to update the records in view and in below code, you will see I am using Update function which we get the value true or false if we trying to set that parameter value in our case we are trying to deptname so update(deptname) return true.





alter trigger tr_updateempdec
on vw_empdec
instead of Update
as
begin
declare @deptname nvarchar(20);
declare @deptid int;

select @deptname=deptname from inserted;
print('department is '+@deptname)

if(UPDATE(deptname))
begin
select @deptid=tbldept.deptid from tbldept join
inserted on tbldept.deptname=inserted.deptname;

if(@deptid is null)
begin
raiserror('dept is null ',16,1)
return
end;

update tblEmp set deptid=@deptid from inserted join tblEmp on tblEmp.id=inserted.id;
end

end;


update vw_empdec set deptname='Hr' where id=1;




above is the query of our view which we trying to update.





Instead of Delete trigger





This triggers also the same which is fire when someone tries to delete records from view.





Insted Of Delete Trigger
Insted Of Delete Trigger




When you trying to delete records from view then we get the following error





Msg 4405,
Level 16, State 1, Line 6





View or function 'vw_empdec' is not updatable because the modification affects multiple base tables.





create trigger tr_deletetrigger
on vw_empdec
instead of delete
as
begin

delete from tblEmp
where tblEmp.id in (select id from deleted)
end;

delete from vw_empdec where id=1;




For avoiding this error we create above delete trigger which works perfectly fine.





Table Variable In SQL Server





It is like
a temporary table and table variable also created in tempdb





The scope
of table variable in batch, stored procedure and in the statement of blocks in
which it is declared.





Also,
table variables can be passed as parameters.





Below is
the syntax of the table variable.





When you use table variable you need to define the data type and column name in that table.





declare @tabledemo table(departname varchar(20),empcount int);


insert into @tabledemo
select d.Department_Name, COUNT(e.empid) as empcount from Department as d
join Employee as e on d.DepartmentID=e.DepartmentID
group by d.Department_Name;

select * from @tabledemo where empcount>100;










Derived Table In SQL Server





This
derive tables like a temporary table or table variable but it is available only
in the context of the current query.





Remember
when you derived a table you need to give a name for that table else it is not
working.





If you trying to access this derived table in another select statement outside the context of this query then it is not possible.





select deptname, empcount
from
(
select d.Department_Name as deptname, COUNT(e.empid) as empcount from Department as d
join Employee as e on d.DepartmentID=e.DepartmentID
group by d.Department_Name
) as derivedtable
where
empcount>100;








Derived Table In SQL Server
Derived Table In SQL Server




GitHub Link:- https://github.com/Sagar-Jaybhay

Tuesday, March 3, 2020

What Is Triggers In SQL By Sagar Jaybhay Part 1

In this series of article you will understand What is Triggers in SQL Server and How many Different Types of Triggers Present in SQL Server by Sagar Jaybhay.









Triggers in SQL Server





In SQL
server there are different types of triggers are present





  1. DML triggers
  2. DDL triggers
  3. Logon triggers








DML Triggers





This type
of trigger is fired automatically when DML query is executed on an underlying
table means Insert, Update or Delete query fired then DML triggers are
triggered.





DML stands for data manipulation trigger and it is fire when data is modified using this insert, update or delete query or command.





DML triggers are classified into 2 different types of triggers





  1. After triggers / For triggers
  2. Instead of triggers




After Trigger





The name itself suggests that when the query is executed after that after trigger will fire. This means that after triggering action the after trigger will fire. It means after complete execution of Insert, Update and Delete query the trigger will fire.





Instead Of Trigger





This instead of trigger will fire, instead of triggering action. This Insert, update and delete are causes to fire instead of trigger.





In
general, we can consider a trigger a stored procedure or function which can
trigger after some kind of triggering action.





When you create a trigger you can create this for a specific table and specific event.









After Trigger





This
trigger will fire after the operation is completed means insert, update or
delete.





From this
trigger, we get inserted row in which whatever the value we inserted table we
get this. Inserted is a table which is also called a Magic table which is
maintained by the SQL server and which retains a copy of row which we inserted
into the table. It is accessed inside the context of creating a trigger





We are having simple student table in that 5 rows and we are creating after triggering on insert by which trigger will fire when we insert a row and whatever value inserted we get this simply by using select * from inserted; query in the trigger. Below is a query for that trigger





create trigger afterinsert
on studenttable
for insert
as
begin
select * from inserted
end;








AfterInsert Trigger
AfterInsert Trigger








In this
above image, you can see when insert command completed successfully the select
will fire.





Now we have to add newly added row into another table how we do that





alter trigger afterinsert
on studenttable
for insert
as
begin
declare @id int;
declare @fullname nvarchar(2000);
select @id=Id from inserted;
select @fullname= first_name from inserted;

insert into afterinserttable values(@id,'name is '+CAST( @fullname as nvarchar(100)) + cast(GETDATE() as nvarchar));
select * from afterinserttable;
end;

insert into studentTable values(7,'sagar1','jaybhay1','sagar1@sagarjaybhay.net','Male','2020-02-07');








In the above query, we inserted data into the newly created table which is afterinserttable and we select all rows from that table. When the trigger is called row is inserted and all rows from that table are selected. See below image





Alter afterinsert trigger
Alter afterinsert trigger








In insert trigger, we get Inserted table in a trigger like that for delete trigger we get deleted table in that create a table. If we try to access this outside create trigger syntax we get an error.





create trigger afterdelted
on studenttable
for delete
as
begin
declare @id int;
declare @fullname nvarchar(2000);
select @id=Id from deleted;
select @fullname= first_name from deleted;

insert into afterinserttable values(@id,'name is '+CAST( @fullname as nvarchar(100)) + cast(GETDATE() as nvarchar));
select * from afterinserttable;
end;








GitHub: https://github.com/Sagar-Jaybhay

Sunday, March 1, 2020

What Is Indexed View In SQL By Sagar Jaybhay

In this article we will understand What Is Indexed View In SQL Server By Sagar Jaybhay.









Indexed View









A normal view or non-indexed view is a saved SQL query or a virtual table. When you try to get data from the table the data is coming from an underlying table. So it means the view is a virtual table and doesn’t store any data.





But when you create an index on view it gets materialized which means you can store data in view so in the SQL server we called is as Indexed view.





There are some guidelines for creating an indexed view.









  1. The view should be created with schemabinding option.
  2. If in your select function contains aggregate functions like sum, avg
    like that then for this you need to replace the null value with other value
    means 0 or not null value.
  3. If your select query contains group by clause then you need to use
    Count_Big(*) expression.
  4. Whatever table you used in view you need to specify 2 part names of
    these tables the example of above shown below








create view IndexedView
as
select d.Department_Name as dept,sum(IsNull(e.salary,0)) as totalsal from Employee as e
inner join Department as d
on d.DepartmentID=e.DepartmentID
group by d.Department_Name;








Indexed View In SQL By Sagar Jaybhay
Indexed View In SQL By Sagar Jaybhay








Now by using the above query, we created a view but we are not able to create an index on that so that you can get below error









Msg 1939,
Level 16, State 1, Line 59





Cannot create an index on view 'IndexedView' because the view is not schema bound.





Indexed View In SQL Error Message By Sagar Jaybhay
Indexed View In SQL Error Message By Sagar Jaybhay








For this, we need to create a view schemabinding option and now we can alter our view. For altering view our query looks like below









alter view IndexedView
with schemabinding
as
select d.Department_Name as dept,sum(IsNull(e.salary,0)) as totalsal from Employee as e
inner join dbo.Department as d
on d.DepartmentID=e.DepartmentID
group by d.Department_Name;








Msg 4512,
Level 16, State 3, Procedure IndexedView, Line 4 [Batch Start Line 58]





Cannot schema bind view 'IndexedView' because the name 'Employee' is invalid for schema binding. Names must be in two-part format and an object cannot reference









Now when we are altering the view with schema binding option we get the above error. To fix this we need two-part names of the table.





Now our view gets created by using below query





alter view IndexedView
with schemabinding
as
select d.Department_Name as dept,sum(IsNull(e.salary,0)) as totalsal from dbo.Employee as e
inner join dbo.Department as d
on d.DepartmentID=e.DepartmentID
group by d.Department_Name;








But when we are going to create the index we will get below error









Msg 10138,
Level 16, State 1, Line 68





Cannot create an index on view 'temp.dbo.IndexedView' because its select list does not include proper use of COUNT_BIG. Consider adding COUNT_BIG(*) to select a list.





Now we add count_big(*) in our query





alter view IndexedView
with schemabinding
as
select d.Department_Name as dept,sum(isnull(e.salary,0)) as totalsal,
COUNT_BIG(*) as totalemp
from dbo.Employee as e
inner join dbo.Department as d
on d.DepartmentID=e.DepartmentID
group by d.Department_Name;




and when we use below query





create unique clustered index view_deptindex
on IndexedView(dept);




to create an index it works perfectly fine.