Tag Archives: #TSQL

Articles on T-SQL. This can be a script or a syntax element

#0170-SQL Server-Deprecated Features-Column Alias defined by a string enclosed in quotation marks


I recently wrote a piece about the impact of table and column aliases on query performance and plan cache size. As I was writing the post, I recalled that there are multiple ways in which column aliases can be defined in a T-SQL query, depending upon the developer’s preference. However, one of these methods is marked for deprecation in one of the future releases of Microsoft SQL Server (it is still a valid method for SQL Server 2012, so there is no cause of worry in the immediate future).

The available methods for column aliasing and their status is shown in the table below:

Format Status
‘column_alias’ = expression Deprecated
expression AS column_alias Active
expression AS ”column_alias” Active
expression AS [column_alias] Active
[column_alias] = expression Active
expression AS “column_alias” Active

All of these methods are demonstrated in the query below:

USE AdventureWorks2012;
GO

SELECT                                            --           Format            ;   Status
    "Employee Birth Date" = Employee.BirthDate,   -- "column_alias" = expression ; Deprecated
    Employee.HireDate AS JoiningDate,             -- expression AS column_alias  ; Active
    Employee.BusinessEntityID AS "EmployeeId",    -- expression AS "column_alias"; Active
    Employee.OrganizationLevel AS [Org. Level],   -- expression AS [column_alias]; Active
    [Salary Flag] = Employee.SalariedFlag,        -- [column_alias] = expression ; Active
    Employee.SickLeaveHours AS "SickHours",       -- expression AS “column_alias"; Active
    "VacationHours" = Employee.VacationHours      -- "column_alias" = expression ; Deprecated
FROM HumanResources.Employee AS Employee;
GO

My recommendations

My recommendations around any such feature is:

  • To have one standard for the entire organization/product
  • The element adopted as the standard should not have been marked for deprecation for at least the next 2 major releases of Microsoft SQL Server
  • Finally, and the most important consideration is that the feature should help the team become more productive and efficient

I personally use either expression AS [column_alias] OR [column_alias] = expression methods.

Before you leave, do share your preferred format for column aliasing.

Until we meet next time,

Be courteous. Drive responsibly.

SQL Server – Experiments with BIT data type – Is it really Boolean? Can values other than 0 and 1 be assigned?


Recently at the office, we ended up discussing the BIT data type (http://msdn.microsoft.com/en-us/library/ms177603.aspx). While we all understand that BIT is supposed to represents a Boolean value, we were not quite convinced. Boolean values are two-state – they can only be TRUE or FALSE (or 1 and 0). However, we have seen BIT to be NULL a couple of times. Therefore, the questions that we had in our minds were:

  1. Is BIT really a two-state data type? Or is it tri-state (for those not familiar with the world of electronics, the tri-state is a state that’s undefined – it’s neither ON nor OFF)
  2. Do we need to use only a 0 or a 1 to initialize the BIT data type?
  3. Can we use ‘TRUE’ and ‘FALSE’ with the BIT datatype?

Finally, we decided to perform a little experiment. We prepared a small script covering the possible scenarios and checked their outputs. The script is available for your reference below:

--Declare the variable
DECLARE @bit BIT

--Check for default value
SELECT @bit AS DefaultValue

--Set to a positive value, other than 0 or 1
SET @bit = 99;
SELECT @bit AS [PositiveValue];

--Set to a negative value
SET @bit = -99;
SELECT @bit AS [NegativeValue];

--Set to a decimal value > 0 and < 1
SET @bit = 0.25;
SELECT @bit AS [DecimalValue025];

--Set to a decimal value > 0 and < 1
SET @bit = 0.50;
SELECT @bit AS [DecimalValue050];

--Set to a decimal value > 0 and < 1
SET @bit = 0.75;
SELECT @bit AS [DecimalValue075];

--Set to a string value - TRUE
SET @bit = 'TRUE';
SELECT @bit AS [StringTRUE],
       CASE
           WHEN @bit = 'TRUE'
           THEN 'Yes'
           ELSE 'No'
       END AS  [StringComparison];

--Set to a string value - FALSE
SET @bit = 'FALSE';
SELECT @bit AS [StringFALSE],
       CASE
           WHEN @bit = 'TRUE'
           THEN 'Yes'
           ELSE 'No'
       END AS  [StringComparison];

The results that came up resolved all our questions.

Results from my experiments with the BIT datatype. (Image (c)SQLTwins, nakulvachhrajani.com)
Experimenting with the BIT datatype in SQL Server

Conclusion

The above experiment helped us conclude that:

  1. BIT values are not completely Boolean, they are tri-state with NULL, 0 and 1 being possible values
  2. If left unassigned, the value is NULL
  3. If assigned with a value anything other than 0 or NULL, the value is taken as 1
  4. You can use a ‘TRUE’ and ‘FALSE’ string values with the BIT data type
  5. Because the default value of BIT is NULL, always assign your BIT variables! (for that matter, always assign a default value to any variable!)

I trust you found the above experiment interesting. I would welcome your ideas for future experiments.

Until we meet next time,

Be courteous. Drive responsibly.

CAST v/s CONVERT – Is there a difference as far as SQL Server is concerned? Which is better?


Data type conversion has been one of the most used features of any programming language. Microsoft SQL Server users are familiar with the two functions: CAST() and CONVERT() and use them regularly, and more specifically, interchangeably. A few months ago, I had written a post comparing the performance of CAST v/s CONVERT, and was able to prove that there is no difference in performance of the two functions.You can read that post here: https://nakulvachhrajani.com/2011/01/03/cast-vs-convert/.

Recently, a colleague and I were discussing a particular design element and found that a data type casting was required. During this discussion, the following questions almost simultaneously came to our minds –

  • If the performance and end results are the same, what is the difference between CAST & CONVERT aside from the fact that they have different syntax elements?
  • Do we really need 2 data conversion functions?
Parameter CAST CONVERT
ANSI standard Yes No
Data-type coverage Limited Full (Date & Date Time values supported)
Performance No difference No difference
Microsoft SQL Server implementation ?? ??
Books On Line Page http://msdn.microsoft.com/en-us/library/ms187928.aspx http://msdn.microsoft.com/en-us/library/ms187928.aspx

So, I ran a little test, and today, I will share with you my findings.

The CAST v/s CONVERT Test

The test is quite simple – we have two identical T-SQL statements, one using CAST, the other using CONVERT. We will use the Properties window of SSMS to analyze the execution plan and try to see what can be found about the underlying implementation.

Let’s take a look at our test statements:

/***********************************************************
Press Ctrl+M (or go to Query->Include Actual Execution Plan)
************************************************************/
USE AdventureWorks2008R2
GO
--Use CONVERT
select CONVERT(VARCHAR(10),BusinessEntityID) FROM HumanResources.Employee

--Use CAST
select CAST(BusinessEntityID AS VARCHAR(10)) FROM HumanResources.Employee
  1. Connect to your SQL Server instance using SQL Server Management Studio (SSMS)
  2. Copy the T-SQL code above into SSMS Query editor window
  3. Run the above T-SQL statements against your SQL Server instance
  4. Change over to the Execution Plan tab in the Results pane
  5. In the results pane, notice that both CAST & CONVERT have been implemented as “Compute Scalar” operators
  6. image
  7. Press the F4 key or go to View –> Properties to launch the properties window
  8. Expand the “Defined Values” node

CONVERT implementation

CONVERT does not come up with any surprises, and has a straightforward internal implementation as demonstrated in the Properties window.

image

CAST implementation

When we move to the properties for the query using the CAST operation, we see that under the hood, SQL Server does take us for a ride. Internally, CAST is implemented as a CONVERT call. There is no difference between CAST & CONVERT besides the fact that CAST is an ANSI standard, while CONVERT is not. No wonder both CAST & CONVERT demonstrate the same performance.

image

Surprised? Try it for yourself – I was not prepared to see what I saw when I first ran through the test. I restarted the entire server and got a cup of coffee to make sure I was not dreaming!

Conclusion

I guess all I need to do now is to complete the little grid I had above:

Parameter CAST CONVERT
ANSI standard Yes No
Data-type coverage Limited Full (Date & Date Time values supported)
Performance No difference No difference
Microsoft SQL Server implementation CONVERT CONVERT
Books On Line Page http://msdn.microsoft.com/en-us/library/ms187928.aspx http://msdn.microsoft.com/en-us/library/ms187928.aspx

What would I recommend?

Although we now know that to Microsoft SQL Server, data type conversion only happens via CONVERT, I would still prefer to go with CAST unless I am converting dates or date-time values. The reason being CAST is an ANSI standard, CONVERT is not. CONVERT is implementation specific, and therefore may change in terms of the number of parameters or underlying processes. To the calling T-SQL statement, it is safe to assume that CAST would remain unchanged (unless the standard changes) and therefore, it would be the responsibility of Microsoft SQL Server to translate the CAST to a CONVERT implementation.

Do share your thoughts on the whole CAST v/s CONVERT myths and controversies floating around in the SQL Server world. I will be more than happy to research more and share my findings with you.

Until we meet next time,

Be courteous. Drive responsibility.

CAST v/s CONVERT


Data type conversion has been one of the most used features of any programming language. Microsoft SQL Server users are familiar with the two functions: CAST() and CONVERT() and use them regularly, and more specifically, interchangeably.

However, using CAST() and CONVERT() interchangeably is one of the most capital mistakes that a developer can make. Madhivanan, a SQL Server blogger on BeyondRelational.com (http://beyondrelational.com/blogs/madhivanan/default.aspx) does a very good job at highlighting the differences between CAST() and CONVERT() in his blog post here.

To summarize, the differences that he highlights are:

  1. CAST is an ANSI standard, while CONVERT is specific to Microsoft SQL Server
  2. CAST cannot be used for formatting purposes (i.e. used to type cast something to a character string), whereas CONVERT can do so, especially for datetime and money datatypes
  3. CAST cannot convert a string to a DATETIME value of a required format (i.e. formatting as mm/dd/yyyy or dd/mm/yyyy as required etc), while the CONVERT can

Finally, he warns us to use a properly calculated size value when using the CAST and CONVERT functions to convert integer values to character data types.

All very great points, and very, very useful. Thank-you, Madhivanan for the wonderful research and enlightenment.

A Question

We can draw a general conclusion that for computation purposes, CAST should be used and for formatting of values for display on a UI or a report, CONVERT should be used. However, the interesting question is one which came up when I was following the discussion on the blog the other day –

Tuesday, July 27, 2010 10:38 AM by cute_boboi

For data extraction purpose, with 1M+ records, which method is faster/recommended ? CAST or CONVERT from:
(i) Date to varchar
(ii) Int to varchar

Today, I try to answer that question.

The Demonstration

Preparing the Environment

Let’s start by creating a table, and filling it up with some test data (Running against the AdventureWorks2008 database gives you about 356409 rows in the table):

-- Step 01. Create a test table
CREATE TABLE CASTCONVERTTest (Id INT,
                              CrDate DATETIME)

-- Step 02. Generate Test Data
INSERT INTO CASTCONVERTTest
SELECT sso1.Id, sso1.crdate
FROM sys.sysobjects sso1
CROSS JOIN sys.sysobjects sso2

Now, let’s begin by pressing Ctrl+M when in the SQL Server Management Studio or go to Query->Include Actual Execution Plan to enable showing the Actual Execution Plan.

Conversion of INT to VARCHAR

In order to see the performance of using CAST and CONVERT on INT to VARCHAR conversion, we will use the following script. At each stage, we will be using DBCC freeproccache to remove all elements from the plan cache.

/***********************************************************
Press Ctrl+M (or go to Query->Include Actual Execution Plan)
************************************************************/
-- Step 03. Test conversion of INT to VARCHAR
-- A. Remove all elements from the plan cache
DBCC freeproccache
GO

-- B. Check the performance of CAST
SELECT CAST(Id AS VARCHAR(11))
FROM CASTCONVERTTest
GO

-- C. Remove all elements from the plan cache
DBCC freeproccache
GO

-- D. Check the performance of CONVERT
SELECT CONVERT(VARCHAR(11),Id)
FROM CASTCONVERTTest
GO

Let’s look at the Actual Execution Plan used by SQL Server. As you can see, we get a 50-50 split, which means that both CAST and CONVERT perform equally well for the INT to VARCHAR conversion.

image

Conversion of DATETIME to VARCHAR

In order to see the performance of using CAST and CONVERT on DATETIME to VARCHAR conversion, we will use the following script. At each stage, we will be using DBCC freeproccache to remove all elements from the plan cache.

-- Step 04. Test conversion of DATETIME to VARCHAR
-- A. Remove all elements from the plan cache
DBCC freeproccache
GO

-- B. Check the performance of CAST
SELECT CAST(CrDate AS VARCHAR(25))
FROM CASTCONVERTTest
GO

-- C. Remove all elements from the plan cache
DBCC freeproccache
GO

-- D. Check the performance of CONVERT
SELECT CONVERT(VARCHAR(25),CrDate,106)
FROM CASTCONVERTTest
GO

Let’s look at the Actual Execution Plan used by SQL Server. As you can see, again we get a 50-50 split, which means that both CAST and CONVERT perform equally well for the DATETIME to VARCHAR conversion.

image

The Cleanup

Finally, as always, let’s cleanup the environment.

-- Step 05. Cleanup!
DROP TABLE CASTCONVERTTest

In Conclusion

In conclusion, we can safely conclude that both CAST and CONVERT perform equally well for the following conversions:

  1. INT to VARCHAR
  2. DATETIME to VARCHAR

I hope the above is a satisfactory reply to the question we started with.

Powered with the research conducted by Madhivanan and with the afore described performance test, the choice is now up to the reader. Do share your practices with CAST & CONVERT on this blog. Also, do mention the reasons why you practice a particular rule of thumb, if possible.

Be courteous. Drive responsibly.