Archive
SET ANSI_NULLS, QUOTED_IDENTIFIER, ANSI_PADDING – SQL Server
You have to create a Stored-Procedure and you need a template. You expand the Object Explorer go to Database -> Programmability -> “Stored Procedure” -> (right click) -> select “New Stored Procedure”.
A new editor opens up with lot of commented & flawless code. There you see some predefined statements.
Sometimes while working with Stored Procedures and other SQL Scripts a those few statements makes you confusing and clueless. Most of the time people remove them or just ignore them, but one should know why are they placed there. The 2 mains SET statements that are placed by default are described below with examples:
–// SET ANSI_NULLS (http://msdn.microsoft.com/en-us/library/ms188048.aspx)
Specifies ISO compliant behavior of the Equals (=) and Not Equal To (<>) comparison operators when they are used with null values.
Syntax: SET ANSI_NULLS { ON | OFF }
create table #tempTable (sn int, ename varchar(50)) insert into #tempTable select 1, 'Manoj' UNION ALL select 2, 'Pankaj' UNION ALL select 3, NULL UNION ALL select 4, 'Lokesh' UNION ALL select 5, 'Gopal' SET ANSI_NULLS ON select * from #tempTable where ename is NULL -- (1 row(s) affected)
sn ename
3 NULL
select * from #tempTable where ename = NULL -- (0 row(s) affected) select * from #tempTable where ename <> NULL -- (0 row(s) affected) SET ANSI_NULLS OFF select * from #tempTable where ename is NULL -- (1 row(s) affected) select * from #tempTable where ename = NULL -- (1 row(s) affected)
sn ename
3 NULL
select * from #tempTable where ename is not NULL -- (4 row(s) affected) select * from #tempTable where ename <> NULL -- (4 row(s) affected)
sn ename
1 Manoj
2 Pankaj
4 Lokesh
5 Gopal
drop table #tempTable
–// SET QUOTED_IDENTIFIER (http://msdn.microsoft.com/en-us/library/ms174393.aspx)
Causes SQL Server to follow the ISO rules regarding quotation mark delimiting identifiers and literal strings. Identifiers delimited by double quotation marks can be either Transact-SQL reserved keywords or can contain characters not generally allowed by the Transact-SQL syntax rules for identifiers.
When SET QUOTED_IDENTIFIER is ON, identifiers can be delimited by double quotation marks, and literals must be delimited by single quotation marks.
When SET QUOTED_IDENTIFIER is OFF, identifiers cannot be quoted and must follow all Transact-SQL rules for identifiers.
Syntax: SET QUOTED_IDENTIFIER { ON | OFF }
-- Example 1 SET QUOTED_IDENTIFIER ON create table "#tempTable" (sn int, ename varchar(50)) -- Command(s) completed successfully. SET QUOTED_IDENTIFIER OFF create table "#tempTable" (sn int, ename varchar(50)) -- Incorrect syntax near '#tempTable'. drop table #tempTable -- Example 2 SET QUOTED_IDENTIFIER ON select "'My Name is Manoj'" as Col1, "Let's play" as Col2 -- Invalid column name ''My Name is Manoj''. Invalid column name 'Let's play'. SET QUOTED_IDENTIFIER OFF select "'My Name is Manoj'" as Col1, "Let's play" as Col2 -- (1 row(s) affected)
Col1 Col2
'My Name is Manoj' Let's play
-- Example 3 SET QUOTED_IDENTIFIER ON select '''My Name is Manoj''' as Col1, 'Let''s play' as Col2 -- (1 row(s) affected)
Col1 Col2
'My Name is Manoj' Let's play
SET QUOTED_IDENTIFIER OFF select '''My Name is Manoj''' as Col1, 'Let''s play' as Col2 -- (1 row(s) affected)
Col1 Col2
'My Name is Manoj' Let's play
–// SET ANSI_PADDING (http://msdn.microsoft.com/en-us/library/ms187403.aspx)
Controls the way the column stores values shorter than the defined size of the column, and the way the column stores values that have trailing blanks in char, varchar, binary, and varbinary data.
Syntax: SET ANSI_PADDING { ON | OFF }
-- Example 1 SET ANSI_PADDING ON create table #tempTable1 (charcol char(20), varcharcol varchar(20)) insert into #tempTable1 select 'Manoj', 'Manoj' UNION ALL select 'Pandey', 'Pandey' select '['+charcol+']' as charcol, '['+varcharcol+']' as varcharcol from #tempTable1
charcol varcharcol
[Manoj ] [Manoj]
[Pandey ] [Pandey]
-- Example 2 SET ANSI_PADDING OFF create table #tempTable2 (charcol char(20), varcharcol varchar(20)) insert into #tempTable2 select 'Manoj', 'Manoj' UNION ALL select 'Pandey', 'Pandey' select '['+charcol+']' as charcol, '['+varcharcol+']' as varcharcol from #tempTable2
charcol varcharcol
[Manoj] [Manoj]
[Pandey] [Pandey]
drop table #tempTable1 drop table #tempTable2
Other SET statements MSDN BOL: http://msdn.microsoft.com/en-us/library/ms190356.aspx
SQL Server CURSOR and it’s Life Cycle
A CURSOR in SQL is a database object that contains a set of records that you can traverse one-by-one, rather than the SET as a whole.
SQL is a set-based language and produces a complete result set, and the SQL queries works on this complete set only, and not on individual rows. But there are times when the results are best processed one row at a time. Opening a cursor on a result set allows processing the result set one row at a time. You can assign a cursor to a variable or parameter with a cursor data type.
CURSOR in SQL language gives you the flexibility to traverse records like the way you do in other programming languages with iterators and for-loop.
–> A simple Cursor life cycle with minimum definition:
USE [AdventureWorks]
GO
-- Returns -3
SELECT CURSOR_STATUS('global','myCursor') AS 'Before Declare'
DECLARE myCursor CURSOR
FOR SELECT ContactID, FirstName, LastName FROM Person.Contact WHERE ContactID BETWEEN 100 and 102
-- Returns -1
SELECT CURSOR_STATUS('global','myCursor') AS 'After Declare'
DECLARE @ContactID INT, @FirstName VARCHAR(50), @LastName VARCHAR(50)
OPEN myCursor
-- Returns 1
SELECT CURSOR_STATUS('global','myCursor') AS 'Open Cusrsor'
FETCH NEXT FROM myCursor INTO @ContactID, @FirstName, @LastName
WHILE @@fetch_status=0
BEGIN
-- SQL Statements with logic inside
SELECT @ContactID, @FirstName, @LastName
FETCH NEXT FROM myCursor INTO @ContactID, @FirstName, @LastName
END
-- Returns 1
SELECT CURSOR_STATUS('global','myCursor') AS 'While loop exited, all rows iterated'
CLOSE myCursor
-- Returns -1
SELECT CURSOR_STATUS('global','myCursor') AS 'Cursor is Closed'
DEALLOCATE myCursor
-- Returns -3
SELECT CURSOR_STATUS('global','myCursor') AS 'Cursor Deallocated'
SQL Basics – IDENTITY property of a Column (in a table)
With IDENTITY property you can:
1. Creates an identity column in a table.
2. Used for generating key values, based on the current seed & increment.
3. Each new value for a particular transaction is different from other concurrent transactions on the table.
–> You can check the demo about IDENTITY property here:
–> IDENTITY property on a column does not guarantee:
1. Uniqueness of the value,
2. Consecutive values within a transaction,
3. Consecutive values after server restart or other failures,
4. Reuse of values,
–> SQL Script used in Demo:
-- IDENTITY property of a Column
CREATE TABLE [dbo].[Employee](
[EmployeeID] int NOT NULL IDENTITY (100, 1),
[EmployeeName] nvarchar(100) NOT NULL,
[Gender] nchar(1) NULL,
[DOB] datetime NULL,
[DOJ] datetime NULL,
[DeptID] int NULL
)
INSERT INTO [dbo].[Employee] (EmployeeName, Gender, DOB, DOJ, DeptID)
VALUES ('MANOJ PANDEY', 'M', '1990-01-01', '2010-01-01', 101)
INSERT INTO [dbo].[Employee] (EmployeeName, Gender, DOB, DOJ, DeptID)
VALUES ('JHON K', 'M', NULL, '2010-01-01', NULL)
INSERT INTO [dbo].[Employee] ([EmployeeName])
VALUES ('Brock H')
GO
SELECT * FROM [dbo].[Employee]
GO
-- Inserting Explicit value in IDENTITY column:
SET IDENTITY_INSERT [dbo].[Employee] ON
INSERT INTO [dbo].[Employee] ([EmployeeID],[EmployeeName])
VALUES (1000, 'Brock H')
SET IDENTITY_INSERT [dbo].[Employee] OFF
GO
SELECT * FROM [dbo].[Employee]
GO
INSERT INTO [dbo].[Employee] ([EmployeeName])
VALUES ('Jhon B')
GO
SELECT * FROM [dbo].[Employee]
GO
–> Check more articles on IDENTITY property:
– RE-SEED an IDENTITY value of a Column
– Using IDENTITY() function with SELECT into statement
– All about IDENTITY columns, some more secrets
– IDENTITY property behavior with SQL Server 2012 and above
Multiple ways to INSERT records in a table
The following exercise shows multiple ways to INSERT records in a table, as the post title says.
USE [tempdb]
GO
CREATE TABLE sometable(a INT, b VARCHAR(20), c INT)
GO
-- Method #1 - Simple INSERT statement
INSERT sometable (a, b, c)
VALUES(1, 'New York', 123)
GO
DROP TABLE sometable
-- Method #2 - CREATE the table and INSERT records. This is minimally logged operation and faster than explicitly creating table and inserting records.
SELECT 1 a, 'New York' b, 334 c
INTO sometable
UNION
SELECT 2, 'London', 823
UNION
SELECT 3, 'Paris', 1124
UNION
SELECT 4, 'Munich', 2080
GO
-- Method #3
INSERT sometable (a, b, c)
EXEC('SELECT 5, ''New York'', 234
SELECT 6, ''London'', 923
SELECT 7, ''Paris'', 1024
SELECT 8, ''Munich'', 1980')
GO
-- Method #4
INSERT sometable (a, b, c)
SELECT 9, 'New York', 334 UNION
SELECT 10, 'London', 823 UNION
SELECT 11, 'Paris', 1124 UNION
SELECT 12, 'Munich', 2080
GO
-- Method #5 - More options in SQL Server 2008, by using the VALUES() constructor
INSERT sometable (a, b, c)
VALUES (13, 'New York', 334),
(14, 'London', 823),
(15, 'Paris', 1124),
(16, 'Munich', 2080))
GO
-- Method #6 - Yes you can also use SQL statements at column level inside the VALUES constructor
INSERT sometable (a, b, c)
VALUES (18, 'New York', 334),
(19, 'London', 823),
((SELECT MAX(a)+1 FROM sometable), (SELECT b FROM sometable WHERE a=15), SELECT SUM(c) FROM sometable),
(20, 'Munich', 2080))
GO
-- Now check the resultset
SELECT * FROM sometable
-- Final Cleanup
DROP TABLE sometable
More on VALUES constructor on MS BOL: http://technet.microsoft.com/en-us/library/dd776382.aspx
Physical Join vs Logical Join in SQL Server
Most of us know about JOINS in SQL Server and their types. But do we really know how they are interpreted in SQL Server internally. Today I found lot of informative, interesting and important sources regarding Logical and Physical joins in SQL Server (links below).
–> Classifying JOINS mainly into 2 types:
1. Logical Joins: These joins are simple joins that we apply in our SQL queries, like INNER JOIN, RIGHT/LEFT OUTER JOIN, CROSS JOIN, OUTER APPLY, etc.
2. Physical Joins: These are the joins that users don’t use/write in their SQL queries. Instead these are implemented inside SQL Server engine as operators or algorithms to implement the Logical Joins. Their types are Nested Loop, Merge and Hash.
For a particular SQL query when you try to view an Estimated Execution Plan or execute a query by selecting Actual Execution Plan, you can clearly see these Physical Joins under the Execution Plan tab in SSMS.
Reference for Logical Joins from one of my old posts: https://sqlwithmanoj.wordpress.com/2009/03/12/sql-server-joins-and-types
–> Logical Joins:
– Inner/Outer/Cross: https://blogs.msdn.microsoft.com/craigfr/2006/07/19/introduction-to-joins/
–> Physical Joins:
– Nested Loop Joins: https://blogs.msdn.microsoft.com/craigfr/2006/07/26/nested-loops-join/
– Merge Joins: https://blogs.msdn.microsoft.com/craigfr/2006/08/03/merge-join/
– Hash Joins: https://blogs.msdn.microsoft.com/craigfr/2006/08/10/hash-join/




