Requires A Singleton?

Facebooktwitterredditpinterestlinkedinmail

Have you ever got this error message when you tried to parse an XML string in SQL Server?

XQuery [value()]: ‘value()’ requires a singleton (or empty sequence), found operand of type ‘xdt:untypedAtomic *’

DECLARE	@XMLToParse  XML
 
-- Load the XML data in to a variable to work with.
-- This would typically be passed as a parameter to a stored proc
SET		@XMLToParse =	'
								Baboon
						 '

SELECT	
@XMLToParse.value('data(/Animal/AnimalName)', 'VARCHAR(MAX)') AS AnimalName

 
How do we fix this?

This error is saying that the value() function needs an xpath that only exits once (non-repeating node). You and I know that there will only be one instance of , but SQL Server does not know that. To solve this, we just need to tell SQL Server that it should use the first instance of this AnimalName node that it finds. We do this by added the [1] tag to the xpath. We want to add it after the closing parentheses. This will tell SQL Server to grab whatever is the first node with that name.

DECLARE	@XMLToParse  XML
 
-- Load the XML data in to a variable to work with.
-- This would typically be passed as a parameter to a stored proc
SET		@XMLToParse =	'
								Baboon
						 '

SELECT	
@XMLToParse.value('data(/Animal/AnimalName)[1]', 'VARCHAR(MAX)') AS AnimalName
-- Notice the [1] on the line above!

 
Extra Fun

If there are multiple nodes with the same name in your XML, you can adjust the number inside the square braces to match whatever node you want. For example:


	Baboon
	Cat
	Dog 

[1] would return Baboon
[2] would return Cat
[3] would return Dog

How To Create A Date Table

Facebooktwitterredditpinterestlinkedinmail

Many times when developing SQL Server databases you have the requirement to show all dates in a range. One way to do this is with a date table. One of the most common reasons that I use a date table is when I have a reconciliation report. In a reconciliation report I want to show all of the days in a date range, even if they don’t have data on those days. SQL Server doesn’t have a function to generate dates in a range. So to accomplish this, I create a date table using the following script.

CREATE
TABLE	DateTable
		(DateValue	DATETIME)

GO

DECLARE @StartDate		DATETIME = '01/01/2014'
DECLARE @NumberOfDays	INT = 3000

INSERT
INTO	DateTable
		(DateValue)
SELECT	DATEADD(DAY, RowNum, @StartDate) AS DateValue
FROM	(SELECT	TOP (@NumberOfDays)
				p1.PARAMETER_ID,
				ROW_NUMBER() OVER (ORDER BY p1.PARAMETER_ID) - 1 AS RowNum
		 FROM	sys.all_parameters p1
		 CROSS	JOIN sys.all_parameters p2) NumberTable

 

SQL Server Quarter From Date

Facebooktwitterredditpinterestlinkedinmail

One question that we get a lot is how to get the quarter from a date.  SQL Server has a very easy way to get the quarter from a date (since SQL 2005) using the DATEPART command.

 
To get the quarter from the current date

SELECT	DATEPART(quarter, GETDATE()) AS Quarter_From_Date

 
To get the quarter from a different date

DECLARE	@DateToCheck DATETIME

SET		@DateToCheck = '7/1/2014'

SELECT	DATEPART(quarter, @DateToCheck) AS Quarter_From_Date

 

SQL Server Truncate Date

Facebooktwitterredditpinterestlinkedinmail

A common function that people need to do when dealing with datetimes is extracting the date from the datetime.  Oracle has a built-in function to do this called TRUNC.  SQL Server does not have this (yet).  However… you can accomplish this very easily.  Here are a few ways to perform a truncate date function in SQL Server.

-- Assign date to variable
DECLARE	@DateToTruncate	DATETIME = '2014-08-01 14:12:34'

-- Get the date using casts
SELECT	CAST(CAST(@DateToTruncate AS DATE) AS DATETIME)

-- Get the date using convert
SELECT	CAST(CONVERT(VARCHAR(10), @DateToTruncate, 101) AS DATETIME)