1

I have used below script to shrink database. I know even if not best practice but have requirement to do shrink. Is there any way to get latest database name every time into the script to shrink. at the moment I am doing manually but need to do automatically. Please can anyone suggest.

USE [Sales_backup_2016_08_10_203001_7966467]
ALTER DATABASE [Sales_backup_2016_08_10_203001_7966467]
SET RECOVERY SIMPLE
DBCC SHRINKFILE (Sales_Data)
GO
USE [Sales_backup_2016_08_10_203001_7966467]
DBCC SHRINKFILE (Sales_Log,0)
GO
ALTER DATABASE [Sales_backup_2016_08_10_203001_7966467]
SET RECOVERY SIMPLE
DBCC SHRINKFILE (Sales_Log,0)
GO
TheGameiswar
  • 27,855
  • 8
  • 56
  • 94
Amelia
  • 159
  • 1
  • 3
  • 17

2 Answers2

1

This Statement might help you

SELECT TOP 1 NAME FROM SYS.DATABASES WHERE name<>'tempdb' ORDER BY create_date DESC

Shakeer Mirza
  • 5,054
  • 2
  • 18
  • 41
  • Thanks. This gives the latest database name. how can I include this statement into shrink db script which I added in ticket. please suggest. I mean how can I use the latest database name next to USE which I got from your select query that you posted. – Amelia Nov 11 '16 at 09:49
1

Here are couple of methods you could use:

Method A: Dynamic SQL

This query, which is a little old and could be improved, writes the shrink statement to a variable. The variable is then executed.

For brevity, I've not included the full shrink statement. Edit the line that starts + 'USE ' + QUOTENAME(d.name)....

This query is best viewed in Results to Text mode (Ctrl + T), as it uses line breaks to make the content easier to read (for us humans).

    DECLARE @Qry NVARCHAR(MAX)  = ''        -- The dynamic SQL is written to this var.

    -- Populate @Qry.
    SELECT  
        @Qry = @Qry 
            + 'USE ' + QUOTENAME(d.name) + '; ALTER DATABASE ' + QUOTENAME(d.name) + ' ...;'
            + CHAR(10) 
    FROM    
        sys.Databases d
    WHERE   
        d.[State] =0 
        AND LOWER(d.Name) <> 'tempdb'
    ;

/* Enable the first line to run.
 * Disable the bottom line, when you are happy with the script.
 */
-- EXECUTE sp_ExecuteSQL @Qry
SELECT @Qry;

Method B: Maintencance Tasks

Integration Services includes a number of tasks for performing maintenance work. One of these is the Shrink Database Task. SQL Server includes a wizard that can help you write and schedule your job.

Both methods can be scheduled using the SQL Agent.

EDIT

Corrected query, which contained an undeclared variable.

David Rushton
  • 4,915
  • 1
  • 17
  • 31
  • See this [question](http://stackoverflow.com/questions/194852/concatenate-many-rows-into-a-single-text-string) for more on building a single string from multiple rows. You will see the method used above is not current best practice (and maybe wasn't even when I first wrote this query many years ago). – David Rushton Nov 11 '16 at 10:03
  • Thanks. when I am executing execute sp_executesql @bkuscript showing error must declare bkuscript. so, I replaced bkuscript to qry then query executed with result command completed successfully. but the database did not shrink. Am I missing anything? please suggest. – Amelia Nov 11 '16 at 10:38
  • Apologies! Copy and paste fail. I'll update the example. You were right to change the var to Qry. How long did the process take? If you paste the contents of Qry into a separate window does it run correctly? – David Rushton Nov 11 '16 at 12:35
  • when I am executing the query in separate and same window showing as NULL. nothing displaying. do I need to change anything – Amelia Nov 11 '16 at 12:49
  • Think I know what is happening here. Any string + NULL = NULL (that's why the first line is `DECLARE @Qry NVARCHAR(MAX) = '';`). If you edit your question to include your version of my query I can help you fix it. – David Rushton Nov 11 '16 at 12:55
  • Thanks. here is the one I used. – Amelia Nov 11 '16 at 14:35
  • DECLARE @Qry NVARCHAR(MAX) = '' -- The dynamic SQL is written to this var. -- Populate Qry. SELECT top 1 Qry = Qry + 'USE ' + QUOTENAME(d.name) + 'alter database '+QUOTENAME(d.name) +' '+'SET RECOVERY SIMPLE'+' '+'DBCC SHRINKFILE (Sales_Data)'+' '+'GO'+' '+ 'USE ' + QUOTENAME(d.name) +' '+ +'DBCC SHRINKFILE (Sales_Log,0)'+' '+'GO'+' '+'alter database ' + QUOTENAME(d.name) +' '+'SET RECOVERY SIMPLE'+' '+'DBCC SHRINKFILE (Sales_Log,0)'+' '+'GO'--+' '+--+ CHAR(10) FROM sys.Databases d WHERE d.[State] =0 AND LOWER(d.Name) <> 'tempdb' ORDER BY create_date DESC; – Amelia Nov 11 '16 at 14:41
  • /* Enable the first line to run. * Disable the bottom line, when you are happy with the script. */ EXECUTE sp_ExecuteSQL @Qry --SELECT @Qry; – Amelia Nov 11 '16 at 14:41
  • getting error message as below Msg 102, Level 15, State 1, Line 1 Incorrect syntax near 'GO'. Msg 102, Level 15, State 1, Line 1 Incorrect syntax near 'GO'. Msg 102, Level 15, State 1, Line 1 Incorrect syntax near 'GO'. – Amelia Nov 11 '16 at 14:43
  • I am trying to post @ symbol in the replies but it is not allowing me to post @. but in the query I used @ symbol. please help me to sort out error message – Amelia Nov 11 '16 at 14:44
  • The problem is with the [GO commands](https://msdn.microsoft.com/en-us/library/ms188037.aspx?f=255&MSPPError=-2147217396). From the docs *A Transact-SQL statement cannot occupy the same line as a GO command*. You can either a) remove GO or b) ensure they are written to a separate line. – David Rushton Nov 11 '16 at 15:28
  • Actually first I tried with separate line. after getting error I changed to single line. – Amelia Nov 11 '16 at 15:35
  • I suspect that ExecuteSQL flattens strings, which is why added line breaks did not work. Glad you got it up and running. :) – David Rushton Nov 11 '16 at 16:50