HOW TO CONVERT TABLE DATA TO XML AND XML TO TABLE

HOW TO CONVERT TABLE DATA TO XML AND VICEVERSA.

Table to XML and XML to Table

The below code explains how to convert the data in a table to xml form and then convert the xml back into table data.

Creating sample table with data:

CREATE TABLE tmpEmployee(ID INT,NAME VARCHAR(100))
GO

INSERT INTO tmpEmployee
SELECT 1,'Devi'
union
SELECT 2,'Prasad'
GO


SELECT * FROM tmpEmployee
GO

Below code converts data and schema of table tmpEmployee into XML, Then it uses the XML to convert it back into the table:

/*Below code converts Table SCHEMA & Data to XML*/

DECLARE @TableData XML,@TableSchema XML

SELECT @TableSchema = (
select column_name,
data_type,
case(is_nullable)
when 'YES' then 'true'
else 'false'
end as is_nullable,
CHARACTER_MAXIMUM_LENGTH as Charlen
from information_schema.columns [column]
where table_name = 'tmpEmployee'
for xml auto,root('Table')
)

SELECT @TableData = (
SELECT *
FROM tmpEmployee Row
FOR XML AUTO, BINARY BASE64,root('TableData')
)

SELECT @TableSchema,@TableData

/*Below code converts XML to Table*/

if object_id('tempdb..#XMLColumns') is not null
drop table #XMLColumns

SELECT x.value('@column_name', 'sysname') AS column_name
,x.value('@data_type', 'sysname') AS data_type
,x.value('@is_nullable', 'VARCHAR(20)') AS is_nullable
,x.value('@Charlen', 'VARCHAR(20)') AS Charlen
into #XMLColumns
FROM @TableSchema.nodes('/Table/column') TempXML (x)

select * from #XMLColumns

DECLARE @SQL nVARCHAR(MAX) = 'SELECT '

SELECT @SQL = @SQL + '
x.value(''@'+column_name+''', '''+data_type+case when Charlen is null then '' else '('+Charlen+')' end + ''''+') AS ['+column_name+'],'
from #XMLColumns

SET @SQL = LEFT(@SQL, LEN(@SQL) - 1)

SELECT @SQL = @SQL + ' FROM @TableData.nodes(''/TableData/Row'') TempXML (x)'

EXEC sp_executeSQl @SQL,N'@TableData xml',@TableData=@TableData

Output:

tmpEmployee:

ID NAME
----------- ----------------------------------------------------------------------------------------------------
1 Devi
2 Prasad


(2 row(s) affected)

@TableSchema:

<Table>
<column column_name="ID" data_type="int" is_nullable="true" />
<column column_name="NAME" data_type="varchar" is_nullable="true" Charlen="100" />
</Table>

@TableData:

<TableData>
<Row ID="1" NAME="Devi" />
<Row ID="2" NAME="Prasad" />
</TableData>

Table generated from XML:

ID NAME
----------- ----------------------------------------------------------------------------------------------------
1 Devi
2 Prasad


(2 row(s) affected)

Deadlock Internals with Real Time Scenario – Explanation and Resolution

What is deadlock?
A deadlock is a situation in which two or more competing actions are each waiting for the other to finish, and thus neither ever does.
Refer: http://en.wikipedia.org/wiki/Deadlock

Scenario:
Data Preparation Script: (Script-a)

[sql]
–Create Sample Database
CREATE DATABASE SampleDeadLockDatabase
GO

USE SampleDeadLockDatabase
GO

–Create Sample Tables
CREATE TABLE SampleTable1(ID INT IDENTITY(1,1),VALUE UNIQUEIDENTIFIER)
GO

CREATE TABLE SampleTable2(ID INT IDENTITY(1,1),VALUE UNIQUEIDENTIFIER)
GO

–Populate Sample tables
INSERT INTO SampleTable1(VALUE)
SELECT NEWID()
GO 10

INSERT INTO SampleTable2(VALUE)
SELECT NEWID()
GO 10

–Retreive data for verification
SELECT * FROM SampleTable1
SELECT * FROM SampleTable2
[/sql]

Transaction1 Script: (Script-b)

[sql]
Select @@SPID — Note down this value here (68)
——————Transaction1——————-
–Step1 Begins–
USE SampleDeadLockDatabase
GO
BEGIN TRAN

UPDATE SampleTable1
SET VALUE = ‘1DF1EBE1-322E-4698-A5BD-2E2C6D85AEB6’
WHERE ID=1
–Step1 Ends–

—RUN Step2 in Transaction2

–Step3 Begins–
SELECT * FROM SampleTable2 WHERE ID=4

ROLLBACK TRAN
–Step3 Ends–
——————Transaction1——————-

[/sql]

Transaction2 Script: (Script-c)

[sql]
Select @@SPID — Note down this value here — 65
——————Transaction2——————-
–Step2 Begins–
USE SampleDeadLockDatabase
GO
BEGIN TRAN

UPDATE SampleTable2
SET VALUE = ‘23154CCE-0919-4D3A-92EB-E6B4062F8715’
WHERE ID=3
–Step2 Ends–

–Step4 Begins–
SELECT * FROM SampleTable1 WHERE ID=5

ROLLBACK TRAN
–Step4 Ends–
——————Transaction2——————-
[/sql]

Data Preparation:
In SQL Server Management Studio, Click on new query
Paste the Data Preparation Script, and execute it.

Dead Lock Scenario Creation:
Paste the two code snippets transaction1 and transaction 2 in separate query windows.
In each of them highlight the code (SELECT @@SPID) and run it to note down the SPID
Now run the Step1 in transaction1
This step updates SampleTable1 with a new value for id 1
Now run the Step2 in transaction2
This step updates SampleTable2 with a new value for id 3
Now run the Step3 in transaction1
This step selects the values of SampleTable2 with id 4
You will notice that this step3 is still executing. Why? We will analyze this later in the post.
Now run the Step4 in transaction2
This step selects the values of SampleTable1 with id 5
You will notice that this step executes for few seconds and completes. Also one of the session (Transaction1 or Transaction2 will be deadlocked.) with the errormessage


Msg 1205, Level 13, State 45, Line 1
Transaction (Process ID 65) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

Analysis:
Why Step3 was waiting (Blocked?)
So now let us replicate the scenario again, by running the above steps1 and 2.
In the new query window (again a new Query window 🙂 ) Run the below script to understand what locks are placed on the tables pages and rows.

Script-d
[sql]
–Update this id with the @@spid of transaction1
SELECT resource_type,
resource_description,
resource_associated_entity_id,
request_mode,
request_type,
request_status FROM sys.dm_tran_locks
where request_session_id = 68

–Update this id with the @@spid of transaction2
SELECT resource_type,
resource_description,
resource_associated_entity_id,
request_mode,
request_type,
request_status FROM sys.dm_tran_locks
where request_session_id = 65

–Fetch the partition_id of the table
select p.partition_id,t.name,t.object_id From sys.partitions p join sys.tables t
on t.object_id = p.object_id
where t.name in (‘SampleTable1′,’SampleTable2’)
[/sql]

Update the values above with the respective @@spud’s that we noted down earlier. (SPID’s of the respective queries)
Output:

Table Locks

When you execute this you can find that each session has created exclusive lock (X) on the row level and intent exclusive (IX) locks on the page and table level.
Let’s find what exactly those rows are.
Copy the resource_description values for resource_type RID to the below script and run it.

Script-e:
[sql]
select * From SampleTable1 (nolock) where %%lockres%% = ‘1:154:0’
select * From SampleTable2 (nolock) where %%lockres%% = ‘1:156:2’
[/sql]

This would output the rows that we updated in respective transactions.

Lockres Output

Now run the step3 in transaction1, and run the script-d pasted above.
Output:
Shared Lock Waiting

You will notice that transaction1 now has the new lock for RID 1:156:2 which is in waiting state.
It’s waiting for an exclusive lock to be released on a row on SampleTable2
In order to find out the row for which transaction 1 is waiting copy the resource_description values to the below script and run it.
Script-f:
[sql]
select * From SampleTable2 (nolock) where %%lockres%% = ‘1:156:2’
[/sql]

Shared Lock Waiting For Row

So transaction1 is waiting for exclusive lock on row ID 3 to be released.
But in no way we are referring to rowid3 of transaction1., we were actually referring to row ID 4.

Why is SQL Server waiting for this row?

In order to understand this stop the step3 in transaction1 (it’s still getting executed) , select step3 code and click on Display estimated execution plan button ( or Query – Display estimated execution plan button) (or Ctrl + L )
You will find a table scans in the execution plan.

Waiting Transaction Execution Plan

So this table scan is forcing SQL Server to actually scan all the rows in the table(for ID=4) , as the ID=3 is blocked by transaction 2 it is waiting for transaction 2 to actually complete in order to take shared lock on the row and compare its value with 4.

Similarly when step4 is executed it is blocked by transaction 1, as step 4 has to do a table scan on the table SampleTable1 for ID = 5, but the transaction 1 has exclusively locked the row ID = 1.
So,
Transaction 1 is blocked by Transaction 2
AND
Transaction 2 is blocked by Transaction 1
This causes deadlock situation.
As both transactions would stay for infinite time blocking each other.
So, one of the transaction that is easier to rollback is terminated by SQL Server giving deadlock error: 1205

Resolutions:
1. Change to Snapshot Isolation.
[sql]
ALTER DATABASE SampleDeadLockDatabase
SET READ_COMMITTED_SNAPSHOT ON
[/sql]

Run the above query after disconnecting all the queries connected to SampleDeadLockDatabase
Now if you run the above Dead Lock Scenario steps you will notice that the deadlock is not occurring now.

2.Create index on the table so that there will be alternates for Table Scan.
Before testing the below approach remove snapshot isolation

[sql]
ALTER DATABASE SampleDeadLockDatabase
SET READ_COMMITTED_SNAPSHOT OFF
[/sql]

Script to Create clustered indexes on tables.
[sql]
ALTER TABLE SampleTable1
ADD CONSTRAINT SampleTable1_PK PRIMARY KEY (ID)
GO

ALTER TABLE SampleTable2
ADD CONSTRAINT SampleTable2_PK PRIMARY KEY (ID)
[/sql]

Now if you run the above Dead Lock Scenario steps you will notice that the deadlock is not occurring now. But you can reproduce dead lock if you force SQL Server to do an index /table scan instead of index seek. Using WITH (INDEX (0)) hint in Step 3 and Step 4.

[sql]
–Step3 Begins–
SELECT * FROM SampleTable2 WITH (INDEX(0)) WHERE ID=4

ROLLBACK TRAN
–Step3 Ends—

–Step4 Begins–
SELECT * FROM SampleTable1 WITH (INDEX(0)) WHERE ID=3

ROLLBACK TRAN
–Step4 Ends–
[/sql]

How To View Data in Hidden System Tables.

SQL Server has System base tables which are hidden cannot be directly queried.

For example:

[sql]
SELECT * FROM sys.sysrscols
[/sql]

Output:

Msg 208, Level 16, State 1, Line 1
Invalid object name ‘sys.sysrscols’.

In order to view data from the hidden System base tables you have to connect to SQL Server using Dedicated Administrator Connection.

In order to connect using Dedicated Administrator Connection, Add ADMIN: before the name of the server\instance in SQL Server Management studio.

Dedicated Administrator Connection

Now you can query all the System tables. 🙂

[sql]

——————————————————————————————————————————————————
SELECT * FROM sys.sysrscols
GO
SELECT * FROM sys.sysrowsets
GO
SELECT * FROM sys.sysallocunits
GO
SELECT * FROM sys.sysfiles1
GO
SELECT * FROM sys.syspriorities
GO
SELECT * FROM sys.sysdbfrag
GO
SELECT * FROM sys.sysfgfrag
GO
SELECT * FROM sys.syspru
GO
SELECT * FROM sys.sysbrickfiles
GO
SELECT * FROM sys.sysphfg
GO
SELECT * FROM sys.sysprufiles
GO
SELECT * FROM sys.sysftinds
GO
SELECT * FROM sys.sysowners
GO
SELECT * FROM sys.sysdbreg
GO
SELECT * FROM sys.sysprivs
GO
SELECT * FROM sys.sysschobjs
GO
SELECT * FROM sys.syslogshippers
GO
SELECT * FROM sys.syscolpars
GO
SELECT * FROM sys.sysxlgns
GO
SELECT * FROM sys.sysxsrvs
GO
SELECT * FROM sys.sysnsobjs
GO
SELECT * FROM sys.sysusermsgs
GO
SELECT * FROM sys.syscerts
GO
SELECT * FROM sys.sysrmtlgns
GO
SELECT * FROM sys.syslnklgns
GO
SELECT * FROM sys.sysxprops
GO
SELECT * FROM sys.sysscalartypes
GO
SELECT * FROM sys.systypedsubobjs
GO
SELECT * FROM sys.sysidxstats
GO
SELECT * FROM sys.sysiscols
GO
SELECT * FROM sys.sysendpts
GO
SELECT * FROM sys.syswebmethods
GO
SELECT * FROM sys.sysbinobjs
GO
SELECT * FROM sys.sysaudacts
GO
SELECT * FROM sys.sysobjvalues
GO
SELECT * FROM sys.sysclsobjs
GO
SELECT * FROM sys.sysrowsetrefs
GO
SELECT * FROM sys.sysremsvcbinds
GO
SELECT * FROM sys.sysxmitqueue
GO
SELECT * FROM sys.sysrts
GO
SELECT * FROM sys.sysconvgroup
GO
SELECT * FROM sys.sysdesend
GO
SELECT * FROM sys.sysdercv
GO
SELECT * FROM sys.syssingleobjrefs
GO
SELECT * FROM sys.sysmultiobjrefs
GO
SELECT * FROM sys.sysguidrefs
GO
SELECT * FROM sys.syschildinsts
GO
SELECT * FROM sys.syscompfragments
GO
SELECT * FROM sys.sysftstops
GO
SELECT * FROM sys.sysqnames
GO
SELECT * FROM sys.sysxmlcomponent
GO
SELECT * FROM sys.sysxmlfacet
GO
SELECT * FROM sys.sysxmlplacement
GO
SELECT * FROM sys.sysobjkeycrypts
GO
SELECT * FROM sys.sysasymkeys
GO
SELECT * FROM sys.syssqlguides
GO
SELECT * FROM sys.sysbinsubobjs
GO
SELECT * FROM sys.syssoftobjrefs
GO
[/sql]

Interesting Observation – Declaring Table Variables impact on Tempdb

Following was an intresting observation when creating table variables.
1. Table variables are created in tempdb.
2. Table variables are created in tempdb even before the declare table is called.

Steps to find that the Table variables are created in tempdb:
1. Restart your local SQL Server instance. (So that the tempdb gets cleared)
2. Connect to the SQL Server in SQL Server management studio and check if there are any records in sys.objects in tempdb.
[sql]
SELECT * FROM tempdb.sys.tables
[/sql]
You will find there are 0 records(ideally)
3. In a new query window run the below script.
[sql]
USE MASTER
GO

DECLARE @TableVariable TABLE (ID INT,VALUE VARCHAR(100))

INSERT INTO @TableVariable
select 1,’A’

WAITFOR DELAY ’00:02:00′
[/sql]
4. While the above code is getting executed run the below script in other query window.
[sql]
SELECT * FROM tempdb.sys.tables
–Take objectid from the above resultset
SELECT * FROM tempdb.sys.columns where OBJECT_ID = 117575457
[/sql]

Result: It can be found that the tempdb.sys.tables and tempdb.sys.columns has records for the table variable. This proves that the table variable is created in tempdb.

Steps to find that the Table variables are created in tempdb even before the declare table is called:
1. Restart your local SQL Server instance. (So that the tempdb gets cleared)
2. Connect to the SQL Server in SQL Server management studio and check if there are any records in sys.objects in tempdb.
[sql]
SELECT * FROM tempdb.sys.tables
[/sql]
You will find there are 0 records(ideally)
3.In a new query window run the below script.

[sql]
SELECT * FROM tempdb.sys.tables

DECLARE @TableVariable TABLE (ID INT,VALUE VARCHAR(100))

INSERT INTO @TableVariable
select 1,’A’
[/sql]

Result: It can be found that there is a record in the tempdb.sys.tables even before the DECLARE Statement is executed. This proves that the table variables are created in tempdb even before the declare table is called.

Wishing all the blog readers advanced happy new year. 🙂

SSMS Available Databases DropDown Acts weird if Connection Properties Are Changed

SQL Server Management Studio (SSMS) Has a available databases dropdown ( to select a database to execute the query.).

Available Databases Dropdown in SSMS

This dropdown behaves weird when you change the connection properties.

Observation 1:
Run the below query in the query window
[sql]
SET PARSEONLY ON
[/sql]

Now when you try to expand the dropdown, the drop down does not expand.

Run the below query to turn off PARSEONLY
[sql]
SET PARSEONLY OFF
[/sql]

Observation 2:

Run the below query in the query window
[sql]
SET ROWCOUNT 2
[/sql]

Now if you try to click on the dropdown, you will find only 2 available databases.

Run the below query to reset ROWCOUNT to 0
[sql]
SET ROWCOUNT 0
[/sql]

Why is the dropdown behaving this way?
SSMS is using the same connection used by the query to fetch the Available databases list.
SSMS runs the below command to fetch the results for the Availabale Databases DropDown, using the same connection used by the Query.
[sql]
SELECT dtb.name AS [Name], dtb.state AS [State] FROM master.sys.databases dtb
[/sql]

Also, You would also get wrong results count into the @@ROWCOUNT, when you run the query and accidentally touch the availabale databases dropdown.

Observation 3:
Run the below query
[sql]
SELECT * FROM SYS.OBJECTS
SELECT @@ROWCOUNT as ROWSCOUNT
[/sql]
Make a note of the ROWSCOUNT Result.

Now run the query
[sql]
SELECT * FROM SYS.OBJECTS
[/sql]

Click on the available databases dropdown and run the below query.

[sql]
SELECT @@ROWCOUNT as ROWSCOUNT
[/sql]

You can identify the difference in the values of @@ROWCOUNT.

The first result would be the number of objects in the database.
The second result would be the number of databases in the Server.

Concatenating Data From Different Rows into Single Column Row

Consider a scenario where a table has multiple rows, and each of these rows belong to a group and the data from all the rows should be concatenated based on the group. This post explains different ways to accomplish this.

Sample data creation:
[sql]

CREATE TABLE GroupMembers(GroupName VARCHAR(100),MemberName VARCHAR(100))
GO

INSERT INTO GroupMembers
SELECT ‘Group1′,’A’
union
SELECT ‘Group1′,’B’
union
SELECT ‘Group1′,’C’
union
SELECT ‘Group1′,’D’
union
SELECT ‘Group1′,’E’
union
SELECT ‘Group1′,’F’
union
SELECT ‘Group1′,’G’
union
SELECT ‘Group1′,’H’
union
SELECT ‘Group2′,’A1’
union
SELECT ‘Group2′,’B1’
union
SELECT ‘Group2′,’C1’
union
SELECT ‘Group2′,’D1’
union
SELECT ‘Group2′,’E1’
union
SELECT ‘Group2′,’F1’
union
SELECT ‘Group2′,’G1’
union
SELECT ‘Group2′,’H1’
GO
SELECT GroupName,MemberName FROM GroupMembers
GO
[/sql]

The above created table has data that belongs to two groups Group1 and Group2.

Below TSQL Queries concatenate this data into single column/row for each group.
[sql]
–Sol1:
–Using XML
SELECT GroupName,
(SELECT MemberName
FROM GroupMembers WHERE GroupName=A.GroupName
FOR XML PATH(”))
FROM GroupMembers A
GROUP BY GroupName
GO

–Sol2:
–With out seperation between member names
–Using XML, Without XML Attributes
SELECT GroupName,
(SELECT MemberName AS [text()]
FROM GroupMembers WHERE GroupName=A.GroupName
FOR XML PATH(”))
FROM GroupMembers A
GROUP BY GroupName

–Sol3:
–With comma seperation between member names
–Using XML, Without XML Attributes
SELECT GroupName,
(SELECT MemberName+ ‘,’ AS [text()]
FROM GroupMembers WHERE GroupName=A.GroupName
FOR XML PATH(”))
FROM GroupMembers A
GROUP BY GroupName

–Sol4:
–With comma seperation between member names(no ending comma)
–Using XML, Without XML Attributes
SELECT G.GroupName,Left(G.Members,Len(G.Members)-1)
FROM (
SELECT GroupName,
(SELECT MemberName+ ‘,’ AS [text()]
FROM GroupMembers WHERE GroupName=A.GroupName
FOR XML PATH(”)) AS Members
FROM GroupMembers A
GROUP BY GroupName
) G
[/sql]

SQL Server Misconception – VARCHAR(MAX) Cannot Store More Than 8000 Characters

This post deals with one of the SQL Server Misconception – VARCHAR(MAX) Cannot Store More Than 8000 Characters.

Lets analyse this first
Take the below query.
[sql]
DECLARE @String VARCHAR(MAX)
DECLARE @i INT
SELECT @i = 10000,@String=”

WHILE @i>0
BEGIN
SELECT @String = @String + ‘A’
SET @i = @i – 1
END

PRINT @String
[/sql]

When you run this query you will get the following output.
Output:

Print Output Length

Find the length of the output:
When you move the cursor to the end of the output in the Messages window you can notice that the column number (as shown in above image) to be 8001(So length is 8000 characters).

This leads to the misconception
– VARCHAR(MAX) Cannot Store More Than 8000 Characters

Actuality:
– Print statement has a limit of 8000 characters(non-unicode) hence the output is truncated.
– The varchar(max) statement can store up to 2gb of data(2^31-1 bytes).

Take the below SQL Code
[sql]
DECLARE @String nVARCHAR(MAX)
DECLARE @i INT
SELECT @i = 10000,@String=”

WHILE @i>0
BEGIN
SELECT @String = @String + ‘A’
SET @i = @i – 1
END

SELECT LEN(@String) as Length
[/sql]

Output:
Length
——————–
10000


(1 row(s) affected)

LEN statement returns 10000 and it proves that varchar(max) can store more than 8000 characters.

FIX – Cannot Restore SQL Server 2000 Backup on SQL Server 2012

Unable to Restore SQL Server 2000 Backup on SQL Server 2012?

If you are trying to restore SQL Server 2000 backup on SQL Server 2008 you would be facing error like:


Msg 3169, Level 16, State 1, Line 1

The database was backed up on a server running version 8.00.2055. That version is incompatible with this server, which is running version 11.00.2100. Either restore the database on a server that supports the backup, or use a backup that is compatible with this server.

Restoring SQL Server 2000 backup to SQL Server 2012 is not supported.

Why?
According to MSDN In SQL Server 2012, you can restore a user database from a database backup that was created by using SQL Server 2005 or a later version.

How to restore then?
Fix/resolution:
Use SQL Server 2008 R2 as an intermediate source.

Steps:
1. First restore the SQL Server 2000 backup to SQL Server 2008 r2.
2. Then backup the database from SQL Server 2008 r2 and restore it on SQL Server 2012.

If you do not have SQL Server 2008 r2, You can download a trial version of SQL Server 2008 r2 from the below links.
http://msdn.microsoft.com/en-us/evalcenter/ff459612
http://www.microsoft.com/sqlserver/en/us/editions/previous-versions.aspx

Alternatively you can use SQL Server 2005 (or) SQL Server 2008 also as an intermediate source.

Following the above steps should help solve the problem.

Also verify the database backup on each target server before restoring: Verify SQL Server Database Backup

How to call or execute a Stored Procedure from inside a Select Statement

How to call or execute a Stored Procedure from Select Statement in SQL Server?

It is really simple to call a stored procedure from a select statement Using OPENROWSET.

Below TSQL Query calls the procedure sp_who from the select statement.

[sql]
SELECT * FROM
OPENROWSET(‘SQLNCLI’
,’Server=(local);Trusted_Connection=Yes;Database=Master’
,’EXEC dbo.sp_Who’)
[/sql]

Syntax:
[sql]
SELECT * FROM
OPENROWSET(‘SQLNCLI’
,’Server=(local);Trusted_Connection=Yes;Database=Master’
,’EXEC [procedurename]’)
[/sql]

Additional Information:
The data that is coming from the procedure can also be filtered in the where clause.

[sql]
SELECT * FROM
OPENROWSET(‘SQLNCLI’
,’Server=(local);Trusted_Connection=Yes;Database=Master’
,’EXEC dbo.sp_Who’)
where dbname = ‘master’
[/sql]

The data from the execution of a select statement can be directly pushed into a table.

[sql]
SELECT * INTO who2_table FROM
OPENROWSET(‘SQLNCLI’
,’Server=(local);Trusted_Connection=Yes;Database=Master’
,’EXEC dbo.sp_Who’)
where dbname = ‘master’
[/sql]

If the openrowset is disabled in the system, learn how to enable it using this link enable openrowset

Related to SQL Server 2005,SQL Server 2008,SQL Server 2012

Who Killed My SQL Server Process?

Who Killed My SQL Server process – session – connection – spid?
If you are sharing single database server with multiple users you might many times end up your process being force killed and an error message shown below comes up.

Msg 233, Level 20, State 0, Line 0
A transport-level error has occurred when sending the request to the server. (provider: Shared Memory Provider, error: 0 – No process is on the other end of the pipe.)

You might be interested in policing as to who killed your process?
Was it done intentionally or some server side error occurred?

In this post let us analyze a technique to sport the user who killed your process:

Using SQL Server error Log:
SQL Server logs errors to the sql server error log, It can be found that it also logs the killing of processes in its error log.

So first query the latest error log for the word kill.
[sql]
EXEC sys.xp_readerrorlog 0,1,’kill’
[/sql]
If you cannot find any results then continue with the next error log
[sql]
EXEC sys.xp_readerrorlog 1,1,’kill’
[/sql]

You can find the logdate,the killed SPID ,Host name and host processid that killed the process in the result

Killed Processes

Now find out the record for your processid in the result.

To find the user who killed your process run the below queries replacing the host process id with the value that you found out in the above step.

[sql]
select login_name,* from sys.dm_exec_sessions where host_process_id = ‘[host process ID]’
[/sql]

The login_name in the result gives you the login name of the user who killed your process.

Hope this post helps..
Applicable to sql server 2005,sql server 2008,sql server 2008 r2,sql server 2012
Also read: Read SQL Server Error Log Using TSQL Query

Do Comment if you wanted to discuss further or have any issues.