Friday, June 29, 2012

Declare DataType When Creating Computed Column in SQL Server

When creating a computed column in SQL Server, be sure to use CONVERT (or CAST) to specify the datatype of the computed column, otherwise SQL Server will make the choice for you. It may not make the choice that you expected.

Here is a very simple example that shows a computed column with two possible values: 0 and 1. With no covert, SQL Server defaults to int. By using convert, we can use bit. This simple example shows that using CONVERT drops the storage requirement from 4 bytes to a single bit.

Code

SET NOCOUNT ON;USE tempdb;GOIF EXISTS (SELECT * FROM sys.tables WHERE [object_id] = OBJECT_ID('dbo.TestTable'))
  
DROP TABLE dbo.TestTable;GOCREATE TABLE dbo.TestTable (
  
TestId      INT         IDENTITY,
  
TestName    VARCHAR(25) NOT NULL,
  
LamboNoConvert AS (
      
CASE
      
WHEN TestName LIKE 'Lamborghini%'
      
THEN 1
      
ELSE 0
      
END
  
),
  
LamboConvert AS (
      
CASE
      
WHEN TestName LIKE 'Lamborghini%'
      
THEN CONVERT(bit, 1)
      
ELSE CONVERT(bit, 0)
      
END
  
)
);
GO
INSERT INTO dbo.TestTable (TestName)VALUES
  
('Lamborghini Aventador'),
   (
'McLaren F1');
SELECT * FROM dbo.TestTable;
SELECT
  
name                      AS ColumnName,
  
TYPE_NAME(system_type_id) AS TypeNameFROM sys.columnsWHERE [object_id] = OBJECT_ID('dbo.TestTable');

Results

TestId      TestName                  LamboNoConvert LamboConvert
----------- ------------------------- -------------- ------------
1           Lamborghini Aventador     1              1
2           McLaren F1                0              0

ColumnName      TypeName
--------------- --------
TestId          INT
TestName        VARCHAR
LamboNoConvert  INT
LamboConvert    BIT

Computed Column References:

Friday, June 22, 2012

List All Columns with MAX Length

To get a list of all columns in a database with "MAX" length, use this query:

SELECT
  
SCHEMA_NAME(t.[schema_id]) + '.' + t.name + '.' + c.name    AS [Sch.Tbl.Col],
  
TYPE_NAME(c.user_type_id)                                   AS [Type]FROM sys.columns    AS cJOIN sys.tables     AS t ON c.[object_id] = t.[object_id]WHERE c.max_length = -1
  
AND t.name NOT IN ('sysdiagrams')ORDER BY SCHEMA_NAME(t.[schema_id]) + '.' + t.name + '.' + c.name

Friday, June 08, 2012

SQL Server Date/Time Byte Counts

Here is a table showing how many bytes each date/time datatype requires. The script to generate the table is after the table.

TypeByteCtExample Precision
date32012-06-08
smalldatetime42012-06-08 16:27:00.000
datetime82012-06-08 16:27:12.187
time(0)316:27:12
time(1)316:27:12.2
time(2)316:27:12.19
time(3)416:27:12.188
time(4)416:27:12.1875
time(5)516:27:12.18751
time(6)516:27:12.187506
time(7)516:27:12.1875059
datetime2(0)62012-06-08 16:27:12
datetime2(1)62012-06-08 16:27:12.2
datetime2(2)62012-06-08 16:27:12.19
datetime2(3)72012-06-08 16:27:12.188
datetime2(4)72012-06-08 16:27:12.1875
datetime2(5)82012-06-08 16:27:12.18751
datetime2(6)82012-06-08 16:27:12.187506
datetime2(7)82012-06-08 16:27:12.1875059
datetimeoffset(0)82012-06-08 16:27:12 -07:00
datetimeoffset(1)82012-06-08 16:27:12.2 -07:00
datetimeoffset(2)82012-06-08 16:27:12.19 -07:00
datetimeoffset(3)92012-06-08 16:27:12.188 -07:00
datetimeoffset(4)92012-06-08 16:27:12.1875 -07:00
datetimeoffset(5)102012-06-08 16:27:12.18751 -07:00
datetimeoffset(6)102012-06-08 16:27:12.187506 -07:00
datetimeoffset(7)102012-06-08 16:27:12.1875059 -07:00

Query

SET NOCOUNT ON;DECLARE @now    datetime2(7)        = SYSDATETIME();DECLARE @nowU   datetime2(7)        = SYSUTCDATETIME();DECLARE @nowO   datetimeoffset(7)   = SYSDATETIMEOFFSET();DECLARE @d      date                = @now;DECLARE @s      smalldatetime       = @now;DECLARE @dt     DATETIME            = @now;DECLARE @t0     time(0)             = @now;DECLARE @t1     time(1)             = @now;DECLARE @t2     time(2)             = @now;DECLARE @t3     time(3)             = @now;DECLARE @t4     time(4)             = @now;DECLARE @t5     time(5)             = @now;DECLARE @t6     time(6)             = @now;DECLARE @t7     time(7)             = @now;DECLARE @dt0    datetime2(0)        = @now;DECLARE @dt1    datetime2(1)        = @now;DECLARE @dt2    datetime2(2)        = @now;DECLARE @dt3    datetime2(3)        = @now;DECLARE @dt4    datetime2(4)        = @now;DECLARE @dt5    datetime2(5)        = @now;DECLARE @dt6    datetime2(6)        = @now;DECLARE @dt7    datetime2(7)        = @now;DECLARE @dto0   datetimeoffset(0)   = @nowO;DECLARE @dto1   datetimeoffset(1)   = @nowO;DECLARE @dto2   datetimeoffset(2)   = @nowO;DECLARE @dto3   datetimeoffset(3)   = @nowO;DECLARE @dto4   datetimeoffset(4)   = @nowO;DECLARE @dto5   datetimeoffset(5)   = @nowO;DECLARE @dto6   datetimeoffset(6)   = @nowO;DECLARE @dto7   datetimeoffset(7)   = @nowO;
SELECT 'date'           AS 'Type',   DATALENGTH(@d)  AS 'ByteCt', CONVERT(VARCHAR(100), @d, 121) AS 'Example Precision'UNION ALLSELECT 'smalldatetime',             DATALENGTH(@s),                 CONVERT(VARCHAR(100), @s, 121)UNION ALLSELECT 'datetime',                  DATALENGTH(@dt),                CONVERT(VARCHAR(100), @dt, 121)UNION ALLSELECT 'time(0)',                   DATALENGTH(@t0),                CONVERT(VARCHAR(100), @t0, 121)UNION ALLSELECT 'time(1)',                   DATALENGTH(@t1),                CONVERT(VARCHAR(100), @t1, 121)UNION ALLSELECT 'time(2)',                   DATALENGTH(@t2),                CONVERT(VARCHAR(100), @t2, 121)UNION ALLSELECT 'time(3)',                   DATALENGTH(@t3),                CONVERT(VARCHAR(100), @t3, 121)UNION ALLSELECT 'time(4)',                   DATALENGTH(@t4),                CONVERT(VARCHAR(100), @t4, 121)UNION ALLSELECT 'time(5)',                   DATALENGTH(@t5),                CONVERT(VARCHAR(100), @t5, 121)UNION ALLSELECT 'time(6)',                   DATALENGTH(@t6),                CONVERT(VARCHAR(100), @t6, 121)UNION ALLSELECT 'time(7)',                   DATALENGTH(@t7),                CONVERT(VARCHAR(100), @t7, 121)UNION ALLSELECT 'datetime2(0)',              DATALENGTH(@dt0),               CONVERT(VARCHAR(100), @dt0, 121)UNION ALLSELECT 'datetime2(1)',              DATALENGTH(@dt1),               CONVERT(VARCHAR(100), @dt1, 121)UNION ALLSELECT 'datetime2(2)',              DATALENGTH(@dt2),               CONVERT(VARCHAR(100), @dt2, 121)UNION ALLSELECT 'datetime2(3)',              DATALENGTH(@dt3),               CONVERT(VARCHAR(100), @dt3, 121)UNION ALLSELECT 'datetime2(4)',              DATALENGTH(@dt4),               CONVERT(VARCHAR(100), @dt4, 121)UNION ALLSELECT 'datetime2(5)',              DATALENGTH(@dt5),               CONVERT(VARCHAR(100), @dt5, 121)UNION ALLSELECT 'datetime2(6)',              DATALENGTH(@dt6),               CONVERT(VARCHAR(100), @dt6, 121)UNION ALLSELECT 'datetime2(7)',              DATALENGTH(@dt7),               CONVERT(VARCHAR(100), @dt7, 121)UNION ALLSELECT 'datetimeoffset(0)',         DATALENGTH(@dto0),              CONVERT(VARCHAR(100), @dto0, 121)UNION ALLSELECT 'datetimeoffset(1)',         DATALENGTH(@dto1),              CONVERT(VARCHAR(100), @dto1, 121)UNION ALLSELECT 'datetimeoffset(2)',         DATALENGTH(@dto2),              CONVERT(VARCHAR(100), @dto2, 121)UNION ALLSELECT 'datetimeoffset(3)',         DATALENGTH(@dto3),              CONVERT(VARCHAR(100), @dto3, 121)UNION ALLSELECT 'datetimeoffset(4)',         DATALENGTH(@dto4),              CONVERT(VARCHAR(100), @dto4, 121)UNION ALLSELECT 'datetimeoffset(5)',         DATALENGTH(@dto5),              CONVERT(VARCHAR(100), @dto5, 121)UNION ALLSELECT 'datetimeoffset(6)',         DATALENGTH(@dto6),              CONVERT(VARCHAR(100), @dto6, 121)UNION ALLSELECT 'datetimeoffset(7)',         DATALENGTH(@dto7),              CONVERT(VARCHAR(100), @dto7, 121);

Friday, May 25, 2012

SQL Fiddle

SQL Fiddle is a new on-line tool that allows you to illustrate SQL DDL/DML. It currently defaults to SQL Server 2008 R2 but also supports 2012 and five other databases.

Check out a simple example here. This example shows the table and queries I built to answer this Stack Overflow question. When you build something in the tool, it automatically generates a unique URL for that schema/query pair.

Bravo to Jake Feasel for creating such a great tool.

Rob