Feeds:
Posts
Comments

Archive for the ‘System Stored Procedure’ Category

In my earlier article, I discussed that if you need to use result set with any stored procedure then you cannot insert the result set into a table. It generates the error no 102,  Incorrect syntax near ‘SETS’. After I posted this article, I kept looking for the solution, because it is a very handy feature of SQL Server 2012. At last, I found the solution. The details of this feature are available here.

Let me discuss the Solution step by step.

Step 1 :
In Step 1, we need to create a table and stored procedure to explain the problem and solution.

USE AdventureWorks2012
GO
CREATE TABLE #temp
(
[DepartmentID] int,
[Name] varchar(50)
)
GO

CREATE PROCEDURE SP_ResultSet_Example1
AS
SELECT [DepartmentID]
,[Name]
FROM [HumanResources].[Department]
ORDER BY DepartmentID
GO

Step 2 :
In Step 2, I will show you the error if you try to execute the stored procedure (SP_ResultSet_Example1) using result set and insert the result set into the table (#temp).
Given below is the script.

USE AdventureWorks2012
GO
INSERT INTO #temp
EXEC SP_ResultSet_Example1
WITH RESULT SETS
(
([Department ID] INT NOT NULL,
[Department name] NAME NOT NULL));
GO
--OUTPUT

Msg 102, Level 15, State 1, Line 3
Incorrect syntax near ‘SETS’.

Ooopps…… I am unable to execute it.

Step 3 :
In Step 3, I will try to execute the stored procedure (SP_ResultSet_Example1) using result set and insert the result set into the table (#temp) successfully.
Given below is the script.

USE AdventureWorks2012
GO
DECLARE @Sql AS NVARCHAR(200)
SET @Sql='
EXEC SP_ResultSet_Example1
WITH RESULT SETS
(
([Department ID] INT NOT NULL,
[Department name] NAME NOT NULL));'

INSERT INTO #temp EXEC (@Sql)
GO
SELECT * FROM #temp
GO
--OUTPUT

insertintowithresultset1.1

Read Full Post »

sys.dm_os_sys_info is one of the handy dynamic management views when it comes to query about the miscellaneous information of computer, resources & consumption by SQL Server. sys.dm_os_sys_info is with SQL Server family since SQL Server 2005, but whenever there is a new version of SQL Server, it always brings modification / additional helpful information in this view. But this modification / addition may  break your code if you don’t consider these changes with respect to versions. To avoid any such errors, I have prepared a comparison sheet of different versions of sys.dm_os_sys_info along with the changes to make life far easier.

Given below is the screen image of the comparison sheet. (Also attached Excel file for version 2007 & above):

sys.dm_os_sys_info.1.1

Reference : MSDN

Read Full Post »

sp_describe_undeclared_parameters is one of the featured system stored procedures introduced in SQL Server 2012. In this article we will discuss this stored procedure syntax, purpose & examples.

Syntax:

sp_describe_undeclared_parameters
[ @tsql = ] 'Transact-SQL_batch'
[ , [ @params = ] N'parameters' data type ] [, ...n]

Purpose :
This function gives us details about all undeclared parameters of any t-sql query. Lets say if I give you a dynamic sql and tell you to execute it. You will definitely ask me two main questions :

  • How many parameters are required to execute this dynamic sql ?
  • What are the data types of these parameters ?

Without having answers to above questions you cannot execute a dynamic t-sql query ? The beauty of sp_describe_undeclared_parameters stored procedure is, it will give you the answers to above questions and once you have the parameters & its data type, you can easily execute any dynamic sql.

Lets do it step by step.

Step 1 :
In the given below example, we have a t-sql but we don’t know how many parameters are required and its data type, nevertheless we will try to execute it.

Use AdventureWorks2012
GO
DECLARE @SQL NVARCHAR(500);
DECLARE @ParameterDefinition NVARCHAR(500);
DECLARE @BusinessEntityID INT;

SET @SQL =N'SELECT @BusinessID=[BusinessEntityID] from [HumanResources].[vEmployee]
Where [FirstName]=@FName';

EXECUTE sp_executesql @SQL
--OUTPUT

Msg 137, Level 15, State 1, Line 1
Must declare the scalar variable “@BusinessID

Oops ! error because we did not pass the parameters and we don’t know about it either.

Step 2 :
Lets pass the same t-sql to sp_describe_undeclared_parameters to get parameters details including segregation of input and output parameters.

sp_describe_undeclared_parameters @tSQL=N'SELECT @BusinessID=[BusinessEntityID]
from [HumanResources].[vEmployee] Where [FirstName]=@FName';

undeclared_parameters1.1

Step 3 :
Now, you have the parameters details including which one is input and output parameter. Lets pass it and view the results.

Example-1 :

use AdventureWorks2012
GO
DECLARE @SQL NVARCHAR(500);
DECLARE @ParameterDefinition NVARCHAR(500);
DECLARE @BusinessEntityID INT;
DECLARE @FirstName as NVARCHAR(50)

SET @FirstName='Ken'
SET @SQL =N'SELECT @BusinessID=[BusinessEntityID] from [HumanResources].[vEmployee]
Where [FirstName]=@FName';

SET @ParameterDefinition = N'@FName nvarchar(50), @BusinessID INT OUTPUT';

EXECUTE sp_executesql @SQL
,@ParameterDefinition,
@FName=@FirstName,
@BusinessID =@BusinessEntityID OUTPUT;

SELECT @BusinessEntityID as [BusinessEntityID]
GO
--OUTPUT

BusinessEntityID
———————
1
(1 row(s) affected)

Example-2 :
In this example we know only one parameter and the rest of the parameters we don’t. Simply we need to pass t-sql and the known parameter to sp_describe_undeclared_parameters, and it will give you the unknown / undeclared parameter information.

sp_describe_undeclared_parameters @tSQL=N'SELECT @BusinessID=[BusinessEntityID]
from [HumanResources].[vEmployee] Where [FirstName]=@FName'
,@params =N'@FName nvarchar(50)'
--OUTPUT

undeclared_parameters1.2

Example-3 :
Sometimes, we know all the parameters but to make sure none of the parameters is missing, simply we need to pass t-sql and the all parameters to sp_describe_undeclared_parameters, it will give you the  missing parameters (if any), otherwise Nil result set.

sp_describe_undeclared_parameters @tSQL=
N'SELECT @BusinessID=[BusinessEntityID]
from [HumanResources].[vEmployee] Where [FirstName]=@FName'
,@params =N'@FName nvarchar(50), @BusinessID INT OUTPUT'

undeclared_parameters1.3

Will post some real world examples in the upcoming posts.

Read Full Post »

In my previous article, I wrote about Executing Stored Procedure with Result Sets. I utilized this new feature introduced in SQL Server 2012 many times and it is very handy, when it comes to manipulate stored procedure result sets.

Today, I was reading a question related to this topic in a forum where a community member tried to manipulate stored procedure result set with result sets keyword and then insert it into a temporary table. But it gives an error.

Let me create few examples to explain the problem :

Example 1 :
In this example, we will insert the result set of a stored procedure in a temporary table without using result set keyword and it works fine.

Use AdventureWorks2012
GO
Create Table #temp
(
[DepartmentID] int,
[Name] varchar(50)
)
GO
Create PROCEDURE SP_ResultSet_Example1
as
Select [DepartmentID]
,[Name]
from [HumanResources].[Department]
GO
Insert into #temp EXEC SP_ResultSet_Example1
GO
Select * from #temp order by [DepartmentID]

resultseterror1.1

Example 2 :
In this example, we will insert the result set of a stored procedure in a temporary table with result sets keyword. It gives an error .

Use AdventureWorks2012
GO
Create Table #temp
(
[DepartmentID] int,
[Name] varchar(50)
)
GO
Create PROCEDURE SP_ResultSet_Example1
as
Select [DepartmentID]
,[Name]
from [HumanResources].[Department]
GO

Insert into #temp EXEC SP_ResultSet_Example1 WITH RESULT SETS
(
([Department ID] int NOT NULL,
[Department name] Name NOT NULL));
GO
Select * from #temp order by [DepartmentID]

resultseterror1.2

Explanation :
We cannot use result sets keyword, when we need to insert any stored procedure result set into a table. The reason behind this is if we use result sets keyword we can return multiple results with different columns and with different data types from a single stored procedure and this functionality cannot be handled in a single table. As per MSDN ” WITH
Possible execute options. The RESULT SETS options cannot be specified in an INSERT…EXEC statement.”
.

Read Full Post »

sp_sequence_get_range System stored procedure is shipped with SQL SERVER 2012 and it is one of the handy system stored procedures when it comes to fetch range of IDs from SQL Server.
Note : Sequence is a prerequisite for this article.

Syntax :

sp_sequence_get_range [ @sequence_name = ] N''
, [ @range_size = ] range_size
, [ @range_first_value = ] range_first_value OUTPUT
[, [ @range_last_value = ] range_last_value OUTPUT ]
[, [ @range_cycle_count = ] range_cycle_count OUTPUT ]
[, [ @sequence_increment = ] sequence_increment OUTPUT ]
[, [ @sequence_min_value = ] sequence_min_value OUTPUT ]
[, [ @sequence_max_value = ] sequence_max_value OUTPUT ]
[ ; ]

Explanation :
Lets proceed step by step :

Step 1:

Lets create a sequence.

CREATE SEQUENCE [dbo].[Invoice]
AS [int]
START WITH 1
INCREMENT BY 1
MINVALUE 1
MAXVALUE 1000
CYCLE
CACHE
GO

Step 2:

Lets pick up a new ID from this sequence.

SELECT NEXT VALUE FOR dbo.[Invoice] as [New ID]
--OUTPUT

New ID
1

(1 row(s) affected)

Step 3:

Lets fetch the new IDs via sp_sequence_get_range and see the difference.

Example:

DECLARE @range_first_value sql_variant
, @range_first_value_output sql_variant
, @range_last_value_output sql_variant

EXEC sp_sequence_get_range
@sequence_name = N'dbo.Invoice'
, @range_size = 4
, @range_first_value = @range_first_value_output OUTPUT
, @range_last_value = @range_last_value_output OUTPUT

SELECT @range_first_value_output AS [First ID]
,@range_last_value_output as [Last ID]
--OUTPUT

First ID       Last ID
2                5

(1 row(s) affected)

In the above example, you can see that this stored procedure returns a range from 2-5 IDs (First Value – Last Value),  so can use all four IDs (2, 3,4, 5) in your application.

If you execute the same script, 2nd time it will give you the range from 6-9 IDs and it will carry on till it reaches its maximum ID.

sp_sequence_get_range is not limited to return First & Last ID only. It will return other info related to sequence as well.

Step 4:

In Step 2 & Step 3, you can see both techniques are used to get new ID (s), but the difference between both of them is the requirement.

Whenever you need only one new ID you need to use NEXT VALUE & and if you need to get a range of new IDs from sequence you need to use sp_sequence_get_range.

Step 5:
Lets create another example to return all possible result sets from sp_sequence_get_range.

Example:

DECLARE @First_Value sql_variant
, @Last_Value sql_variant
, @Cycle_Count int
, @Sequence_Increament sql_variant
, @Sequence_Min_Value sql_variant
, @Sequence_Max_Value sql_variant ;

EXEC sys.sp_sequence_get_range
@sequence_name = N'dbo.Invoice'
, @range_size = 5
, @range_first_value = @First_value OUTPUT
, @range_last_value = @Last_Value OUTPUT
, @range_cycle_count = @Cycle_Count OUTPUT
, @sequence_increment = @Sequence_Increament OUTPUT
, @sequence_min_value = @Sequence_Min_Value OUTPUT
, @sequence_max_value = @Sequence_Max_Value OUTPUT ;

SELECT
@First_value AS FirstVal
, @Last_Value AS LastVal
, @Cycle_Count AS CycleCount
, @Sequence_Increament AS SeqIncrement
, @Sequence_Min_Value AS MinSeq
, @Sequence_Max_Value AS MaxSeq ;

Real world example :

I recently developed a billing system for one of my clients and the major requirement was to open 4 different invoices before saving the previous invoices.

And the problem was that I could not get a new ID without saving the previous invoice. So, I used this technique and it was successful.

Reference : MSDN

Read Full Post »

Today, I was searching one stored procedure in the entire SQL server databases. To find this, I need to go to each database right click on procedure and then filter the name. It is little bit time consuming and boring work if you have more  number of Databases and you need to repeat this process number of times. Given below is the solution designed with the help of  a sys.procedures(system table).

Note : This solution is compatible with SQL SERVER 2005 and above.

-- Script Name: Sp_Search_Procedure_Across_Databases
-- Script Type : Search Stored Procedure Across all SQL Server databases.
-- Develop By: Muhammad Imran
-- Date Created: 03 Oct 2012

Create Procedure Sp_Search_Procedure_Across_Databases
@ProcedureName nvarchar(Max)
As
BEGIN
DECLARE @SQL nvarchar(MAX)     --Declare variable to store dynamic query result
DECLARE @DB_NAME nvarchar(200) --Declare variable to store Database name

SET @SQL=''

--Create table to store the result of each database
CREATE TABLE #SearchResult
(
[DB_Name] nvarchar(max),
[Procedure Name] nvarchar(max),
[Status] varchar(50)
)

--Declare cusrsor to loop across all databases
DECLARE DB_Cursor CURSOR FOR
--Pick the list of all database
SELECT QUOTENAME([name]) from sys.databases order by [name]

OPEN DB_Cursor
FETCH NEXT FROM DB_Cursor INTO @DB_NAME

WHILE @@FETCH_STATUS = 0
BEGIN
--In this dynamic query, two select statements are built because
--one statement will check the unavailability and the
--second statement will check the availability of the
--procedure in the database and insert the result in the #SearchResult table

SET @SQL= 'Insert into #SearchResult
SELECT ''' + @DB_NAME + ''' as [Database Name],'''',''Not Available''
from ' + @DB_NAME + '. sys.procedures
Where [name] like ''%' + @ProcedureName + '%'' Having Count(*)=0
UNION ALL
SELECT ''' + @DB_NAME + ''' as [Database Name],[name],''Available''
from ' + @DB_NAME + '.sys.procedures
Where [name] like ''%' + @ProcedureName + '%'' Group By [name]
Having Count(*)>0'

EXEC(@SQL)

FETCH NEXT FROM DB_Cursor INTO @DB_NAME
END
CLOSE DB_Cursor
DEALLOCATE DB_Cursor
--We can browse the table to view the results
Select * from #SearchResult Order by [DB_Name],[Procedure Name]
END
GO
--Syntax
--Sp_Search_Procedure_Across_Databases 'Stored Procedure Name'

--Example
Sp_Search_Procedure_Across_Databases 'SP_Employee'

Read Full Post »

In SQL Server 2012 , Microsoft has provided a very helpful new system stored procedure namely “sp_describe_first_result_set”. Like name, like Work.. As the name goes, so is the performance. It gives the detailed meta data(Schema) information for the first possible result set. Note that it works only in SQL Server 2012. If you need to get the meta data info in SQL Server 2005/2008, you need to use “SP_help” and with very limited info availability.

Syntax :

sp_describe_first_result_set [ @tsql = ] N'Transact-SQL_batch'
[ , [ @params = ] N'parameters' ]
[ , [ @browse_information_mode = ]  ] ]

Lets make some simple examples to check its functionality  :

EXEC sp_describe_first_result_set @tsql =N'SELECT * FROM HumanResources.Department'
GO
--OUTPUT

As I discussed, you can view the  output as a detailed meta data.

Now, let me explain why “first possible result set,” name is given to this procedure, with the help of a simple example.
Given below are two queries and it will return two sets of result as well.

SELECT * FROM [HumanResources].[Department];
SELECT * FROM [HumanResources].[Employee];

But, if we pass both the queries to “sp_describe_first_result_set” to provide meta data, it will provide the meta data of the first query only and according to this functionality this name (sp_describe_first_result_set) is given to this stored procedure. Lets execute this scenario.

EXEC sp_describe_first_result_set @tsql =N'SELECT * FROM [HumanResources].[Department];
SELECT * FROM [HumanResources].[Employee];'
--Output

Now, lets look at the different option of @browse_information_mode in sp_describe_first_result_set

Lets create a view to explain the different option of @browse_information_mode.

Use AdventureWorks2012
GO
Create View [HumanResources].[vDepartment]
AS
SELECT [DepartmentID] as [ID]
,[Name] as [Department Name]
FROM [HumanResources].[Department]
--Output

Now, lets execute sp_describe_first_result_set with the different option of @browse_information_mode.

@browse_information_mode=0

Use AdventureWorks2012
GO
EXEC sp_describe_first_result_set
@tsql =N'SELECT * FROM [HumanResources].[vDepartment];'
,@params=NULL,@browse_information_mode=0
GO
-- When @browse_information_mode=0, it will give you the meta data but no source data available in this option.

@browse_information_mode=1

Use AdventureWorks2012
GO
EXEC sp_describe_first_result_set
@tsql =N'SELECT * FROM [HumanResources].[vDepartment];'
,@params=NULL,@browse_information_mode=1
GO
-- When @browse_information_mode=1, it will give you the meta data along with the source info but the source details will be based on this view's table.

@browse_information_mode=2

Use AdventureWorks2012
GO
EXEC sp_describe_first_result_set
@tsql =N'SELECT * FROM [HumanResources].[vDepartment];'
,@params=NULL,@browse_information_mode=2
GO
-- When @browse_information_mode=2, it will give you the meta data along with the source info but the source details will be based on this view.

Reference : MSDN

Read Full Post »

In Sql server 2012,  Microsoft has introduced a very nice and interesting feature and that is execute stored procedure with result set.  With the help of feature, now we can change the column name & data type of the stored procedure result set.

Before SQL server 2012, we were doing the same but it was a lengthy procedure. First we had to create a temporary table and then execute the stored procedure and insert the result set in the temporary table and then select it.

Today, we will discuss the different aspects of this new feature.

Let me explain it with simple examples:

Example 1: (Stored procedure with Single Result set)

Use AdventureWorks2012
GO
Create PROCEDURE SP_ResultSet_Example1
as
Select [DepartmentID]
,[Name]
,[ModifiedDate]
from  [HumanResources].[Department]
GO
EXEC SP_ResultSet_Example1
GO

In the above example, we have three columns in the result set
[DeprtmentID],[Name],[ModifiedDate]

But, I would like to rename the column name and change the data type of Modified Date column in the result set like this
[Deprtment ID],[Department Name], [Modified Date]

Use AdventureWorks2012
GO
EXEC SP_ResultSet_Example1
WITH RESULT SETS
(
( [Department ID] int NOT NULL,
[Department name] Name NOT NULL,
[Modified Date] varchar(11) NOT NULL
));
GO
--Result

Example 2: (Stored procedure with Multiple Result set)

The same way we can do it for multiple result sets also. Given below is the example.

--Without resultset
Use AdventureWorks2012
GO
Create PROCEDURE SP_ResultSet_Example2
as
Select [DepartmentID]
,[Name]
,ModifiedDate
from  [HumanResources].[Department]
Select 'Total' as [Total] ,Count(*) as [Count] from [HumanResources].[Department]
GO
EXEC SP_ResultSet_Example2
GO
--With resultset
Use AdventureWorks2012
GO
EXEC SP_ResultSet_Example2
WITH RESULT SETS
(
( [Department ID] int NOT NULL,
[Department name] Name NOT NULL,
[Modified Date] varchar(11) NOT NULL
),
(
[Total] varchar(5) NOT NULL,
[Department Count] Int NOT NULL
));

Limitations :

  1. You cannot change the data type to any incompatible data type.

For example: Cannot change from varchar to int.

  1. You cannot reduce or increase the number of columns in result set.



Summary:

In this article, we discussed how we can rename and change the data type of the stored procedure output. This feature is very handy especially for SQL Server Integration Services (SSIS) developers when they need to rename/ change the column name and data type respectively in the result  set.

Reference : MSDN

Read Full Post »