SQL Server CTE ~ Hooray for Common Table Expressions

What is a SQL Server CTE?

CTE stands for Common Table Expression.

A CTE is basically a subquery. So why is it special? This is why they are good:

  • Separate a subquery from the body of the main query.
  • Cleaner code – CTEs enable you to separate your logically congruent code segments.
  • Can be used for improving the execution plan of your query.
  • Can be used for recursive, hierarchical queries.

When aren’t they good? Almost never. Basically, if you don’t need a subquery don’t use a CTE. Also don’t bother using a CTE when you are performing a query with resources outside of SQL Server, there are negative performance issues in SQL Server 2005, but is fixed in SQL Server 2008. Here is everything you will need to know about CTEs.

CTE Basics

Books Online

Recursive CTE

Advertisements

Canceled By User ~ Debugging CLR Objects in SQL Server and Visual Studio

So you enabled CLR debugging on your TEST SQL Server (don’t ever do this on production!)

You are trying to debug but you get a message “Canceled by user” in the Output window in Visual Studio. Here is the answer, you have to enable the ports on BOTH your workstation and the SQL Server machine.

Add the following inbound exceptions to both machines:
TCP: 135
UDP: 400,500

On your WORKSTATION:
Add the program devenv.exe to your exceptions list in your firewall.

This will worked for me. Let me know if you had a different solution.

SQL Server ~ Creating a CLR User Defined Function Error 181

Cannot use the OUTPUT option in DECLARE or CREATE FUNCTION statement

So this may or may not trip you up. If you are like me, you want thing to run fast. One of those ways is to pass a reference to a variable as opposed to passing a copy of the value to the function. In .Net this works well, however SQL Server translates the byref to it’s equivalent which is OUTPUT option. Simply bite the bullet and change the function to have all of your parameters to byval and you are good to go.

Hopefully I saved you some time and agrivation.

SQL Server Null Values ~ Into the Void (pun intended)

Null values can get some people rather confused writing queries. I hope I can shed some light on that. By default, SQL Server uses ANSI Nulls. This behavior says that any value compared to null is not equal to null.

if ‘a’=null
print ‘true’
else
print ‘false’

Returns false

Here is something interesting and if you are slightly devious, what about null compared to null?

if null=null
print ‘true’
else
print ‘false’

Returns false

if null is null
print ‘true’
else
print ‘false’

Returns true

Lets turn off ANSI_Null:

SET ANSI_NULL OFF;

if null=null
print ‘true’
else
print ‘false’ 

RETURNS TRUE!!!!!

if null is null
print ‘true’
else
print ‘false’ 

Returns true

According to MSDN, if you are trying to search for or compare null values using “is null” is recommended and will return consistent results.

If you are trying to create a query and want to include nulls in the result set you have to do it explicitly like this:
WHERE name = ‘Smith’ OR name IS NULL
Or if you want to exclude nulls:
WHEREname = ‘Smith’ OR name IS NOT NULL

If you want to be tricky you could do something like:

WHERE ISNULL (name,) = ‘Smith’

In London, they have signs that say “Mind the gap”, I say MIND THE NULLS!

One handy function to deal with nulls is Coalesce, which I describe here.

Troubleshooting MSDTC: The transaction manager has disabled its support for remote/network transactions

This guy has a great article that I have re-blog: http://wp.me/p1qkE8-2I

Drop All Tables in a Database

So I recently had to delete all tables in a database based on schema name. Here is the solution I came up with:

DECLARE @tblName VARCHAR(200) ;

 

DECLARE tbl CURSOR

FOR

SELECT SCHEMA_NAME(schema_id) + ‘.’ + name AS tableName

FROM sys.tables

WHERE schema_id IN (SCHEMA_ID(‘admdb’), SCHEMA_ID(<Your Schema Here>), SCHEMA_ID(<Your Schema Here>)) ;

 

OPEN tbl ;

 

FETCH NEXT FROM tbl INTO @tblName ;

WHILE @@FETCH_STATUS=0

BEGIN

EXEC(‘DROP TABLE ‘ + @tblName) ;

 

FETCH NEXT FROM tbl INTO @tblName ;

END

 

CLOSE tbl ;

DEALLOCATE tbl ;

 

A couple things worth mentioning is that I set the table name to 200 character varchar. Of course this script can do some damage, please, please, please make sure you don’t need anything in any of the tables before running this!

By default, drop table does not accept a variable but if you turn it into a dynamic query (wrapping it in an execute function) works perfectly.

SQL Server DAC (Dedicated Administrator Connection)

SQL Server DAC (Dedicated Administrator Connection)

Have you ever had a query go rogue? CPU at pegged at 100%? This will help!

Note: This is only for SQL Server 2005 and later…

There is some groundwork to do.

Setting up the DAC

Run these statements as an administrator:

sp_configure 'remote admin connections',1
GO
RECONFIGURE
GO

This will enable the ability to connect to the server.

Using DAC When IT Matters!

You can do two things use sqlcmd to connect to the SQL Server or a query window (not the Object Browser). The trick is before the name of the server prefix the name of the server with admin:.

Example:

admin:servername

A note of interest, you are limited by what you can do in this mode. Nothing that needs to store temporary tables and things like that. You can even use this if you do something terrible like corrupt the master or tempdb databases.

I hope you never need this!