Convert an XML Variable Datatype to Relational Table Sql Server

0 comments

Posted on 10th February 2010 by admin in Scripts

, , , ,

***I’ve been having difficulty getting the code to display correctly. NOTE: the xml code is case sensitive! I’ve been trying to get all the bugs this lovely blog template is throwing at me, but I’m sorry if i miss some.***

This is an easy way to get xml into a relational table to work a little easier with other tables in the database. There are a few ways out there that produce the same result, but it seemed like this was the simplest to work with.

declare @xml xml
set @xml =
'~~?xml version="1.0" encoding=''UTF-8'' ?~~
    
        
        
        
        
        
    '
 select  c.value('@question[1]','varchar(255)') as Question
   ,c.value('@answer[1]','int') as Answer
 from @xml.nodes('//rows/item') as t(c)

Because of how the blog parses things, replace ~~ with the respective greater than or less than brackets.

The query is parsing everything for you and putting into a table. The example is using attributes for the query statement. Its a little easier on the eyes for me when trying to read what the results are expected to be, but I do not work with xml that much.

In the time I’ve been playing with it, it seems the default way is to use elements exclusively. As this example shows:

declare @xml xml
set @xml =
'~~?xml version="1.0" encoding=''UTF-8'' ?~~
    
        
            name1
            1
        
        
            name2
            2
        
        
            name3
            3
        
        
            name4
            4
        
        
            name5
            5
        
'
 select  c.value('question[1]','varchar(255)') as Question
   ,c.value('answer[1]','int') as Answer
 from @xml.nodes('//rows/Item') as t(c)

Besides the format change, the only thing that really changed in the query is I told it to look for elements. This is represented by the change from ‘@question[1]‘ to ‘question[1]‘. A small change, but this little small change can be really frustrating to try to figure out if you don’t know about it.

The just element route bugged me in trying to explain things, cuz everything I’ve been dealing with has a mix of elements and attributes. So getting confused on how to call it was the hardest step trying to reverse engineer my findings from internet blogs.The big thing to remember is attributes are called with an @ symbol before the attribute name, and the element is called with just the element name.

The value that is in the brackets is what date you are trying to grab. Since there is only one item in the tree, this makes it easy to grab the first dataset… I’m sorry if I’m giving bad terminology, I’m a little new towards what to properly call it.

If there is a situation where you want only the second dataset as this example:


    
        
            name1
            1
            name6
            6
        

Querying with the value of ‘question[2]‘ will return the Question:name6, answer:6 as a row in the table. However, with the limited playing I have done, i don’t know how to only tell it to go for the 2nd data set for a particular element. With the code as ‘question[2]‘, it is going to return all the second “Items.” Something to play around with for sure.

The data type after which attribute/element you are querying is what you need to convert to for the table to display. You want to make sure you have compatible data types. They use SQL data types, so stick to the minimal data types you are expecting.

To specify where you want to look in the xml, the @xml.nodes is where you do it. In the example above, I have the root as rows and the first element as Item. Can’t get much easier that that. :D

Get quick information on what queries are running on your SQL Server instance

0 comments

Posted on 2nd February 2010 by admin in Scripts

, , , , , , , , ,

This is for SQL Server 2005 and higher.

Whenever I need to get the queries that are currently running on the system, I tend to run this query first.

select
    r.session_id,
    r.start_time,
    r.status,
    r.command,
    db_name(r.database_id) as db,
    r.blocking_session_id,
    r.wait_type,
    r.wait_time,
    r.wait_resource,
    r.percent_complete,
    r.estimated_completion_time,
    r.cpu_time,
    r.total_elapsed_time,
    r.scheduler_id,
    r.reads,
    r.writes,
    r.logical_reads,
    r.row_count,
    r.granted_query_memory,
    case r.statement_end_offset
    when -1 then NULL
    else object_name(s2.objectid, s2.dbid)
    end,
    case r.statement_end_offset
    when -1 then s2.text
    else substring(s2.text, r.statement_start_offset/2, (r.statement_end_offset/2) - (r.statement_start_offset/2))
    end,
    s3.query_plan
from sys.dm_exec_requests r
    cross apply sys.dm_exec_sql_text(r.sql_handle) as s2
    cross apply sys.dm_exec_query_plan (r.plan_handle) as s3
where r.status <> 'background'
    and r.command <> 'task manager'
    and r.session_id <> @@SPID
    and r.database_id <> db_id('msdb')
order by r.cpu_time desc
        

It has a little more information than sp_who2 and gives you a rough idea of what is running at the time you execute this script. Running this script multiple times is probably going to return different results every time besides when nothing is running on the server. It’s light-weight and should not take longer than a second. The only time this script should be longer is when you have a serious problem going on with your system.

Now a lot of useful information is being presented here. Most are self explanatory, like the session_id or ‘Status’. However, this script helps in your initial investigation for blocking spids. The Wait_type/time/resource columns allow you to get an initial idea of the problem, and you can always look a little deeper in the sys.dm_os_waiting_tasks system view to get a better idea of the problem for blocks. Finding block reasons can turn into a whole post in it self, as that is not the only way to diagnose blocking spids. SQL Server provides lots of tools to find the necessary information.

Typically the Percent Complete and Estimated Completion Time are for tasks which provide how along the query is and what it is expected to finish. Usually it will be blank. The best example I can think of that uses those columns is when you are doing a backup for a database or when you are shrinking your database. Unfortunately the estimated completion time is Microsoft time… soo take it with a grain of salt. The percent complete is usually pretty accurate, but can be random on how fast it gets to 100%.

The next few columns are stats on the query you are running. It should be obvious with any of these columns, the higher the number, the worse off you are. The differences between reads and logical reads is the former is for physical HDD reads while the latter is for memory reads. Typically you want more logical reads than physical reads, but as always, the higher the number, the more intensive and a hog of the system resources it is. The highest number I’ve seen for logical reads is in the 100s of billions… That was an interesting day of doom.

Granted Query Memory is a column which shows how much memory has been devoted to this query. Since this is a count of pages for memory, you have to a do a little math to get an idea of how much memory is taken up in KB terms. I didn’t add the calculations to the query since I just know a high number can be doomy, but if you want to know the actually amount in terms of KiloBytes, here is the equation:

    (r.granted_query_memory *8060)/1024 as Granted_Query_Memory

A memory page has 8060 bytes of information after overhead, and dividing it by 1024 gets the number of kilobytes assigned to the memory page.

The next two columns provide some helpful information if they are provided. The first column is the object name (sproc/function) of the outer scope of the script running. The second is the sql script it is currently running to provide all the information. Usually the scope is what single script its running, but some times it pulls back the entire object script for you to figure out where the problem is.

The next column is the Query Plan. This guy is so full of information its great you have the ability to see it :D Its the actual execution plan the SQL Server Optimizer is using to run the query with. Since it is just an XML data type, there are two ways to view it. When you click it, it behaves differently depending on which version of SQL Server Management Studio you are using. SQL Server Management Studio 2008 and above see it as a SQL Plan and open it as such without any manipulation.

Unfortunately, it is not as easy in SQL Server Management Studio 2005. Upon opening the XML data type, it opens it in the default XML fashion. What you can do to get the visual representation is to save the file on your HDD. When saving, change the file name from XML to ‘.sqlplan’. Then you open the new sqlplan file and you get the graphical representation of the execution plan. This is an extra step for displaying the same information in the XML file, but its a lot smoother in SQL Server Management Studio 2008 and up.

Most of this information is coming from the system view sys.dm_exec_requests, with the sql text and plan coming from the system functions sys.dm_exec_sql_text and sys.dm_exec_query_plan. The where clauses filter out some of the common noise, but play with everything to get a better feel for what you need. This is the script I commonly use when working with a database problem. It’s scope is system wide, so you do not need to worry about being in a specific database.

This isn’t a script that will tell you everything, but gives a great way to start your investigation. I hope it does you well.