Compress All Tables in Database

PROBLEM: I need to find out all the tables in a database that are not using data compression.

SOLUTION: Here is the T-SQL code to list all tables in a database that are not compressed.

SELECT DISTINCT D.name [SchemaName]
     , C.name [TableName]
     , A.data_compression_desc
  FROM sys.objects C WITH (NOLOCK)
 INNER JOIN sys.partitions A WITH (NOLOCK) ON C.[object_id] = A.[object_id]
 INNER JOIN sys.schemas D WITH (NOLOCK) ON C.[schema_id] = D.[schema_id]
 WHERE A.data_compression = 0
   AND C.[type] = 'U'
   AND SCHEMA_NAME(C.schema_id) <> 'SYS'
 ORDER BY D.name, C.name
GO

The script below will take care of generating the T-SQL commands necessary to compress all tables that are not already compressed on a database. This script will handle heap tables, clustered indexes and non-clustered indexes. Make sure to output the result to text (CTRL+T) so you can copy, paste and execute in a new window.

DECLARE @TSQL nvarchar(1000)
      , @schema varchar(128)
      , @tablename varchar(128)
      , @type tinyint
      , @indexname varchar(128)

DECLARE C CURSOR
    FOR SELECT DISTINCT D.name [SchemaName]
             , C.name [TableName]
             , I.[name] [IndexName]
             , I.[type]
          FROM sys.objects C WITH (NOLOCK)
         INNER JOIN sys.partitions A WITH (NOLOCK) ON C.[object_id] = A.[object_id]
         INNER JOIN sys.schemas D WITH (NOLOCK) ON C.[schema_id] = D.[schema_id]
         INNER JOIN sys.database_principals E WITH (NOLOCK) ON D.principal_id = E.principal_id
         INNER JOIN sys.indexes I WITH (NOLOCK) ON A.index_id = I.index_id
           AND A.object_id = I.object_id
         WHERE A.data_compression = 0
           AND C.[type] = 'U'
           AND C.[name] NOT LIKE 'MS%'
           AND I.object_id > 1000
           AND SCHEMA_NAME(C.schema_id) <> 'SYS'
         ORDER BY D.name, C.name

   OPEN C
  FETCH NEXT
   FROM C
   INTO @schema, @tablename, @indexname, @type

  WHILE @@FETCH_STATUS = 0
        BEGIN
        SELECT @TSQL = CASE @type
		               WHEN 1 THEN N'ALTER TABLE ['+ @schema +'].['+ @tablename +'] REBUILD WITH (DATA_COMPRESSION = PAGE)' + CHAR(10) +'GO'+ CHAR(10)
                       WHEN 0 THEN N'ALTER TABLE ['+ @schema +'].['+ @tablename +'] REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = PAGE)' + CHAR(10) +'GO'+ CHAR(10)
                       ELSE N'ALTER INDEX ['+ @indexname +'] ON ['+ @schema +'].['+ @tablename +'] REBUILD WITH (DATA_COMPRESSION = PAGE)' + CHAR(10) +'GO'+ CHAR(10) END
 
        SELECT @TSQL

        FETCH NEXT FROM C INTO @schema, @tablename, @indexname, @type
    END
  CLOSE C
DEALLOCATE C
GO

DB_RecentFileGrowth

IF (SELECT CONVERT(int,value_in_use) FROM sys.configurations WHERE [name] = ‘default trace enabled’ ) = 1
BEGIN

DECLARE @curr_tracefilename varchar(500)
, @base_tracefilename varchar(500)
, @indx int;

SELECT @curr_tracefilename = [path] FROM sys.traces where is_default = 1 ;

SET @curr_tracefilename = REVERSE(@curr_tracefilename);

SELECT @indx = PATINDEX(‘%\%’, @curr_tracefilename) ;

SET @curr_tracefilename = REVERSE(@curr_tracefilename) ;
SET @base_tracefilename = LEFT( @curr_tracefilename,LEN(@curr_tracefilename) – @indx) + ‘\log.trc’ ;

SELECT (DENSE_RANK() OVER(ORDER BY StartTime DESC))%2 AS [l1] , CONVERT(int, EventClass) [EventClass] , DatabaseName
, [Filename] , StartTime
, EndTime
, (IntegerData*8.0/1024) [ChangeInSize] FROM ::fn_trace_gettable( @base_tracefilename, default )
WHERE EventClass >= 92
AND EventClass <= 95
ORDER BY StartTime DESC;
END
GO

Setting SQL Alias with PowerShell

PROBLEM: The SQL Servers instances I manage have long cryptic names that are almost impossible to memorize and too many keystrokes to type; besides, I rather use my memory for other things. How can I set up aliases for all the SQL instances I manage in a quick an easy manner?

SOLUTION: The configuration of SQL aliases is saved in the registry under two locations. This first one is for 32bit clients HKEY_LOCAL_MACHINE\Software\Microsoft\MSSQLServer\Client\ConnectTo
And this second one is for 64bit clients HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\MSSQLServer\Client\ConnectTo

PowerShell to the rescue!  I wrote the Set-SQLAlias function that will take the SQL instance name, port number and alias I want to create. It will use this information to add an entry on the registry or modify an existing alias. I have added this function to my profile so it is always available. THIS FUNCTION MUST BE EXECUTED IN A POWERSHELL SESSION RUNNING UNDER ADMINSTRATOR PRIVILEGES”

Function Set-SqlAlias {
	[Cmdletbinding()] 
	param ( [parameter(Mandatory=$true)] [string] $SqlInstanceName,
            [parameter(Mandatory=$true)] [string] $Alias,
			[parameter(Mandatory=$true)] [string] $Port,
			[parameter(Mandatory=$false)] $OverWrite = 0
          ) 

	BEGIN {
		$x64 = "HKLM:SOFTWARE\Wow6432Node\Microsoft\MSSQLServer\Client\ConnectTo"

		if (!(Test-Path "$x64")) {
			New-Item -Path "$x64" -Name "ConnectTo" 
		}
	}

	PROCESS {
		if ($OverWrite -ne 0) {
			Get-Item -path "$x64"|Remove-ItemProperty -Name "$Alias"|Out-Null 
		} 
		
		if (!(Get-Item -Path "$x64").GetValue("$Alias")) {
			New-ItemProperty -Path "$x64" -Name "$Alias" `
-PropertyType String `
-Value $("DBMSSOCN,{0},{1}" -f "$SqlInstanceName", $Port) `
|Out-Null
		} 
	} 
}

Thanks to my friend Rodney Starcher for helping me out with the PowerShell script.

Cómo Cambiar el Propietario de Una Base de Datos

PROBLEMA: Tengo base de datos donde el propietario no es “sa”, cómo puedo cambiar el propietario de varias bases de datos a “sa” de una forma dinámica.

SOLUCION: Yo utilizo el cmdlet Get-SqlDatabase del módulo SqlServer para capturar las bases de datos de una instancia de SQL Server. Entonces hago una búsqueda en el objeto generado por el cmdlet Get-SqlDatabase para encontrar las bases de datos donde la propiedad “.owner” no es “sa”. De ahi, ejecuto el método “.SetOwner” y el “.Alter” por cada una de las bases de datos encontradas para asignar el nuevo propietario “sa”.

Get-SqlDatabase -ServerInstance 'TUIRA' `
| Where {$_.Owner -ne "sa"} `
| foreach {$_.SetOwner("sa"); $_.Alter()}

En Inglés

Change Database Ownership

PROBLEM: Database ownership is set to the user who created or restored the database and I want to change it to “SA”.

SOLUTION: I use the Get-SqlDatabase cmdlet from SqlServer module to capture the list of databases from the SQL instance. I then pipe and search for databases where the “.owner” property is not “sa”. Then pipe the database object to change the “.owner” property to “sa” by invoking the methods “.SetOwner” and “.Alter”.

Get-SqlDatabase -ServerInstance "TUIRA" `
| WHERE {$_.owner -ne 'sa'} `
| foreach {$_.SetOwner('sa'); $_.Alter()}

In Spanish

Cars and Coffee, Dallas – July 2014

 Dodge SRT V10 Viper Gen 4

Cars and Coffee, July 2014

This Saturday I went to the Cars and Coffee event which happens the first Saturday of every month where thousands of car enthusiasts gather at the Classic BMW of Plano to see some of the most exotic vehicles in north Texas.  You are sure to find classic vehicles from the ones that are being eaten up by rust to the ones restored with such craftsmanship that is a joy to see.  And then you have the sports vehicles, and concepts with each having a little extra which makes them unique.

This was my second time to one of these events and left somewhat as frustrated as the first time but Joe save the day. If you are like me, wanting to make photographs of some of these amazing vehicles, you must get there really early -before 7am during daylight savings time.  Otherwise you will end up with walkers and their shadows in your images.  I hope that someday I hookup with  some of these vehicle owners and have a photo session of just them.

So, how did Joe save the day? Joe is a proud owner of a SRT Viper V10 Gen 4 and I had the opportunity to talk to him about his vehicle.  In this interview, Joe talks about how he became the owner, the hard decision of selling his previous ride and things he likes about his SRT V10.

Sal: So, when did you purchase your Viper?
Joe: I bought it a couple of years ago. Ugh, literally, two years ago.

Sal: Did you purchase it used or brand new?  My lack of knowledge about this car showed up immediately with this question for obvious reasons.
Joe: I bout it from a guy that had it on the east coast and he had it since new.  He showed it, and baby it, he was a Viper club president, fanatic.

Sal: So, did  you fly all the way to the east coast or drove all the way back and forth to bring it over to Texas?
Joe: I looked for a long time for the right one. In fact, I’ve wanted one for about 7 years.  But I had a Vette that was really good, and it was impossible to let the Vette go -it was such a great car. And finally I decided to make that leap and so in the end I did. And I came across this car which was unbelievable low mileage and in show condition. I talked to the guy in length on the phone, flew over there to check it out and we did a deal and then I had it shipped.  I wasn’t going to drive it from the east coast.  This isn’t the kind of car you want to drive across country, it will beat you up.

Sal: What are the things you like about your car?
Joe: I love the sexy lines, first and foremost. I love the muscle heritage on it.  I love the 8.4 liter V10. It is a basic muscle car. It is almost like a dinosaur by today’s standards. You know, it’s got its 600 horse power but it does it without supercharger or turbo charger, it is just brute force.

I will tell you one thing that is interesting about this car that I did not see coming. I loved my Vette and it was a well all around car, and then I bought this car.  And the first thing I noticed, is like a Vette on steroids, oh yeah! Night and day difference from the moment you turn on the engine, to hitting the gas, it is all that. And then you begin to realize this car is very narrow focus and then… The Vette is a great street car that you can take on the track, the viper is really a track car that you can put on the street -that is the difference.  I mean, when you ride this thing, the suspension will beat you up, really, you could make it your daily ride but you will get abuse a little bit.  The Vette is a fantastic daily driver, so those are the differences I noticed right off the bat.

SRT Viper V10 GEN 4Sal: What about under the hood, is there anything you like?
Joe: Signed by the Viper development team, the guy that made the engine, the guy that was at the head of the program, the CEO of the Viper program Ralph Gilles.  The guy who used to have this car was dabbling with all these people and will get photos.

Another interesting thing is the color viper violet metallic fair coat which was introduced at the end of the production year (2008 – 2009) so there were very few violet cars that came out and that was the only year that it was produced.

 

Table Variables 101

Table variables fall in one of those areas where lack of knowledge and understanding can get you in trouble. I’m leaving the creative part of getting in trouble up to you and here, I will show you a few things I didn’t know about table variables.

Table variables exist in tempdb regardless of their size. I have found in several places on the web people making statements such as temporary tables exist in tempdb and table variables exist in memory. Another reason why we must do our homework and conduct our own tests.

DECLARE @t TABLE (
        RequiredDate datetime NOT NULL
      , ShippedDate datetime NULL
      , CustomerID int)

 SELECT *
   FROM tempdb.sys.objects
  WHERE [type] = 'U'

INSERT INTO @t (
       RequiredDate
     , ShippedDate
     , CustomerID)
VALUES ('20120122', '20120114',4)
     , ('20120122', '20120114',1)
     , ('20120122', '20120114',5);

SELECT * 
  FROM @t;

You can use the IDENTITY column property

DECLARE @t TABLE (
        OrderID int IDENTITY(1,1)
      , RequiredDate datetime NOT NULL
      , ShippedDate datetime NULL
      , CustomerID int)

INSERT INTO @t (
       RequiredDate
     , ShippedDate
     , CustomerID)
VALUES ('20120122', '20120114',4)
     , ('20120122', '20120114',1)
     , ('20120122', '20120114',5);

SELECT *
  FROM @t;

 

You can define a primary key

DECLARE @t TABLE (
        OrderID int IDENTITY(1,1) PRIMARY KEY
      , RequiredDate datetime NOT NULL
      , ShippedDate datetime NULL
      , CustomerID int)
 
INSERT INTO @t (
       RequiredDate
     , ShippedDate
     , CustomerID)
VALUES ('20120122', '20120114',4)
     , ('20120122', '20120114',1)
     , ('20120122', '20120114',5);
 
SELECT * FROM @t;

 

You can define a clustered key other than the primary key.

DECLARE @t TABLE (
        OrderID int IDENTITY(1,1) PRIMARY KEY NONCLUSTERED
      , RequiredDate datetime NOT NULL
      , ShippedDate datetime NULL
      , CustomerID int,
 UNIQUE CLUSTERED (CustomerID, OrderID))

 

You can create a check constraint

DECLARE @t TABLE (
        OrderID int IDENTITY(1,1) PRIMARY KEY NONCLUSTERED
      , RequiredDate datetime NOT NULL
      , ShippedDate datetime NULL
      , CustomerID int,
 UNIQUE CLUSTERED (CustomerID, OrderID),
 CHECK (RequiredDate BETWEEN '20131001' AND '20131031'))

Now, just because you can do all these things with table variable you shouldn’t go and define every table variable with all these properties. You should always practice good database design.

Heard Museum, McKinney, Texas

Black-crowned Night-Heron

The Heard Nature Science & Wildlife Sanctuary is located in the city of McKinney just east of I75 and south of HWY 121. With close to 290 acres of land and 6 plus miles of meticulous well-carved trails, this sanctuary was made possible by the generosity of Miss Bessie Heard.

I had the opportunity to share this photographic experience with my good friend Brian Anderson who impressed me with his knowledge of birds. For a day, I had my own tour guide who named the different kinds of birds, their behavior, and able to recognize them by their sounds.

I brought a Canon EOS 20D with a EF 17-40mm f/4L USM, a Lumix LX3 for macro shots, but mainly used my EOS 5D Mark II with an EF 400mm f/2.8L II USM.  After 24 hours and a few painkillers, I’m still hurting from carrying around this 13lb monster.  The 400mm is the ideal focal length for this type of photography and I’m happy with the images I was able to capture with it -I will for sure be making large prints from some of them.  If I had to do it all over again I would carry the EF 400mm f/4L IS (4.5lb) or any of the EF 300mm (less than 3lb) plus a teleconverter.

2012 SQL in the City – Austin, TX

Bull Park Creek in Austin, TX

Bull Creek Park in Austin, TX

Bull Creek Park, Austin, TX

At the beginning of October 2012 I traveled to Austin, TX for the RedGate SQL in the City event. I made the trip to Austin a few days before the conference to visit with family and go to some of the parks in the area.  My first stop was at Bull Creek Park on the west side of Austin where I capture the pictures above.  From there I traveled west to the Pedernales Falls state park expecting something huge with lots of water.  It was kind of disappointing because there wasn’t much water flowing. On the flip side, I was able to walk right on the middle where normally is covered by water.

Pedernales Falls in Austin, TX

Pedernales Falls National Park in Austin, TX
Pedernales Falls State Park - fishing