get sql log file name from within a script - sql

We have a few test databases that we are throwing test indexes into and the log file gets bloated real quickly due to us dropping the contents of the table and repopulating it.
I have found, thanks to Stack Overflow, a few scripts and put them together to do what I need.
Here is the script:
USE SSSIndexes
GO
ALTER DATABASE SSSIndexes SET RECOVERY SIMPLE WITH NO_WAIT
GO
DBCC SHRINKFILE(N'SSSIndexes_Log', 1) <-- my issue is here
GO
The problem is the log file name. Is there a way to get the log file name without having to look it up manually and include it in the script to where this part is automated?
Btw, we never intend on restore this database. These are temporary indexes.
Thanks!

USE SSSIndexes
GO
ALTER DATABASE SSSIndexes SET RECOVERY SIMPLE WITH NO_WAIT
GO
DECLARE #Name NVARCHAR(50)
DECLARE cur CURSOR FOR
SELECT [name]
FROM [sys].[database_files]
where [type] = 1
OPEN cur
FETCH NEXT FROM cur INTO #Name
WHILE ##FETCH_STATUS = 0
BEGIN
DBCC SHRINKFILE(#Name, 1)
FETCH NEXT FROM cur INTO #Name
END
CLOSE cur
DEALLOCATE cur

You can use this to generate script for log file truncating of all databases on a specific server. To stick to specific databases use a filter.
SELECT
' USE [' + name + ']; GO
-- Truncate the log by changing the database recovery model to SIMPLE.
ALTER DATABASE [' + name + '] SET RECOVERY SIMPLE;
GO
-- Shrink the truncated log file to 1 MB.
DECLARE #logname varchar(128);
SELECT TOP 1 #logname=[name] FROM [' + name + '].[sys].[database_files] WHERE [type] = 1;
DBCC SHRINKFILE (#logname, 1);
GO
-- Reset the database recovery model.
ALTER DATABASE [' + name + '] SET RECOVERY FULL;
GO
' AS qry FROM master.dbo.sysdatabases
WHERE dbid > 6

WARNING!!!: YOU SHOULD ONLY DO THIS ON TEST DB SERVERS. Production DBs typically WANT to have FULL recovery mode. Test DBs you usually don't care.
Expanding on Abdul's answer (I had trouble getting it to show in new lines) and Dis' answers this finds the first db that has recovery FULL, sets it to simple and shrinks it... just keep clicking execute until it returns null
declare #dbname nvarchar(50)
declare #logfilename nvarchar(100)
select top(1) #dbname = name from sys.databases where recovery_model_desc <> 'SIMPLE' AND name <> 'tempdb'
declare #shrinkdb nvarchar(500)
set #shrinkdb = 'USE master
ALTER DATABASE [' + #dbname + '] SET RECOVERY SIMPLE
'
select #shrinkdb
execute sp_executesql #shrinkdb
set #shrinkdb = 'USE [' + #dbname + ']
DECLARE #Name NVARCHAR(50)
DECLARE cur CURSOR FOR
SELECT [name]
FROM [sys].[database_files]
where [type] = 1
OPEN cur
FETCH NEXT FROM cur INTO #Name
WHILE ##FETCH_STATUS = 0
BEGIN
DBCC SHRINKFILE(#Name, 1)
FETCH NEXT FROM cur INTO #Name
END
CLOSE cur
DEALLOCATE cur
'
select #shrinkdb
execute sp_executesql #shrinkdb

Related

Can I use a drop statement to delete specific principals from database after completing a restore from Production in SQL Server?

I have task to automate the process of taking a copy of a specific production environment and using the .bak file to restore a different environment (TEST or DEV) so that they don't end up out of sync. I understand this isn't exactly best practice, but it's the best solution right now for the problem we're addressing.
I obviously don't want to keep the principals/roles/permissions that my Prod environment has in my Test environment, and so I am looking for a way to delete the principals and then put the original test ones back.
I found Kenneth Fisher's example here. However, I'm wondering if that solution is a little over engineered for my purposes.
Is there a reason I shouldn't just use a script like below to delete exactly which principals I need to from the restored test file and then use Mr. Fisher's script to put the old principals back?
DECLARE #sql AS NVARCHAR(500)
DECLARE #name sysname
DECLARE cursor_name CURSOR FAST_FORWARD READ_ONLY FOR
SELECT name
FROM sys.database_principals
WHERE [type] in (N'U',N'S',N'G')
AND name NOT IN ('dbo', 'guest', 'INFORMATION_SCHEMA', 'sys', 'public', 'codaprod_user', 'NT SERVICE\HealthService')
OPEN cursor_name
FETCH NEXT FROM cursor_name INTO #name
WHILE ##FETCH_STATUS = 0
BEGIN
SET #sql = N'IF EXISTS (SELECT TOP 1 1 FROM sys.schemas WHERE [name] = ''' + #name + ''')
BEGIN
DROP SCHEMA [' + #name + N']
END
BEGIN TRY
DROP USER [' + #name + N']
END TRY
BEGIN CATCH END CATCH;'
--PRINT 'USE ' + DB_NAME() + ';' + #sql
EXEC sys.sp_executesql #sql
FETCH NEXT FROM cursor_name INTO #name
END
CLOSE cursor_name
DEALLOCATE cursor_name;
GO

Drop databases with no tables

Is there a query which drops / deletes databases with no tables in them (deletes empty databases)?
Server is Microsoft SQL Server 2005
This should do it.
Tested on a lab machine and it dropped all databases with 0 user tables.
Note, however, that tables aren't the only things in a database, necessarily. There could be stored procedures, functions, etc that someone might still need.
NOTE THAT THIS IS A VERY DANGEROUS OPERATION, AS IT DROPS DATABASES. USE AT YOUR OWN RISK. I AM NOT RESPONSIBLE FOR DAMAGE YOU CAUSE.
USE [master];
DECLARE #name varchar(50);
DECLARE #innerQuery varchar(max);
DECLARE tableCursor CURSOR FOR SELECT name FROM sys.databases where owner_sid != 0x01;
OPEN tableCursor;
FETCH NEXT FROM tableCursor
INTO #name
WHILE ##FETCH_STATUS = 0
BEGIN
SET #innerQuery = 'USE [' + #name + ']; IF (SELECT COUNT(*) FROM sys.objects WHERE type = ''U'') = 0
BEGIN
USE [master];
DROP DATABASE [' + #name + ']
END'
EXEC(#innerQuery)
FETCH NEXT FROM tableCursor INTO #name
END
CLOSE tableCursor;
DEALLOCATE tableCursor;
Note also that, if a database is in use, SQL Server will refuse to drop it. So, if there are other connections to a particular database that this tries to drop, the command will abort.
To avoid that problem, you can set the database in question to single-user mode.
The following script is the same as the above, except it also sets the target databases to single-user mode to kill active connections.
BE EVEN MORE CAREFUL WITH THIS, AS IT'S ESSENTIALLY THE NUCLEAR OPTION:
use [master];
DECLARE #name varchar(50);
DECLARE #innerQuery varchar(max);
DECLARE tableCursor CURSOR FOR SELECT name FROM sys.databases where owner_sid != 0x01;
OPEN tableCursor;
FETCH NEXT FROM tableCursor
INTO #name
WHILE ##FETCH_STATUS = 0
BEGIN
SET #innerQuery =
'USE [' + #name + '];
IF (SELECT COUNT(*) FROM sys.objects WHERE type = ''U'') = 0
BEGIN
USE [master];
ALTER DATABASE [' + #name + '] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE [' + #name + '];
END'
EXEC(#innerQuery)
FETCH NEXT FROM tableCursor INTO #name
END
CLOSE tableCursor;
DEALLOCATE tableCursor;
I think it is not possible (at least not with a TSQL command, might be a stored procedure somewhere). You would have to query sysobjects and abort if any found. (And you have to decide if you want to ignore some of the system objects like the design tables).
The script below will generate the needed DROP DATABASE script. You could tweak this to execute the statement too (in the master database context) but I suggest you review it first just in case.
EXEC sp_MSforeachdb N'
USE [?];
IF N''?'' NOT IN(N''master'', N''model'', N''msdb'', N''tempdb'')
BEGIN
IF NOT EXISTS(
SELECT *
FROM sys.tables
WHERE
OBJECTPROPERTYEX(object_id, ''IsMSShipped'') = 0
)
BEGIN
PRINT ''DROP DATABASE [?];'';
END;
END;';

Script to kill all connections to a database (More than RESTRICTED_USER ROLLBACK)

I have a development database that re-deploy frequently from a Visual Studio Database project (via a TFS Auto Build).
Sometimes when I run my build I get this error:
ALTER DATABASE failed because a lock could not be placed on database 'MyDB'. Try again later.
ALTER DATABASE statement failed.
Cannot drop database "MyDB" because it is currently in use.
I tried this:
ALTER DATABASE MyDB SET RESTRICTED_USER WITH ROLLBACK IMMEDIATE
but I still cannot drop the database. (My guess is that most of the developers have dbo access.)
I can manually run SP_WHO and start killing connections, but I need an automatic way to do this in the auto build. (Though this time my connection is the only one on the db I am trying to drop.)
Is there a script that can drop my database regardless of who is connected?
Updated
For MS SQL Server 2012 and above
USE [master];
DECLARE #kill varchar(8000) = '';
SELECT #kill = #kill + 'kill ' + CONVERT(varchar(5), session_id) + ';'
FROM sys.dm_exec_sessions
WHERE database_id = db_id('MyDB')
EXEC(#kill);
For MS SQL Server 2000, 2005, 2008
USE master;
DECLARE #kill varchar(8000); SET #kill = '';
SELECT #kill = #kill + 'kill ' + CONVERT(varchar(5), spid) + ';'
FROM master..sysprocesses
WHERE dbid = db_id('MyDB')
EXEC(#kill);
USE master
GO
ALTER DATABASE database_name
SET OFFLINE WITH ROLLBACK IMMEDIATE
GO
Ref: http://msdn.microsoft.com/en-us/library/bb522682%28v=sql.105%29.aspx
You can get the script that SSMS provides by doing the following:
Right-click on a database in SSMS and choose delete
In the dialog, check the checkbox for "Close existing connections."
Click the Script button at the top of the dialog.
The script will look something like this:
USE [master]
GO
ALTER DATABASE [YourDatabaseName] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
USE [master]
GO
DROP DATABASE [YourDatabaseName]
GO
Little known: the GO sql statement can take an integer for the number of times to repeat previous command.
So if you:
ALTER DATABASE [DATABASENAME] SET SINGLE_USER
GO
Then:
USE [DATABASENAME]
GO 2000
This will repeat the USE command 2000 times, force deadlock on all other connections, and take ownership of the single connection. (Giving your query window sole access to do as you wish.)
To my experience, using SINGLE_USER helps most of the times, however, one should be careful: I have experienced occasions in which between the time I start the SINGLE_USER command and the time it is finished... apparently another 'user' had gotten the SINGLE_USER access, not me. If that happens, you're in for a tough job trying to get the access to the database back (in my case, it was a specific service running for a software with SQL databases that got hold of the SINGLE_USER access before I did).
What I think should be the most reliable way (can't vouch for it, but it is what I will test in the days to come), is actually:
- stop services that may interfere with your access (if there are any)
- use the 'kill' script above to close all connections
- set the database to single_user immediately after that
- then do the restore
Matthew's supremely efficient script updated to use the dm_exec_sessions DMV, replacing the deprecated sysprocesses system table:
USE [master];
GO
DECLARE #Kill VARCHAR(8000) = '';
SELECT
#Kill = #Kill + 'kill ' + CONVERT(VARCHAR(5), session_id) + ';'
FROM
sys.dm_exec_sessions
WHERE
database_id = DB_ID('<YourDB>');
EXEC sys.sp_executesql #Kill;
Alternative using WHILE loop (if you want to process any other operations per execution):
USE [master];
GO
DECLARE #DatabaseID SMALLINT = DB_ID(N'<YourDB>');
DECLARE #SQL NVARCHAR(10);
WHILE EXISTS ( SELECT
1
FROM
sys.dm_exec_sessions
WHERE
database_id = #DatabaseID )
BEGIN;
SET #SQL = (
SELECT TOP 1
N'kill ' + CAST(session_id AS NVARCHAR(5)) + ';'
FROM
sys.dm_exec_sessions
WHERE
database_id = #DatabaseID
);
EXEC sys.sp_executesql #SQL;
END;
The accepted answer has the drawback that it doesn't take into consideration that a database can be locked by a connection that is executing a query that involves tables in a database other than the one connected to.
This can be the case if the server instance has more than one database and the query directly or indirectly (for example through synonyms) use tables in more than one database etc.
I therefore find that it sometimes is better to use syslockinfo to find the connections to kill.
My suggestion would therefore be to use the below variation of the accepted answer from AlexK:
USE [master];
DECLARE #kill varchar(8000) = '';
SELECT #kill = #kill + 'kill ' + CONVERT(varchar(5), req_spid) + ';'
FROM master.dbo.syslockinfo
WHERE rsc_type = 2
AND rsc_dbid = db_id('MyDB')
EXEC(#kill);
You should be careful about exceptions during killing processes. So you may use this script:
USE master;
GO
DECLARE #kill varchar(max) = '';
SELECT #kill = #kill + 'BEGIN TRY KILL ' + CONVERT(varchar(5), spid) + ';' + ' END TRY BEGIN CATCH END CATCH ;' FROM master..sysprocesses
EXEC (#kill)
#AlexK wrote a great answer. I just want to add my two cents. The code below is entirely based on #AlexK's answer, the difference is that you can specify the user and a time since the last batch was executed (note that the code uses sys.dm_exec_sessions instead of master..sysprocess):
DECLARE #kill varchar(8000);
set #kill =''
select #kill = #kill + 'kill ' + CONVERT(varchar(5), session_id) + ';' from sys.dm_exec_sessions
where login_name = 'usrDBTest'
and datediff(hh,login_time,getdate()) > 1
--and session_id in (311,266)
exec(#kill)
In this example only the process of the user usrDBTest which the last batch was executed more than 1 hour ago will be killed.
You can use Cursor like that:
USE master
GO
DECLARE #SQL AS VARCHAR(255)
DECLARE #SPID AS SMALLINT
DECLARE #Database AS VARCHAR(500)
SET #Database = 'AdventureWorks2016CTP3'
DECLARE Murderer CURSOR FOR
SELECT spid FROM sys.sysprocesses WHERE DB_NAME(dbid) = #Database
OPEN Murderer
FETCH NEXT FROM Murderer INTO #SPID
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQL = 'Kill ' + CAST(#SPID AS VARCHAR(10)) + ';'
EXEC (#SQL)
PRINT ' Process ' + CAST(#SPID AS VARCHAR(10)) +' has been killed'
FETCH NEXT FROM Murderer INTO #SPID
END
CLOSE Murderer
DEALLOCATE Murderer
I wrote about that in my blog here:
http://www.pigeonsql.com/single-post/2016/12/13/Kill-all-connections-on-DB-by-Cursor
SELECT
spid,
sp.[status],
loginame [Login],
hostname,
blocked BlkBy,
sd.name DBName,
cmd Command,
cpu CPUTime,
memusage Memory,
physical_io DiskIO,
lastwaittype LastWaitType,
[program_name] ProgramName,
last_batch LastBatch,
login_time LoginTime,
'kill ' + CAST(spid as varchar(10)) as 'Kill Command'
FROM master.dbo.sysprocesses sp
JOIN master.dbo.sysdatabases sd ON sp.dbid = sd.dbid
WHERE sd.name NOT IN ('master', 'model', 'msdb')
--AND sd.name = 'db_name'
--AND hostname like 'hostname1%'
--AND loginame like 'username1%'
ORDER BY spid
/* If a service connects continously. You can automatically execute kill process then run your script:
DECLARE #sqlcommand nvarchar (500)
SELECT #sqlcommand = 'kill ' + CAST(spid as varchar(10))
FROM master.dbo.sysprocesses sp
JOIN master.dbo.sysdatabases sd ON sp.dbid = sd.dbid
WHERE sd.name NOT IN ('master', 'model', 'msdb')
--AND sd.name = 'db_name'
--AND hostname like 'hostname1%'
--AND loginame like 'username1%'
--SELECT #sqlcommand
EXEC sp_executesql #sqlcommand
*/
USE MASTER
GO
DECLARE #Spid INT
DECLARE #ExecSQL VARCHAR(255)
DECLARE KillCursor CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR
SELECT DISTINCT SPID
FROM MASTER..SysProcesses
WHERE DBID = DB_ID('dbname')
OPEN KillCursor
-- Grab the first SPID
FETCH NEXT
FROM KillCursor
INTO #Spid
WHILE ##FETCH_STATUS = 0
BEGIN
SET #ExecSQL = 'KILL ' + CAST(#Spid AS VARCHAR(50))
EXEC (#ExecSQL)
-- Pull the next SPID
FETCH NEXT
FROM KillCursor
INTO #Spid
END
CLOSE KillCursor
DEALLOCATE KillCursor
If you want to only drop/delete a database you can select the option "Close existing connections" which is by default unset.
Right-click on Database catalog -> options.
Delete -> check option.
Ok
I have tested successfully with simple code below
USE [master]
GO
ALTER DATABASE [YourDatabaseName] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO

SQL Server Kill Command

I have an SQL script which backs up a database and then restores it over another database. the problem I'm having is that the database being overwritten is being locked open by a user so the job fails. I can manually kill the attached user and it runs fine but I need this process to run automatically every night. Is there a kill command which I can time to execute every night? or is there something in the restore options to do the same thing?
Any thoughts?
Thanks
KILL isn't always effective if the client reconnects
I'd consider taking the database offline (or dbo only) then restoring. Thus will prevent further reconnects.
ALTER DATABASE TargetDB SET OFFLINE WITH ROLLBACK IMMEDIATE
or
ALTER DATABASE TargetDB SET RESTRICTED_USER WITH ROLLBACK IMMEDIATE
agree with #gbn you can use following code to get database restore success also
USE master
GO
ALTER DATABASE YourDatabaseName SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
ALTER DATABASE YourDatabaseName SET OFFLINE WITH ROLLBACK IMMEDIATE
GO
however you can use following script to kill connections to selected database.
-- Create the sql to kill the active database connections
DECLARE #execSql VARCHAR(4000),
#databaseName VARCHAR(100)
-- Set the database name for which to kill the connections
SET #databaseName = '[yourdatabase]'
SET #execSql = ''
SELECT #execSql = #execSql + 'kill ' + CONVERT(CHAR(10), spid) + ' '
FROM master.dbo.sysprocesses
WHERE DB_NAME(dbid) = #databaseName
AND DBID <> 0
AND spid <> ##spid
EXEC ( #execSql
)
DECLARE #pid AS INTEGER
DECLARE mycursor CURSOR FOR
select spid
from sys.sysprocesses
WHERE dbid = DB_ID('yourdatabasename')
OPEN mycursor
FETCH NEXT FROM mycursor INTO #pid
WHILE ##FETCH_STATUS = 0
BEGIN
EXECUTE ('KILL '+#pid)
FETCH NEXT FROM mycursor INTO #pid
END
CLOSE mycursor
DEALLOCATE mycursor
Select 'Kill '+ CAST(p.spid AS VARCHAR)KillCommand into #temp
from master.dbo.sysprocesses p (nolock)
join master..sysdatabases d (nolock) on p.dbid = d.dbid
Where d.[name] = 'your db name'
Declare #query nvarchar(max)
--Select * from #temp
Select #query =STUFF((
select ' ' + KillCommand from #temp
FOR XML PATH('')),1,1,'')
Execute sp_executesql #query
Drop table #temp
Use the ‘master’ database and run this query, it will kill all the active connections from your database.

Programmatically replacing linked server references with local database references in SQL Server stored procs?

As a part of a scripted procedure I'm trying to programmatically update references to linked servers in stored procs. We have several references like this:-
SELECT foo, bar
FROM [Server].[Database].dbo.[Table]
Which I would like to translate to:-
SELECT foo, bar
FROM [Database].dbo.[Table]
I would like to do this entirely programmatically in a 'fire and forget' script across several databases.
The idea I have right now is to use metadata to find references to linked tables, read the text of each sp from metadata again, adjust each sp's text, then shove each block of updated text into an exec statement to rebuild 'em one-by-one.
I do wonder whether this will be a humongous pain however, so does anybody have any better ideas? I am open to using powershell if that could provide a better solution.
Thanks in advance!
Hopefully I am understanding the questions, but rather than removing or replacing [Server], I suggest one of two approaches:
Option 1: Don't change any of the
SPs. Instead, update the linked
server configuration to point a
different database, even the local
box.
Option 2: Don't change any of the
SPs. Instead, start using SQL Server
Aliases. SQL Server Aliases are
managed via the CliConfig utility and
are ultimately stored in the
registry. Thus, they can be applied
manually or via .reg script.
Basically, the SQL Server Alias
deciphers the server (along with
port) which is being referenced. If
you update the link server
configuration to reference the SQL
Server Alias rather than a specific
server, you can point your procedures
to different server (even the local server) whenever you
would like.
I hope it helps.
Your approach is the easiest, frankly. I had a similar issue earlier this year
Read sys.sql_modules
REPLACE the linked server text and CREATE -> ALTER
EXEC (#Result)
Here's a script to find all procs/functions/views that reference linked servers on a SQL 2005 instance - might be useful too:
USE master
GO
SET NOCOUNT ON;
--------------------------------------------------------------------
-- Test linked server connections
--------------------------------------------------------------------
BEGIN TRY DROP TABLE #Svrs; END TRY BEGIN CATCH END CATCH;
CREATE TABLE #Svrs
(
[Server] nvarchar(max),
[CanConnectAsDefault] bit
);
DECLARE #ServerName nvarchar(max), #RetVal int;
DECLARE Svrs CURSOR FAST_FORWARD READ_ONLY
FOR
SELECT ServerName = S.name
FROM sys.servers S;
OPEN Svrs;
FETCH NEXT FROM Svrs INTO #ServerName;
WHILE ##FETCH_STATUS = 0
BEGIN
BEGIN TRY
EXEC #RetVal = sys.sp_testlinkedserver #ServerName;
END TRY
BEGIN CATCH
SET #RetVal = sign(##error);
END CATCH;
INSERT INTO #Svrs
SELECT #ServerName
, CASE WHEN #RetVal = 0 THEN 1 ELSE 0 END;
FETCH NEXT FROM Svrs INTO #ServerName;
END;
CLOSE Svrs;
DEALLOCATE Svrs;
SELECT * FROM #Svrs
DROP TABLE #Svrs;
GO
--------------------------------------------------------------------
-- Report linked server references
--------------------------------------------------------------------
BEGIN TRY DROP TABLE #Refs; END TRY BEGIN CATCH END CATCH;
CREATE TABLE #Refs
(
[Server] nvarchar(max),
[Database] nvarchar(max),
[Schema] nvarchar(max),
[Object] nvarchar(max),
[Type] nvarchar(max)
);
DECLARE #DatabaseName nvarchar(max), #ServerName nvarchar(max), #SQL nvarchar(max);
DECLARE Refs CURSOR FAST_FORWARD READ_ONLY
FOR
SELECT DatabaseName = D.name
, ServerName = S.name
-- , ServerProvider = S.provider
-- , ServerSource = S.data_source
FROM sys.databases D
CROSS JOIN sys.servers S
WHERE D.name NOT IN ('master', 'tempdb', 'model', 'msdb', 'ReportServer', 'ReportServerTempDB');
OPEN Refs;
FETCH NEXT FROM Refs INTO #DatabaseName, #ServerName;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQL = 'USE [' + #DatabaseName + '];
INSERT INTO #Refs
SELECT DISTINCT ''' + #ServerName + ''', ''' + #DatabaseName + ''', S.[name], O.[name], O.type_desc
FROM syscomments C
INNER JOIN sys.objects O ON C.id = O.[object_id]
LEFT JOIN sys.schemas S ON S.[schema_id] = O.[schema_id]
WHERE C.[TEXT] LIKE ''%[ ,~[( '''']' + #ServerName + '[ .,~])'''' ]%'' ESCAPE ''~'';'
PRINT 'Looking for ' + #ServerName + ' refs in ' + #DatabaseName -- + ': ' + #SQL;
EXEC sp_executesql #SQL;
FETCH NEXT FROM Refs INTO #DatabaseName, #ServerName;
END
CLOSE Refs;
DEALLOCATE Refs;
SELECT * FROM #Refs
DROP TABLE #Refs;
GO
--------------------------------------------------------------------
SET NOCOUNT OFF;
GO
This is not going to be a good idea for a production environment, but if you need a loopback linked server for dev purposes this worked for me:
EXEC sp_addlinkedserver #server = N'name_for_linked_server',
#srvproduct = N' ',
#provider = N'SQLNCLI',
#datasrc = N'name_of_my_sqlserver_instance',
#catalog = N'name_of_database'