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.

SQL Server – Storage requirements – CHAR v/s VARCHAR – choose the correct data-type


I work with academia frequently, and therefore, get a chance to interact with students and experience the issues they face first hand. I recently had a very interesting experience during one of these visits. I will try to present the experience as a story.

The Problem

One of the students had developed a system which involved some database interaction. As I was reviewing the system, I noticed an issue with the table design. The design that the student had come up with was something like the following:

USE tempdb
GO
--Create the table, with fixed length columns
CREATE TABLE CityMaster (CityId      INT IDENTITY (1,1),
                         CityName    CHAR(50),
                         StateName   CHAR(50),
                         CountryName CHAR(50)
                        )
GO

(The design above is not exactly what he had, but you get the general idea.)

The problem that I had was with his choice of data types. He had chosen a fixed-length data type – CHAR.

I explained that CHAR, being a fixed-length data type, pads a string with trailing blanks when the data is stored to achieve the fixed-length. Variable length data types (e.g. VARCHAR), on the other hand, do not pad trailing blanks, and therefore, have a variable space requirement.

To explain this with an example, the simplest thing for me to do was to insert some test values in his database. Once the test data was ready, I ran the following query, which uses the DATALENGTH() and LEN() functions. For those who came in late,

  • DATALENGTH = Returns the number of bytes used to represent an expression
    • This can be used to estimate the storage space that SQL Server has taken up for an expression
  • LEN = Returns the number of characters of the specified string expression, excluding trailing blanks
USE tempdb
GO                        
--Insert test data
INSERT INTO CityMaster (CityName, StateName, CountryName)
VALUES ('Ahmedabad','Gujarat',    'India'),
       ('Mumbai'   ,'Maharashtra','India'),
       ('New Delhi','Delhi'      ,'India'),
       ('Bengaluru','Karnataka'  ,'India')
GO

USE tempdb
GO
--View the length and the data length for the data in the table
SELECT CityMaster.CityId,
       CityMaster.CityName,    LEN(CityMaster.CityName)    AS CityNameLength,    DATALENGTH(CityMaster.CityName)  AS CityNameDataLength,
       CityMaster.StateName,   LEN(CityMaster.StateName)   AS StateNameLength,   DATALENGTH(CityMaster.StateName) AS StateNameDataLength,
       CityMaster.CountryName, LEN(CityMaster.CountryName) AS CountryNameLength, DATALENGTH(CityMaster.CountryName) AS CountryNameDataLength
FROM CityMaster
GO

image

Using the output of the above query, it became easy for me to explain that because CHAR consumes the full 50 characters, the SQL Server consumes a space of 50 + 50 + 50 = 150 bytes irrespective of the amount of data actually being requested for storage.

The solution

As a solution, I recreated the table with the following design:

USE tempdb
GO
--Create the table, with variable length columns
CREATE TABLE CityMaster_v2 (CityId      INT IDENTITY (1,1),
                            CityName    VARCHAR(50),
                            StateName   VARCHAR(50),
                            CountryName VARCHAR(50)
                           )
GO

Again, I inserted the test data and ran the length determination queries.

USE tempdb
GO                          
--Insert test data
INSERT INTO CityMaster_v2 (CityName, StateName, CountryName)
VALUES ('Ahmedabad','Gujarat',    'India'),
       ('Mumbai'   ,'Maharashtra','India'),
       ('New Delhi','Delhi'      ,'India'),
       ('Bengaluru','Karnataka'  ,'India')
GO

USE tempdb
GO
--View the length and the data length for the data in the table
SELECT CityMaster_v2.CityId,
       CityMaster_v2.CityName,    LEN(CityMaster_v2.CityName)    AS CityNameLength,    DATALENGTH(CityMaster_v2.CityName)  AS CityNameDataLength,
       CityMaster_v2.StateName,   LEN(CityMaster_v2.StateName)   AS StateNameLength,   DATALENGTH(CityMaster_v2.StateName) AS StateNameDataLength,
       CityMaster_v2.CountryName, LEN(CityMaster_v2.CountryName) AS CountryNameLength, DATALENGTH(CityMaster_v2.CountryName) AS CountryNameDataLength
FROM CityMaster_v2
GO

The results spoke for themselves, and he quickly grasped the concept that I was trying to put forward, i.e. variable length datatypes have varying storage requirements, making them more efficient from a storage perspective.

image

ALTER TABLE…ALTER COLUMN will not help in releasing space from fixed-length data-types

Because the concept was clear, he proceeded with converting his existing table designs to use variable-length data types using the ALTER TABLE…ALTER COLUMN statement.

USE tempdb
GO
--Changing CHAR to VARCHAR will NOT release space back once the allocations have been done
ALTER TABLE CityMaster
    ALTER COLUMN CityName VARCHAR(50)

ALTER TABLE CityMaster
    ALTER COLUMN StateName VARCHAR(50)
    
ALTER TABLE CityMaster
    ALTER COLUMN CountryName VARCHAR(50)
GO

However, he found that the ALTER TABLE…ALTER COLUMN statement did not make a difference to the storage requirements.

image

The reason, I explained, was that once SQL Server has added trailing spaces, it is no longer able to distinguish between an intentionally padded and an automatically padded version of the same string (e.g. ‘BeyondRelational.com ‘ (3 spaces) from ‘BeyondRelational.com’ (no spaces)) and therefore, SQL Server will not be able to release the space allocated to the trailing spaces back.

The only option for him was to drop-and-recreate the tables and then re-insert all his test data.

Now that we were all set with the concept, I pointed him to one of Vinod Kumar’s (blog|twitter) posts: http://blogs.extremeexperts.com/2003/10/10/using-varchars/

Conclusion

There are not one, but 2 very good reasons why I shared this experience with the community.

  1. The prime reason being that this post might be helpful to students trying to understand and explore databases, and inculcate in them a habit of choosing the correct data-types
  2. I have seen production code with such issues, such as the incorrect choice of data-types. For us in the industry, this is a capital mistake that should not be made, ever

Reference

Until we meet next time,

Be courteous. Drive responsibly.

Subscribe to my posts via E-mail: Subscribe here | Read my posts via your favourite RSS reader: Click Here! | Tweet to @nakulv_sql

News – In the new year, stay in touch with Nakul Vachhrajani on Google+, Facebook & Twitter!


As 2011 comes to a close, I have expanded my participation in Social Media on the web. You can now follow me on the following:

Twitter:

Google+: +Nakul

Facebook: https://www.facebook.com/nakulvachhrajani 

For other options on how to stay in touch with me, please visit my post: SQL Server – How to stay in touch with me – Blog, RSS Feed and E-mail

Have a Very Happy New Year 2012!!

Until we meet next time,

Be courteous. Drive responsibly.

Subscribe to my posts via E-mail: Subscribe here | Read my posts via your favourite RSS reader: Click Here!

SQL Server – T-SQL – Different ways to generate a comma-separated string from a table


Recently, someone in the team faced a fairly common requirement – to generate a comma-separated string from values stored in a table. This being the last post of the year, I thought of sharing the 2 most-commonly used methods I know of implementing this requirement.

Do you know any other? If you share it on this post, I will publish it with due credit on my blog.

----------------------------------------------------
--WARNING: THIS SCRIPT IS PROVIDED AS-IS AND WITHOUT
--         WARRANTY.
--         FOR DEMONSTRATION PURPOSES ONLY       
----------------------------------------------------
--Step 01: Generate Temp table to store source data
DECLARE  @NamesTable TABLE (Id INT,
                            Name NVARCHAR(50))

--Step 02: Generate test data
INSERT INTO @NamesTable VALUES (1,'A'),
                               (2,'D'),
                               (2,'C'),
                               (3,'E'),
                               (3,'H'),
                               (3,'G')

--Option 01: My favourite
DECLARE @listStr VARCHAR(MAX) --DO NOT initialize this one!

SELECT @listStr = COALESCE(@listStr + ',' ,'') + nt.Name
FROM @NamesTable nt

SELECT @listStr

--Option 02: Using XML
; WITH CommaSeparatedXML (CommaSeparatedXML)
AS (SELECT CAST((SELECT (',' + nt.Name)
                 FROM @NamesTable nt
                 FOR XML PATH('')) AS NVARCHAR(MAX))
   )
SELECT SUBSTRING(CommaSeparatedXML, 2, LEN(CommaSeparatedXML))
FROM CommaSeparatedXML
GO

Until we meet next time,

Be courteous. Drive responsibly.

News – MCTS Exam – 70-432 – Microsoft SQL Server 2008: Implementation & Maintenance passed!


Ever since I started working with Microsoft SQL Server, I have heard and read a lot about the coveted “Microsoft Certified Professional” status. I had yet to get my first certification even after working with SQL Server for the last 7 years. As the year 2011 dawned, I had made a resolution that no matter what happens I need to pass the entry level MCTS examination 70-432.

As 2011 comes to a close, I am happy to announce that last week, I achieved the MCTS certification!

Today, I will try to summarize my learning and examination experience with all.

Preparations

I have always enjoyed the preparation phase of any examination – the simple reason being that I never look at things from an examination perspective. I always look at the preparation as an opportunity to learn new things.

Microsoft Learning has identified a great set of preparation materials on the examination’s home page – http://www.microsoft.com/learning/en/us/exam.aspx?id=70-432. Because of the work schedule, the self-paced training kit was the best option for me, and therefore, I bought a copy of the book – “MCTS Self-Paced Training Kit (Exam 70-432): Microsoft® SQL Server® 2008 – Implementation and Maintenance” by Mike Hotek (Microsoft | Amazon | Flipkart).

TIP: For those in India, make sure you get the “Eastern Economy Edition” when ordering it online.

As I mentioned, I have been working with SQL Server for quite some time now, and therefore, did not go through the complete prescribed reading syllabus. Apart from backup-restores, I have not had real-time, practical exposure on Disaster Recovery plans & techniques. So, as soon as I got the book, I started reading up on the areas to which I only had a cursory exposure.

TIP: Online resources are one of the best resources that can help in the preparations. Apart from the online resources listed on the examination’s home page, make sure you subscribe to blogs and newsletters of stalwarts like Pinal Dave (SQLAuthority.com), Vinod Kumar (Extreme Experts), Jacob Sebastian (BeyondRelational.com), and SQLServerCentral.com. Even outside of the preparations , these are some of the blogs & newsletters I read daily and find them to be enriched with knowledge & information.

That’s pretty much it. The end of the year was fast approaching, and after 6 months of slowly reading selected sections of the book, I decided to give the examinations a go!

Examinations

The examinations for Microsoft certifications are conducted through a network of authorized test centers operated by Prometric. One can go to their web-site, search for a convenient test center location, pay online and schedule an examination on a date of their choice. The online registration process is simple and smooth.

I reached the examination centre about 45 minutes before the scheduled time (they require you to come at least 30 minutes before time), and the check-in process was immediately started. They already knew I was coming, and I was given a couple of forms and non-disclosure agreements to sign on. I was required to produce 2 forms of photographic identifications (passport & driver’s license are the most common) and all pockets were to be emptied. All personal belongings need to go into a standard locker, and therefore, they recommend that one should not bring backpacks or any other oversized item to the test center.

After the sign-in process, I was given a set of 2 erasable boards, marker pens and was explained the examination process by a very kind and patient test administrator. I was then assigned a cubicle where once again a few terms & conditions were to be accepted. Once done, the test began. Personally, I found no reason to hurry – I was given a time of more than 2 hours to complete the examination. On an average, I had about 3-4 minutes per question and so, I immediately relaxed – I had time to think the questions through.

I finished the examination well within the prescribed time, and was immediately provided an embossed score sheet by the administrator certifying that I had passed the examination! After that, it was time for some feedback forms and that’s it – it was time to go!

The next day, I received an E-mail from Microsoft giving me my very own MCP number and access to the MCP website from where I could view my certificates, download them and even order a print copy if required.

I was officially, MCTS Certified! A new-year resolution was completed by me for the first time!

My Recommendations

I found the examination completely practical oriented. If you are going to appear for the exam after only reading through the theory, please do not do so. The secret to clearing the examination is – practice, practice & practice. The questions require you to have faced complex, practical issues in SQL Server implementation, maintenance & administration.

My recommendations would be to read through the theory, and reinforce it with practical experience without fail. The questions and practice exercises within the book are great way to get started on the practical side of the preparation. In addition, go through the content and practice tests in the CD/DVD accompanying the book – the practice tests on the CD/DVD simulate the test environment to a real world level and I strongly recommend that you pass at least 3 consecutive times on the simulated tests before you decide to appear for the exams.

I would recommend that anybody who foresees themselves working on Microsoft technologies should prepare and get themselves Microsoft certifications. The certification has tremendous value. For me, the next step is another MCTS certification (70-433: SQL Server 2008: Database Development), but that would be next year. I am exhausted for now!

Until we meet next time,

Be courteous. Drive responsibly.

Subscribe to my posts via E-mail: Subscribe here | Read my posts via your favourite RSS reader: Click Here!

MCTS(rgb)_1269