Error 1: Cannot define PRIMARY KEY constraint on nullable column in table
Cause: set ansi null default on, when you create a new col
Solution: explicitly state not null
Error 2: The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object
Cause: Duplicate value for the desired columns
Solution: Run the following query to check the dup key, assuming unique index is on col1
select Col1 , count(*)
from Customers
group by col1
having count(*) > 1
Wednesday, September 18, 2013
How to use table name as a variable in stored procedure
Sometimes it would be nice to pass the table name as a variable in a select query, its possible by using dynamic query as shown below
create procedure
declare @tablename varchar(30)
create procedure dbo.Test
@tablename varchar(30),
@val int
as
' WHERE Column1 = ''' + @val + ''''
EXEC sp_executesql @cmd
exec Test
create procedure
declare @tablename varchar(30)
create procedure dbo.Test
@tablename varchar(30),
@val int
as
DECLARE @cmd AS NVARCHAR(max)
SET @cmd = N'SELECT * FROM ' + @table_name +' WHERE Column1 = ''' + @val + ''''
EXEC sp_executesql @cmd
exec Test
How to series TSQL 2
6. How to find second highest
SELECT COL
FROM TABLE
ORDER BY COL DESC
OFFSET 1 ROWS
FETCH NEXT 1 ROWS ONLY;
7. How to use multiple cte
;with cte1
as
(select col1, null as col2 from Tab),
cte2
as
(
select col2, null as col1 from Tab
)
select * from cte1
union
select * from cte2
8 How to rename column
EXEC sp_rename 'TABLENAME.OLD_COLUMNNAME', 'NEW_COLUMNAME', 'COLUMN';
.
How to series TSQL 1
1. How to change col datatype
-- TransDate was in datetime change to date
alter table Transactions
alter column TransDate date
2. How to create primary key on a col
alter table TransactionsArchive
add constraint PK_TransactionsArchive_KeyID primary key clustered (key_ID);
GO
3. How to re-sequence an identity column
alter table List_NotesType
drop constraint PK_List_CommentsType
alter table List_NotesType
drop column NoteType
alter table List_NotesType
add NoteType tinyint identity(1,1)
alter table List_NotesType
add constraint PK_List_NoteTypeID primary key clustered (NoteType);
4. How to change a not null col to null
alter table [Notes]
alter column Comments varchar(500) NULL
5. How to update existing NULL cols with a value
update Notes
set Comments = t.Description
from Notes n join List_NotesType t on n.Type = t.NoteType
where Noteid in (select Noteid from Notes where Comments is null)
Tuesday, September 17, 2013
How to use cross apply instead of cursors in SQL Server
I recently ran into a stored procedure with cursor logic, I wanted to see what would be the performance gain if cursor logic is rewritten with set theory operations.
Here is a simplified description of the stored procedure. There is a table with five columns, one column is an identity and a primary, (let's call it the ID), three columns (x, y, z) are of type integers and the fifth column (a) is a computed column. The computation is quite complex so it cannot be declared as a computed column expression. For each row, the values of the three columns (x, y, z) are passed in as a parameters to a custom function (where the logic is encapsulated) which spits out a calculated value. Finally, for every row the column "a" is updated with the calculated value from the custom function. There are around 7000 rows in this table.
I put this blogpost on code project as well. Check out the following link
http://www.codeproject.com/Tips/654894/How-to-use-cross-apply-instead-of-cursors-in-SQL-S
Let's create a table called test1 with five columns. For this example lets stick with a simple logic, the fifth column is a sum of cols x,y,z.
Step 1: Create the test table
create table test1
(
id int not null identity(1,1),
x int,
y int,
z int,
a int null
)
Step 2: Insert dummy data
insert into test1 values (5,5,5, NULL)
go 10
-- (I inserted 9132 rows, took five minutes for the code to execute)
Step 3: Using cursors to update the column "a"
declare @x1 int
declare @x2 int
declare @x3 int
declare @x4 int
declare @x5 int
declare c1 cursor local for
select id, x, y, z, a from test1
open c1
while (0=0)
begin
fetch next from c1 into
@x1, @x2,@x3,@x4,@x5
if (@@FETCH_STATUS = -1)
break
-- your logic
set @x5 = @x4 + @x2 + @x3
update test1
set test1.a = @x5
from test1
where id = @x1
end
close c1
deallocate c1
-- Exexcution time 01:09
Step 4: Reset column "a"
update test1 set a = null
Step 5: Create a table valued function (tvf) shown below
create function dbo.fnsomelogic (@x int ,@y int, @z int)
returns @val table
(
q int
)
as
begin
declare @q int
set @q = @x + @y +@z
insert into @val (q) values (@q)
return
end
-- tvf can be invoked as shown below
-- select * from dbo.fnsomelogic(1,2,3)
Step 6: use cross apply and the tvf to update column a
update test1
set test1.a = c.q
from test1 b cross apply dbo.fnsomelogic(b.x,b.y,b.z) c
--Execution Time: (9132 row(s) affected) in less than a second.
If you observe the messages, the cursor which is a row based operator, displays (1 row(s) affected) for every row it updated, unlike the cross apply which displays (9132 row(s) affected). Although the problem is screaming out use cursors, however with little observation a cross apply along with a table valued function can boost the performance significantly. Relational/Set theory concepts are deeply embedded within SQL Server.
Here is a simplified description of the stored procedure. There is a table with five columns, one column is an identity and a primary, (let's call it the ID), three columns (x, y, z) are of type integers and the fifth column (a) is a computed column. The computation is quite complex so it cannot be declared as a computed column expression. For each row, the values of the three columns (x, y, z) are passed in as a parameters to a custom function (where the logic is encapsulated) which spits out a calculated value. Finally, for every row the column "a" is updated with the calculated value from the custom function. There are around 7000 rows in this table.
I put this blogpost on code project as well. Check out the following link
http://www.codeproject.com/Tips/654894/How-to-use-cross-apply-instead-of-cursors-in-SQL-S
Let's create a table called test1 with five columns. For this example lets stick with a simple logic, the fifth column is a sum of cols x,y,z.
Step 1: Create the test table
create table test1
(
id int not null identity(1,1),
x int,
y int,
z int,
a int null
)
Step 2: Insert dummy data
insert into test1 values (5,5,5, NULL)
go 10
-- (I inserted 9132 rows, took five minutes for the code to execute)
Step 3: Using cursors to update the column "a"
declare @x1 int
declare @x2 int
declare @x3 int
declare @x4 int
declare @x5 int
declare c1 cursor local for
select id, x, y, z, a from test1
open c1
while (0=0)
begin
fetch next from c1 into
@x1, @x2,@x3,@x4,@x5
if (@@FETCH_STATUS = -1)
break
-- your logic
set @x5 = @x4 + @x2 + @x3
update test1
set test1.a = @x5
from test1
where id = @x1
end
close c1
deallocate c1
-- Exexcution time 01:09
Step 4: Reset column "a"
update test1 set a = null
Step 5: Create a table valued function (tvf) shown below
create function dbo.fnsomelogic (@x int ,@y int, @z int)
returns @val table
(
q int
)
as
begin
declare @q int
set @q = @x + @y +@z
insert into @val (q) values (@q)
return
end
-- tvf can be invoked as shown below
-- select * from dbo.fnsomelogic(1,2,3)
Step 6: use cross apply and the tvf to update column a
update test1
set test1.a = c.q
from test1 b cross apply dbo.fnsomelogic(b.x,b.y,b.z) c
--Execution Time: (9132 row(s) affected) in less than a second.
If you observe the messages, the cursor which is a row based operator, displays (1 row(s) affected) for every row it updated, unlike the cross apply which displays (9132 row(s) affected). Although the problem is screaming out use cursors, however with little observation a cross apply along with a table valued function can boost the performance significantly. Relational/Set theory concepts are deeply embedded within SQL Server.
Tuesday, September 10, 2013
Stored Procs 101
Stored procedures are programmability features of a database engine.
Advantages of stored procs (sp)
1. Reduce server/client network traffic
2. Stronger security
3. Modularization & Code re-usability
4. Easier maintainance
5. Improved performance
-- 1. basic sp
create procedure TestProc1
as
begin --optional
select top 5 * from sales.customers
end -- optional
-- 2. execute a sp
exec TestProc1 -- or execute TestProc1
-- 3. alter a sp
alter procedure TestProc1
as
begin
select top 10 * from sales.customers
end
-- 4. drop a sp
drop procedure TestProc1
-- 5. Rename/ "sp_" are system defined stored procs
exec sp_rename 'TestProc1', 'TestProc2'
-- 6. View the definition of sp
-- approach 1
exec sp_helptext 'TestProc1'
-- approach 2
select object_definition (object_id('TestProc'))
-- approach 3
select definition
from sys.sql_modules
where object_id = (object_id('TestProc'))
-- 7 sp with one parameter
create procedure TestProc
( -- optional
@custid int
) -- optional
as
select * from sales.customers where custid = @custid
-- execute sp with parameters
exec testproc 3
--or
exec testProc @custid = 3
-- 8 sp with more than one parameter
create procedure TestProc
@custid int,
@contacttitle varchar(30)
as
select * from sales.customers where custid = @custid
0 : Successful execution
1 : Required param is not specified
2 : Specified param value is not valid
3 : Error has occurred in getting the value
4 : Null value found for variable
-- 10 recompiling sp
There are three ways to recompile a sp
exec testproc with recompile
exec sp_recompile 'testproc'
Advantages of stored procs (sp)
1. Reduce server/client network traffic
2. Stronger security
3. Modularization & Code re-usability
4. Easier maintainance
5. Improved performance
-- 1. basic sp
create procedure TestProc1
as
begin --optional
select top 5 * from sales.customers
end -- optional
-- 2. execute a sp
exec TestProc1 -- or execute TestProc1
-- 3. alter a sp
alter procedure TestProc1
as
begin
select top 10 * from sales.customers
end
-- 4. drop a sp
drop procedure TestProc1
-- 5. Rename/ "sp_" are system defined stored procs
exec sp_rename 'TestProc1', 'TestProc2'
-- 6. View the definition of sp
-- approach 1
exec sp_helptext 'TestProc1'
-- approach 2
select object_definition (object_id('TestProc'))
-- approach 3
select definition
from sys.sql_modules
where object_id = (object_id('TestProc'))
-- 7 sp with one parameter
create procedure TestProc
( -- optional
@custid int
) -- optional
as
select * from sales.customers where custid = @custid
-- execute sp with parameters
exec testproc 3
--or
exec testProc @custid = 3
-- 8 sp with more than one parameter
create procedure TestProc
@custid int,
@contacttitle varchar(30)
as
select * from sales.customers where custid = @custid
and contacttitle = @contacttitle
-- 9 proc which returns data, use output keyword
create procedure TestProc
@custid int,
@contacttitle varchar(30),
@companyname varchar(40) output
as
select * from sales.customers where custid = @custid
@custid int,
@contacttitle varchar(30),
@companyname varchar(40) output
as
select * from sales.customers where custid = @custid
and contacttitle = @contacttitle
declare @c varchar(30)
exec testproc 2, 'Owner', @companyname = @c output
select @c -- print @c
If you don't use output keyword then if the sp will return a table if called from .net code.
If we use the output keyword then a single value is returned which can be captured as a .net data type
Error codes of sp with output keyword
0 : Successful execution
1 : Required param is not specified
2 : Specified param value is not valid
3 : Error has occurred in getting the value
4 : Null value found for variable
-- 10 recompiling sp
There are three ways to recompile a sp
exec testproc with recompile
exec sp_recompile 'testproc'
Subscribe to:
Posts (Atom)