Posts Tagged ‘mssql’

What happens in EXEC, stays in EXEC. Lifespan of a MSSQL table variable

One of my all time favorite features of MSSQL 2005+ is being able to create table variables on the fly from SELECT statements. This isn’t a lesson in what table variables are, but here is an easy sample in case this is a new concept.

Running this query

SELECT * INTO #myTableVar FROM YourTable

Gives you a new table variable named myTableVar. Table variables are scoped to the active connection, so running this will work.

// make table var
SELECT * INTO #myTableVar FROM YourTable
// show me the data
SELECT * FROM #myTableVar
// you can drop it if you wish
DROP TABLE #myTableVar

However, let’s say you have an aspx page or a sproc that runs this query.

SELECT * INTO #myTableVar FROM YourTable

You can not access myTableVar in a separate connection to the database because as soon as the first query’s connection closes, myTableVar gets dropped.   Here are a few other scenarios that also demonstrate the scoping of a table variable.

-- FAILS
EXEC ('SELECT * INTO #tmp FROM MyTable;');
-- #tmp does not exist
SELECT * FROM #tmp
#tmp only exists inside of EXEC

Table variable #tmp lives inside of EXEC

Here we see that the table variable #tmp only lives for the life of the statement inside of EXEC. The second SELECT * calls is outside of the EXEC statement.

-- #tmp2 works inside of EXEC statement
EXEC ('SELECT * INTO #tmp2 FROM MyTable; SELECT * FROM #tmp2');
table variables in EXEC live in EXEC

What happens in EXEC, stays in EXEC

Here #tmp2 works because it’s being used inside of the EXEC statement. This is worth knowing if you work with dynamic sql statements and exec.

-- works!
SELECT * INTO #tmp FROM MyTable;
-- #tmp exists
SELECT * FROM #tmp
typical sample of using mssql table variable

typical sample of using mssql table variable

This is a typical example that you may use inside a sproc, trigger, script, etc. Both sql calls live in the same space, so #tmp exists.

Select random value from a range of values

Earlier I blogged about creating random numbers using tsql functions.  Here are two techniques for selecting a random value from a pre-defined range of values in a tsql script.  The first technique uses a table variable ( MSSQL 2000 + ), and the second uses a Common Table Expression or CTE ( MSSQL 2005+ ).

Select a random value using a table variable


-- var to hold random integer
declare @field_val int

-- create table var to hold value range [ 0, 512, 1024, 2048, 4096 ]
-- inserting the first value sets the structure for the table variable
SELECT 0 AS 'num'
INTO #temp

-- insert data into table var
INSERT INTO #temp VALUES ( 512 )
INSERT INTO #temp VALUES ( 1024 )
INSERT INTO #temp VALUES ( 2048 )
INSERT INTO #temp VALUES ( 4096 )

-- assign random value
SELECT TOP 1 @field_val = num FROM #temp ORDER BY NEWID()

-- show value
SELECT @field_val

-- drop the table variable
DROP TABLE #temp

Select a random value using a CTE

-- define our data table
WITH data( car )
AS
(
	-- UNION together our range of values
	SELECT 'audi' AS 'car'
	UNION
	SELECT 'bmw' AS 'car'
	UNION
	SELECT 'infinity' AS 'car'
	UNION
	SELECT 'lexus' AS 'car'
	UNION
	SELECT 'porsche' AS 'car'
)
-- select a random value
SELECT TOP 1 car FROM data
ORDER BY NEWID()

Both of these techniques can be used with numbers or text. Just be sure to mind your quotes, and variable datatypes.  Being able to pick a random value in data generation scripts has proven very useful.  I hope this helps somebody else out as well.

Store your SQL database in the same location as live

I do a lot of moving of databases between development and production servers.  If I’m lucky, the production server I’m working with gives me access to DTS services, or even the Database publishing wizard.  More often than not however, the SQLServer I’m pushing to is locked down in a way that I am required to Remote Desktop into the server, then update the database via restore.

So here’s the tip.  When you’re only means of updating a remote SQLServer database is by physically restoring the database, do your best to mirror the product server’s database location on your development machine.  Check out this screenshot, and you’ll see what I mean

MSSQL : Restore Files and Filegroups

MSSQL : Restore Files and Filegroups

The background of this image shows that my production server houses all of it’s databases at the path C:\DB\database.mdf.

The lower right box shows where I keep my databases on my development server. Since I do not store any vital data on my C: drive, I’ve changed the path to D:\DB.

While this isn’t an exact path match, this trick saves me a little bit of time and frustration when restoring a database remotely.  Especially when I have to do it more than a handful of times in the same day.

It’s assumed you know how to the following  :

  • Back up a SQLServer database
  • Copy the BAK file to a remote server
  • Connect remotely to your SQLServer
  • Restore a Database file from a file ( BAK file )

I built a calendar in a tSQL SPROC

Here’s a blast from the past that I recently found in my archives. It’s a novelty stored procedure I wrote during my MS SQL 2000 DBA days.
Back when I wrote this sproc, I was really big into writing calendar applications. I have written some sort of calendar application in
almost every language I know, so writing one in tSql made sense to me.

While I never used this sproc in an application, or had any practical use for it, I still think it’s cool. It’s primarily an excercise using
tSql’s date functions, and my all time favorite feature of MS SQL 2000+, table variables.

If you use MSSQL 2000 or higher and don’t use table variables, I highly recommend looking into these. In a nutshell, it’s a type of tSql variable
that is a table. You can select, insert, update, and delete the rows in this variable just like it’s a real table. The lifespan of a table variable
is the length of your connection to your db. So if you have a table var #myTable in sprocA, as soon as sprocA completes execution, #myTable is gone.
SprocB can’t access #myTable unless is specifically creates a new table var by this name.

So I wrote an article about this sproc for a database site years ago and I haven’t been able to find it again. This was web1.0 days, so I’m sure the site
is gone by now. The good thing is I still have the sproc, and now you can to.

So here’s the info. The sproc efCalendar accepts a month number and year number, and spits out two recordsets.

  1. Month, Year
  2. Calendar view of that month

Recordset 1 is two columns, month name, and year.

Recordset 2 is a calendar view of the specified month. There is a column for each weekday, starting with Sunday and ending with Saturday.
Then there is a row for each week in the specified month.

Here is what the results look like when run in Query Analyzer.

tSQL calendar sproc

tSQL calendar sproc

Download the efCalendar sproc here.