From b1ba27d5601815d1c086b242278fd7c3440dd0c9 Mon Sep 17 00:00:00 2001 From: Konstantin Taranov Date: Mon, 13 Feb 2023 16:15:29 +0300 Subject: [PATCH 01/39] Add SQL training links --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index db3dc914..2b383dfe 100644 --- a/README.md +++ b/README.md @@ -239,6 +239,8 @@ Useful links, scripts, tools and best practice for Microsoft SQL Server Database - [SQL Murder Mystery](https://github.com/NUKnightLab/sql-mysteries) (by NUKnightLab) - [SQL Murder Mystery with answers](https://github.com/erika-e/sql-mysteries) (by Erika Pullum) - [SQL Problems and solutions](http://www.sql-tutorial.ru/en) (by S. I. Moiseenko) + - [Advanced T-SQL Puzzles](https://github.com/smpetersgithub/AdvancedSQLPuzzles) (by Scott Peters) + - [Leetcode SQL Problems](https://leetcode.com/problemset/database/) - Paid - [Lynda Courses](http://www.lynda.com/SQL-Server-training-tutorials/456-0.html) - [Veeam Free Courses](https://go.veeam.com/microsoft-sql-series-webinars.html) From fde7e96cad95e88b7bf7e13b410bfb5b9d11d1b6 Mon Sep 17 00:00:00 2001 From: Michael Salim Date: Tue, 7 Mar 2023 00:40:56 +0000 Subject: [PATCH 02/39] Update databaseanswers.org link to web archive and add dbschemalibrary --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2b383dfe..06944ff1 100644 --- a/README.md +++ b/README.md @@ -487,7 +487,8 @@ Useful links, scripts, tools and best practice for Microsoft SQL Server Database - [SQL Assessment API rules in .csv format](https://github.com/microsoft/sql-server-samples/blob/master/samples/manage/sql-assessment-api/DefaultRuleset.csv) (by Microsoft) - [SQL cheat sheet for PostgreSQL and Oracle](https://www.pcwdld.com/sql-cheat-sheet) (by Marc Wilson) - [Bllitz Excel UI](https://1pro.bi/blitz-excel-ui/) (by Alex) - - [Industry-specific Data Models - cover Subject Areas and are used to create Enterprise Data Models](http://www.databaseanswers.org/data_models/) + - [Industry-specific Data Models - cover Subject Areas and are used to create Enterprise Data Models](https://web.archive.org/web/20220330034214/http://databaseanswers.org/data_models/) + - [Library of Database Schemas](https://dbschemalibrary.com/) - [SQLFacts - A powerful suite of FREE TSQL tools for SQL Server database professionals](https://www.sqlfacts.com) **[⬆ back to top](#table-of-contents)** From 78f4aad545ec783295dcd85ee5e36907c5b8694c Mon Sep 17 00:00:00 2001 From: Konstantin Taranov Date: Mon, 10 Apr 2023 18:04:25 +0300 Subject: [PATCH 03/39] Add Azure_Synapse_Toolbox --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 06944ff1..77daa828 100644 --- a/README.md +++ b/README.md @@ -428,7 +428,8 @@ Useful links, scripts, tools and best practice for Microsoft SQL Server Database - [sp_Develop - can be used by database developers, software developers and for performing database code (smell) reviews.s](https://github.com/EmergentSoftware/SQL-Server-Development-Assessment) (by Kevin Martin) - [DBA Dash - Performance monitoring tool for SQL Server](https://github.com/trimble-oss/dba-dash) (by Trimble) - [lowlydba.sqlserver - A cross-platform Ansible collection using PowerShell to configure and maintain SQL Server](https://github.com/lowlydba/lowlydba.sqlserver) - (by John McCall) - - [SQLWatch - SQLWATCH is an Open Source and completely free SQL Server Monitoring project](https://sqlwatch.io/) + - [SQLWatch - SQLWATCH is an Open Source and completely free SQL Server Monitoring project](https://sqlwatch.io/) (by Marcin Gminski) + - [Azure_Synapse_Toolbox - Repository of tools/queries for managing and monitoring Azure Synapse](https://github.com/microsoft/Azure_Synapse_Toolbox) (by Microsoft) - Other - [SQL# SQLCLR functions](https://sqlsharp.com/) (by Sql Quantum Lift) - [SQL Server Latch Classes Library](https://www.sqlskills.com/help/latches/) (by Paul S. Randal) From cb7cc44caaa4fb4a5062880a239b0cf6099c9995 Mon Sep 17 00:00:00 2001 From: Orestes Date: Tue, 27 Jun 2023 20:53:47 +0100 Subject: [PATCH 04/39] Update dbo.sp_RestoreGene.sql --- Stored_Procedure/dbo.sp_RestoreGene.sql | 2573 +++++++++++++++-------- 1 file changed, 1650 insertions(+), 923 deletions(-) diff --git a/Stored_Procedure/dbo.sp_RestoreGene.sql b/Stored_Procedure/dbo.sp_RestoreGene.sql index 7bea9b5d..f9a3051e 100644 --- a/Stored_Procedure/dbo.sp_RestoreGene.sql +++ b/Stored_Procedure/dbo.sp_RestoreGene.sql @@ -1,26 +1,61 @@ USE [master] GO IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = 'sp_RestoreGene') -EXEC ('CREATE PROC dbo.sp_RestoreGene AS SELECT 1') +EXEC ('CREATE PROC dbo.sp_RestoreGene AS SELECT ''stub version, to be replaced''') GO - + /********************************************************************************************* -Restore Generator v4.3 (2014-10-03) +Restore Generator v8.3 (2022-04-11) (C) 2012, Paul Brewer - + Feedback: paulbrewer@yahoo.co.uk -Updates: https://paulbrewer.wordpress.com/ - +User Guide: https://restoregene.com + This procedure queries msdb database backup history and database file details in master. -It builds and returns RESTORE DATABASE commands as it's result set, it does not execute the commands. - +It builds and returns RESTORE DATABASE commands as its result set, it does not execute the commands. + +---------------------------------------------------------------------------------------------- +PARAMETERS: + +@Database - Default NULL, Restore a specific database or a list of comma seperated database names, NULL which restores all user databases. +@TargetDatabase - Defaults to NULL, override restored database name, only possible if restoring one specific database, if supplied will rename database files and log file too. +@WithMoveDataFiles - Defaults to the actual data file paths, overrides WITH MOVE for data file folder +@WithMoveLogFile - Defaults to the actual log file path, overrides WITH MOVE for log file folder +@WithMoveFileStreamFile - Defaults to the actual file stream file path, overrides WITH MOVE for file stream file folder +@FromFileFullUNC - Defaults to actual backup file drive and folder, UNC path to full backup file +@FromFileDiffUNC - Defaults to actual drive and folder, UNC path to differential backup file +@FromFileLogUNC - Defaults to actual drive and folder, UNC path to log backup files +@StopAt - Defaults to current (datetime2), Stop At a specific date time +@StandbyMode - Defaults to 0, Leave database in standby mode +@IncludeSystemDBs - Defaults to 0, include master, model and msdb database restores +@WithRecovery - Defaults to 0, Recover database(s) after restore +@WithCHECKDB - Defaults to 0, Include a CHECKDB after recovery +@WithReplace - Defaults to 0, replace existing database when no tail log backup exists +@LogShippingStartTime - Only used by ps_RestoreGene +@LogShippingLastLSN - Only used by ps_RestoreGene +@BlobCredential - Defaults to NULL, SQL Credential for Azure Blog Storage Account +@RestoreScriptReplaceThis - Defaults to NULL, Restore Script String Find +@RestoreScriptWithThis - Defaults to NULL, Restore Script String Replace +@SuppressWithMove - Default 1, Exclude WITH MOVE statements from the Restore Script +@PivotWithMove - Default 0, If SuppressWithMove = 0, pivot secondary files to new rows in the result set +@RestoreScriptOnly - Default 0, Return just the RESTORE DATABASE commands +@DropDatabaseAfterRestore - Default 0, Drops the database after the restore, use with check db +@SetSingleUser - Default 0, Adds ALTER DATABASE @database SET SINGLE_USER WITH ROLLBACK IMMEDIATE +@ExcludeDiffAndLogBackups - Default 0, 0=full+diff+ log, 1=full only, 2-full+diff, 3=full+log, 4=diff+log +@IncludeDeviceType7 - Defaults to 1, Include device type 7 backups in restore script +@IncludeDeviceType102 - Defaults to 1, Include device type 102 backups in restore script +@IncludeDeviceType2 - Defaults to 1, Include device type 2 backups in restore script +@IncludeDeviceType9 - Defaults to 1, Include device type 9 backups in restore script + +---------------------------------------------------------------------------------------------- CHANGE LOG: + December 23, 2012 - V1.01 - Release -January 4,2013 - V1.02 - LSN Checks + Bug fix to STOPAT date format -January 11,2013 - V1.03 - SQL Server 2005 compatibility (backup compression problem) & @StandbyMode +January 4, 2013 - V1.02 - LSN Checks + Bug fix to STOPAT date format +January 11, 2013 - V1.03 - SQL Server 2005 compatibility (backup compression problem) & @StandbyMode January 14, 2013 - V1.04 - WITH COPY and up to 10 striped backup files January 15, 2013 - V1.05 - Format of constructed restore script, enclose database name in [ ] -February 7, 2013 - V1.06 - Modified WHERE device_type IN (7,102,2) +February 7, 2013 - V1.06 - Modified WHERE device_type IN (7,102,2,9) May 26, 2013 - V1.07 - Various changes for PoSh Driver Script compatibility October 14, 2013 - V1.08 - Rename parameters, more meaningful names October 15, 2013 - V2.00 - Add 2nd CTE for striped backup files and remove repeating calls to CTE @@ -28,11 +63,11 @@ November 5, 2013 - V2.01 - Secondary .ndf files only included if @WithMoveDat - Extended artificial LSN used for sequencing WITH RECOVERY/CHECKDB to 21 characters - Include database name in results for logging in PoSh May 23, 2014 - V3.0 - Improved logging and error handling, add 'LogShippingVariableDeclare' parameter - Default is Yes when called from query analysier, set to No when called by PoSh + Default is Yes when called from query analyser, set to No when called by PoSh May 30, 2014 - V3.1 - Restructured CTE, all predicates moved to the CTE June 6, 2014 - V3.2 - Add 'LogShippingStartTime' parameter for PowerShell script. To skip subsequent full and diff backups when restoring Logs in PoSh log shipping mode - - Add 'Target Restore Database Name' parameter, Manuj Bahl suggestion + - Add 'Target Restore Database Name' parameter If restoring a specific database, allows overriding restored name Probably used in conjunction with a @WithMove override of data and log files to a different folder. - Add LogShippingLastLSN parameter, used to filter results sent to ps_LogShippingLight @@ -45,24 +80,94 @@ August 5, 2014 - V3.4 - Remove TRY CATCH blocks from log restores and chec - Remove CTE's,use #temp tables, suggested by S.Stresser August 25, 2014 - V3.5 - goestock suggestion - Include device type 7 for AWS EC2 backups August 29th, 2014 - V3.6 - Richard found and fixed a problem with variable declare where database name has a space or full stop. -July 28, 2015 - V3.7 - Luke Sarro, modifications for case sensitivity & parameter sniffing +July 28, 2015 - V3.7 - Luke Sarro, modifications for case sensitivity & parameter sniffing, a massive amount of work done. August 28, 2015 - V3.8 - Luke Sarro modifications, recovery fork management. supports forking in recovery plans when constructing a restore script. Only tested where a single fork exists, IE a restore was done to a historic point in time, with recovery, then subsequent log backups are taken. When a fork exists the restore script will follow the new path for subsequent differential and log backups taken after the forking point. If no rbackup forks exist, the procedure works as before. -September 02 2015 - V3.9 - SQLMongo modification to replace hyphens in database name -September 04, 2015 - V4.0 - Domingo modification, check for default backup path = '' +September 02 2015 - V3.9 - SQLMongo modification to replace hyphens in database name +September 04, 2015 - V4.0 - Domingo modification, check for default backup path = '' September 29, 2015 - V4.2 - Fixes bug identifying full backups taken after a recovery fork, has introduced code duplication to be removed later but fixes problem -October 3, 2015 - V4.3 - Remove code duplication introduced in V4.2 +October 3, 2015 - V4.3 - Remove code duplication introduced in V4.2 +* +June 3rd, 2016 - V5.0 - Feedback from Brent Ozar related viewing spike: + - V5.0 - Reintroduce SQL Server 2005 compatibility - Bob McLaren - Declaring and assigning variables on same line doesn't work with SQL Server 2005. + - V5.0 - Override data and log file paths if overriding restored database name + +June 11th, 2016 - V5.1 - Azure http url restore support, mick@sqlfairy.com + - V5.1 - Restore Script find and replacement variables, mick@sqlfairy.com + +June 17th, 2016 - V5.2 - Removed TRY CATCH block in log restore commands +June 26th, 2016 - V5.3 - Include FILESTREAM files in WITH MOVE, jgkiran +July 3rd, 2016 - V5.4 - New parameter for FILESTREAM files, for WITH MOVE parameter, jgkiran +July 14rd, 2016 - V5.5 - Rename rollback files when standby = 1 to allow multiple concurrent ps_RestoreGene invocations, jgkiran + +August 8th, 2016 - V5.6 - Accepts a comma separated variable list of databases to restore, suggested Stephen T + - Got permission to reuse the 'SELECT DATABASES' code snippet from ola hallengren - https://ola.hallengren.com/ +August 8th, 2016 - V5.7 - Make restore to new database, secondary file names, more meaningful +August 9th, 2016 - V5.8 - Include the WITH MOVE statements on the same results line as the corresponding RESTORE DATABASE statement, flatten the result set to simplify the PoSh driver +August 9th, 2016 - V5.9 - New Parameter, suppress WITH MOVE statements is default, parameter allows override to include them in the script. + +August 13th, 2016 - V6.0 + - Add parameter option to pivot WITH MOVE secondary files to a new result set line. Not compatible with PoSh driver, useful with large, complex databases. + - Add a parameter option to include just the restore script in the result set. Not compatible with PoSh driver, useful as SQL Agent Job step output. + +August 14th, 2016 - V6.1 - Remove parameter @UseDefaultDatabaseBackupPath , no longer used +August 15th, 2016 - V6.2 - @TargetDatabase parameter, file rename tidy +August 17th, 2016 - V6.3 - Edge case fix to fork point LSN +August 19th, 2016 - V6.4 - Publish SQL Server Central +September 4th, 2016 - V6.41 - PoSh Driver Last LSN minor fix. - Published SQL Server Central +September 9th, 2016 - V6.42 - Fix for multiple log files with move, J.Peablles +September 9th, 2016 - V6.43 - Fix for mirrored backups, C.Richardson +September 9th, 2016 - V6.44 - Mod to log file LSN selection, include if matches diff, R.Devries +September 30th, 2016 - V6.45 - Improvements to the output generated when @RestoreScriptOnly = 1, John Lee +September 30th, 2016 - V6.5 - New 'Drop Database After Restore' parameter for use with CHECKDB and automated backup verification, John Lee + +November 5th, 2016 - V6.51 - Increase length of @Database parameter to allow for more comma seperated database names +November 5th, 2016 - V6.52 - Edge case log exclusion criteria mod, R.Devries +November 5th, 2016 - V6.53 - New parameter option to include ALTER DATABASE @database SET SINGLE_USER WITH ROLLBACK IMMEDIATE, Hakan Ekman +November 5th, 2016 - V6.54 - New parameter option to exclude differential and log backups (presumaby for development environment refreshes), Mehedi Amin + +November 19th, 2016 - V6.55 - Remove semi colon from start of T-SQL restore command strings, serves no purpose +November 19th, 2016 - V6.56 - Remove variable declare, log reference and RAISERROR, serves no purpose and generates an error in edge cases ( my_database and my-database ), Lars Rasmussen +November 19th, 2016 - V6.57 - Parameters options for device types to include, Lars Rasmussen + +December 3rd, 2016 - V6.58 - Remove TIME function from STANDBY mode file name construct, for SQL Server 2005 compatibility, Erwin Louwerse +March 26th, 2017 - V6.59 - Significant performance improvements where an instance has many databases, Simone Bizzotto + +June 24th, 2017 - V6.70 - Case Sensitive Collation Database Compatibility - M.Pollock +September 9th, 2017 - V6.71 - Device Type filter fix, LostInEurope01 +November 11th, 2017 - V6.72 - Mod to log file selection, R.Devries + - Increase @Databases variable length, Bob +Febuary 14th, 2018 - V6.73 - Add escape characters to database name in SET SINGLE_USER, Rod +Febuary 16th, 2018 - V7.0 - Increase support for stripped backup files from 10 to 15, Mehedi +Febuary 17th, 2018 - V8.0 - Extensive changes to the backup fork handling, Mike +March 30th, 2018 - V8.04 - Code refactor +May 25th, 2018 - V8.05 - Missing exclusion of copy only backups reintroduced - Andy +August 25th, 2018 - V8.10 - Enhancements to the @ExcludeDiffAndLogBackups parameters, Bob and Chris F + - Change from parameter data type from bit to int + - 0 (default) = full, diff and logs, 1 = full only, 2 = full and diff, 3 = full and logs + - Existing BIT data type functionality retained and extended by new values 2 and 3. +November 8th, 2018 - V8.11 - Bug fix to last log file - Mike +December 6th, 2018 - V8.12 - Optimisation and environment setup fix - Adam +January 12th, 2019 - V8.13 - Sequence of FROM DISK = 'Stripe' files in RESTORE command +January 3rd, 2021 - V8.14 - Restore from Azure blog storage using FROM DISK instead of FROM URL for backup stripes - Aaron +January 9rd, 2021 - V8.15 - Change parameter @ExcludeDiffAndLogBackups, new option 4 to exclude full restore, return incremental diff & log restores - Mehedi Amin +July 11th, 2021 - V8.16 - Add support for an additional 5 stripes bring the total supported to 20, Steven Dannen +April 5th, 2023 - V8.2 - Masood : Bug fix restoring striped backups +April 11th, 2023 - V8.3 - Aaron : Result Set Columns fix + + +* ********************************************************************************************/ - - -ALTER PROC dbo.sp_RestoreGene + +ALTER PROC [dbo].[sp_RestoreGene] ( - @Database SYSNAME = NULL, + @Database VARCHAR(MAX) = NULL, @TargetDatabase SYSNAME = NULL, @WithMoveDataFiles VARCHAR(2000) = NULL, @WithMoveLogFile VARCHAR(2000) = NULL, + @WithMoveFileStreamFile VARCHAR(2000) = NULL, @FromFileFullUNC VARCHAR(2000) = NULL, @FromFileDiffUNC VARCHAR(2000) = NULL, @FromFileLogUNC VARCHAR(2000) = NULL, @@ -72,934 +177,1556 @@ ALTER PROC dbo.sp_RestoreGene @WithRecovery BIT = 0, @WithCHECKDB BIT = 0, @WithReplace BIT = 0, - @UseDefaultDatabaseBackupPath BIT = 0, - @Log_Reference VARCHAR (250) = NULL, - @LogShippingVariableDeclare BIT = 1, + + -- Parameters for PowerShell script use only @LogShippingStartTime DATETIME = NULL, - @LogShippingLastLSN VARCHAR(25) = NULL + @LogShippingLastLSN VARCHAR(25) = NULL, + -- Parameters for PowerShell script use only + + @BlobCredential VARCHAR(255) = NULL, --Credential used for Azure blob access + @RestoreScriptReplaceThis NVARCHAR(255) = NULL, + @RestoreScriptWithThis NVARCHAR(255) = NULL, + @SuppressWithMove BIT = 1, + @PivotWithMove BIT = 0, + @RestoreScriptOnly BIT = 0, + @DropDatabaseAfterRestore BIT = 0, + @SetSingleUser BIT = 0, + @ExcludeDiffAndLogBackups INT = 0, + + -- Options to exclude device types + @IncludeDeviceType7 BIT = 0, --virtual device + @IncludeDeviceType102 BIT = 1, + @IncludeDeviceType2 BIT = 1, + @IncludeDeviceType9 BIT = 1 ) AS BEGIN - -SET NOCOUNT ON; - --- Avoid Parameter Sniffing Problems -DECLARE @Database_ SYSNAME = @Database, - @TargetDatabase_ SYSNAME = @TargetDatabase, - @WithMoveDataFiles_ VARCHAR(2000) = @WithMoveDataFiles, - @WithMoveLogFile_ VARCHAR(2000) = @WithMoveLogFile, - @FromFileFullUNC_ VARCHAR(2000) = @FromFileFullUNC, - @FromFileDiffUNC_ VARCHAR(2000) = @FromFileDiffUNC, - @FromFileLogUNC_ VARCHAR(2000) = @FromFileLogUNC, - @StopAt_ DATETIME = @StopAt, - @StandbyMode_ BIT = @StandbyMode, - @IncludeSystemDBs_ BIT = @IncludeSystemDBs, - @WithRecovery_ BIT = @WithRecovery, - @WithCHECKDB_ BIT = @WithCHECKDB, - @WithReplace_ BIT = @WithReplace, - @UseDefaultDatabaseBackupPath_ BIT = @UseDefaultDatabaseBackupPath, - @Log_Reference_ VARCHAR (250) = @Log_Reference, - @LogShippingVariableDeclare_ BIT = @LogShippingVariableDeclare, - @LogShippingStartTime_ DATETIME = @LogShippingStartTime, - @LogShippingLastLSN_ VARCHAR(25) = @LogShippingLastLSN - --- Defaults Recovery Point Times -IF ISNULL(@StopAt_,'') = '' - SET @StopAt_ = GETDATE(); - -IF ISNULL(@LogShippingStartTime_,'') = '' - SET @LogShippingStartTime_ = @StopAt_; - --- Default written to the SQL Server Error Log -IF ISNULL(@Log_Reference_,'') = '' - SET @Log_Reference_ = 'sp_RestoreGene - Recovery in Progress'; - --- Allow override of restored database name only if working with a specific database -IF @TargetDatabase_ IS NOT NULL AND @Database_ IS NULL - SET @TargetDatabase_ = NULL; - --- ps_LogShippingLight - Filtered Results -IF ISNULL(@LogShippingLastLSN_,'') = '' - SET @LogShippingLastLSN_ = '-1'; - --- Backup file locations defaulted to '' by ps_RestoreGene -IF @FromFileFullUNC_ = '' - SET @FromFileFullUNC_ = NULL; - -IF @FromFileDiffUNC_ = '' - SET @FromFileDiffUNC_ = NULL; - -IF @FromFileLogUNC_ = '' - SET @FromFileLogUNC_ = NULL; - --- Environment Preparation -IF OBJECT_ID('tempdb..#CTE') IS NOT NULL - DROP TABLE #CTE; - -IF OBJECT_ID('tempdb..#Stripes') IS NOT NULL - DROP TABLE #Stripes; - --- Backup forking -IF OBJECT_ID('tempdb..#BackupFork') IS NOT NULL - DROP TABLE #BackupFork; - -SELECT rf1.database_name, MAX(database_backup_lsn) database_backup_lsn, MAX(fork_point_lsn) fork_point_lsn, MAX(last_lsn) last_lsn -INTO #BackupFork -FROM msdb.dbo.backupset rf1 -INNER JOIN -( - SELECT database_name, MAX(backup_finish_date) AS backup_finish_date - FROM msdb.dbo.backupset - WHERE backup_start_date <= @LogShippingStartTime_ - AND fork_point_lsn IS NULL - GROUP BY database_name -) rf2 - ON rf1.database_name = rf2.database_name - -WHERE fork_point_lsn IS NOT NULL -AND rf1.backup_start_date <= @LogShippingStartTime_ -AND rf1.backup_finish_date > rf2.backup_finish_date -GROUP BY rf1.database_name; - -CREATE INDEX IDX_BackupFork ON #BackupFork(database_name); - - --------------------------------------------------------------- --- CTE1 Full Backup UNION Differential Backup UNION Log Backup --------------------------------------------------------------- -WITH CTE -( - database_name - ,current_compatibility_level - ,last_lsn - ,current_is_read_only - ,current_state_desc - ,current_recovery_model_desc - ,has_backup_checksums - ,backup_size - ,[type] - ,backupmediasetid - ,family_sequence_number - ,backupstartdate - ,physical_device_name - ,position -) -AS -( - --------------------------------------------------------------- --- Full backup - Most current immediately before @LogShippingStartTime_ -SELECT - bs.database_name - ,d.[compatibility_level] AS current_compatibility_level - ,bs.last_lsn - ,d.[is_read_only] AS current_is_read_only - ,d.[state_desc] AS current_state_desc - ,d.[recovery_model_desc] current_recovery_model_desc - ,bs.has_backup_checksums - ,bs.backup_size AS backup_size - ,'D' AS [type] - ,bs.media_set_id AS backupmediasetid - ,mf.family_sequence_number - ,x.backup_start_date AS backupstartdate - ,mf.physical_device_name - ,bs.position -FROM msdb.dbo.backupset bs - -INNER JOIN sys.databases d - ON bs.database_name = d.name - -INNER JOIN -( + + SET NOCOUNT ON; + + -- Avoid Parameter Sniffing Problems + DECLARE @Database_ VARCHAR(MAX); + SET @Database_ = @Database; + DECLARE @TargetDatabase_ SYSNAME; + SET @TargetDatabase_ = @TargetDatabase; + + -- Special handling for PoSh Driver + DECLARE @WithMoveDataFiles_ VARCHAR(2000); + IF @WithMoveDataFiles <> '' SET @WithMoveDataFiles_= @WithMoveDataFiles; + DECLARE @WithMoveLogFile_ VARCHAR(2000); + IF @WithMoveLogFile <> '' SET @WithMoveLogFile_= @WithMoveLogFile; + DECLARE @WithMoveFileStreamFile_ VARCHAR(2000); + IF @WithMoveFileStreamFile <> '' SET @WithMoveFileStreamFile_= @WithMoveFileStreamFile; + + DECLARE @FromFileFullUNC_ VARCHAR(2000); + SET @FromFileFullUNC_ = @FromFileFullUNC; + DECLARE @FromFileDiffUNC_ VARCHAR(2000); + SET @FromFileDiffUNC_ = @FromFileDiffUNC; + DECLARE @FromFileLogUNC_ VARCHAR(2000); + SET @FromFileLogUNC_ = @FromFileLogUNC; + DECLARE @StopAt_ DATETIME; + SET @StopAt_ = @StopAt; + DECLARE @StandbyMode_ BIT; + SET @StandbyMode_ = @StandbyMode; + DECLARE @IncludeSystemDBs_ BIT; + SET @IncludeSystemDBs_ = @IncludeSystemDBs; + DECLARE @WithRecovery_ BIT; + SET @WithRecovery_ = @WithRecovery; + DECLARE @WithCHECKDB_ BIT; + SET @WithCHECKDB_ = @WithCHECKDB; + DECLARE @WithReplace_ BIT; + SET @WithReplace_ = @WithReplace; + DECLARE @LogShippingStartTime_ DATETIME; + SET @LogShippingStartTime_ = @LogShippingStartTime; + DECLARE @LogShippingLastLSN_ VARCHAR(25); + SET @LogShippingLastLSN_ = @LogShippingLastLSN; + DECLARE @BlobCredential_ VARCHAR(255); + SET @BlobCredential_ = @BlobCredential; + DECLARE @RestoreScriptReplaceThis_ NVARCHAR(255); + SET @RestoreScriptReplaceThis_ = @RestoreScriptReplaceThis; + DECLARE @RestoreScriptWithThis_ NVARCHAR(255); + SET @RestoreScriptWithThis_ = @RestoreScriptWithThis; + DECLARE @SuppressWithMove_ BIT; + SET @SuppressWithMove_ = @SuppressWithMove; + DECLARE @PivotWithMove_ BIT + SET @PivotWithMove_ = @PivotWithMove; + DECLARE @RestoreScriptOnly_ BIT; + SET @RestoreScriptOnly_ = @RestoreScriptOnly; + DECLARE @DropDatabaseAfterRestore_ BIT; + SET @DropDatabaseAfterRestore_ = @DropDatabaseAfterRestore; + DECLARE @SetSingleUser_ BIT; + SET @SetSingleUser_ = @SetSingleUser; + DECLARE @ExcludeDiffAndLogBackups_ INT; + SET @ExcludeDiffAndLogBackups_ = @ExcludeDiffAndLogBackups; + + -- Defaults Recovery Point Times + IF ISNULL(@StopAt_,'') = '' + SET @StopAt_ = GETDATE(); + + IF ISNULL(@LogShippingStartTime_,'') = '' + SET @LogShippingStartTime_ = @StopAt_; + + -- Allow override of restored database name only if working with a specific database + IF @TargetDatabase_ IS NOT NULL AND @Database_ IS NULL + SET @TargetDatabase_ = NULL; + + IF CHARINDEX(',',@Database_, 1) > 0 + SET @TargetDatabase_ = NULL; + + -- ps_LogShippingLight - Filtered Results + IF ISNULL(@LogShippingLastLSN_,'') = '' + SET @LogShippingLastLSN_ = '-1'; + + -- Present WITH MOVE if override paths are supplied + IF ISNULL(@WithMoveDataFiles,'') <> '' OR ISNULL(@WithMoveLogFile_,'') <> '' OR ISNULL(@WithMoveFileStreamFile_,'') <> '' OR ISNULL(@TargetDatabase_,'') <> '' + SET @SuppressWithMove_ = 0 + + -- Backup file locations defaulted to '' by ps_RestoreGene + IF @FromFileFullUNC_ = '' + SET @FromFileFullUNC_ = NULL; + + IF @FromFileDiffUNC_ = '' + SET @FromFileDiffUNC_ = NULL; + + IF @FromFileLogUNC_ = '' + SET @FromFileLogUNC_ = NULL; + + -- Environment Preparation + IF OBJECT_ID('tempdb..#CTE') IS NOT NULL + DROP TABLE #CTE; + + IF OBJECT_ID('tempdb..#Stripes') IS NOT NULL + DROP TABLE #Stripes; + + IF OBJECT_ID('tempdb..#BackupFork') IS NOT NULL + DROP TABLE #BackupFork; + + IF OBJECT_ID('tempdb..#ForkPointsCount') IS NOT NULL + DROP TABLE #ForkPointsCount; + + IF OBJECT_ID('tempdb..#RestoreGeneResults') IS NOT NULL + DROP TABLE #RestoreGeneResults; + + IF OBJECT_ID('tempdb..#tmpDatabases') IS NOT NULL + DROP TABLE #tmpDatabases; + + IF OBJECT_ID('tempdb..#DeviceTypes') IS NOT NULL + DROP TABLE #DeviceTypes; + + IF OBJECT_ID('tempdb..#FullBackups') IS NOT NULL + DROP TABLE #FullBackups; + + CREATE TABLE #DeviceTypes (device_type tinyint); + IF @IncludeDeviceType7 = 1 INSERT INTO #DeviceTypes (device_type) SELECT 7; + IF @IncludeDeviceType102 = 1 INSERT INTO #DeviceTypes (device_type) SELECT 102; + IF @IncludeDeviceType2 = 1 INSERT INTO #DeviceTypes (device_type) SELECT 2; + IF @IncludeDeviceType9 = 1 INSERT INTO #DeviceTypes (device_type) SELECT 9; + + --======================================================================================================================================= + -- 'SELECT DATABASES' code snippet used below with permission from the ola hallengren - https://ola.hallengren.com/ + ----------------------------------------------------------------------------------------------------------------------------------------- + CREATE TABLE #tmpDatabases + ( + ID int IDENTITY, + DatabaseName nvarchar(450), + DatabaseNameFS nvarchar(max), + DatabaseType nvarchar(max), + Selected bit, + Completed bit + ); + CREATE CLUSTERED INDEX IDX_tmpDatabases ON #tmpDatabases(DatabaseName); + + IF CHARINDEX(',',@Database_,1) > 0 + BEGIN + + DECLARE @SelectedDatabases TABLE + ( + DatabaseName nvarchar(max), + DatabaseType nvarchar(max), + Selected bit + ); + + DECLARE @ErrorMessage nvarchar(max); + DECLARE @Error int; + + ---------------------------------------------------------------------------------------------------- + --// Select databases //-- + ---------------------------------------------------------------------------------------------------- + + SET @Database_ = REPLACE(@Database_, ', ', ','); + + WITH Databases1 (StartPosition, EndPosition, DatabaseItem) AS + ( + SELECT 1 AS StartPosition, + ISNULL(NULLIF(CHARINDEX(',', @Database_, 1), 0), LEN(@Database_) + 1) AS EndPosition, + SUBSTRING(@Database_, 1, ISNULL(NULLIF(CHARINDEX(',', @Database_, 1), 0), LEN(@Database_) + 1) - 1) AS DatabaseItem + WHERE @Database_ IS NOT NULL + UNION ALL + SELECT CAST(EndPosition AS int) + 1 AS StartPosition, + ISNULL(NULLIF(CHARINDEX(',', @Database_, EndPosition + 1), 0), LEN(@Database_) + 1) AS EndPosition, + SUBSTRING(@Database_, EndPosition + 1, ISNULL(NULLIF(CHARINDEX(',', @Database_, EndPosition + 1), 0), LEN(@Database_) + 1) - EndPosition - 1) AS DatabaseItem + FROM Databases1 + WHERE EndPosition < LEN(@Database_) + 1 + ), + Databases2 (DatabaseItem, Selected) AS + ( + SELECT CASE WHEN DatabaseItem LIKE '-%' THEN RIGHT(DatabaseItem,LEN(DatabaseItem) - 1) ELSE DatabaseItem END AS DatabaseItem, + CASE WHEN DatabaseItem LIKE '-%' THEN 0 ELSE 1 END AS Selected + FROM Databases1 + ), + Databases3 (DatabaseItem, DatabaseType, Selected) AS + ( + SELECT CASE WHEN DatabaseItem IN('ALL_DATABASES','SYSTEM_DATABASES','USER_DATABASES') THEN '%' ELSE DatabaseItem END AS DatabaseItem, + CASE WHEN DatabaseItem = 'SYSTEM_DATABASES' THEN 'S' WHEN DatabaseItem = 'USER_DATABASES' THEN 'U' ELSE NULL END AS DatabaseType, + Selected + FROM Databases2 + ), + Databases4 (DatabaseName, DatabaseType, Selected) AS + ( + SELECT CASE WHEN LEFT(DatabaseItem,1) = '[' AND RIGHT(DatabaseItem,1) = ']' THEN PARSENAME(DatabaseItem,1) ELSE DatabaseItem END AS DatabaseItem, + DatabaseType, + Selected + FROM Databases3 + ) + INSERT INTO @SelectedDatabases (DatabaseName, DatabaseType, Selected) + SELECT DatabaseName, + DatabaseType, + Selected + FROM Databases4 + OPTION (MAXRECURSION 0) + + INSERT INTO #tmpDatabases (DatabaseName, DatabaseNameFS, DatabaseType, Selected, Completed) + SELECT [name] AS DatabaseName, + REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE([name],'\',''),'/',''),':',''),'*',''),'?',''),'"',''),'<',''),'>',''),'|',''),' ','') AS DatabaseNameFS, + CASE WHEN name IN('master','msdb','model') THEN 'S' ELSE 'U' END AS DatabaseType, + 0 AS Selected, + 0 AS Completed + FROM sys.databases + WHERE [name] <> 'tempdb' + AND source_database_id IS NULL + ORDER BY [name] ASC + + UPDATE tmpDatabases + SET tmpDatabases.Selected = SelectedDatabases.Selected + FROM #tmpDatabases tmpDatabases + INNER JOIN @SelectedDatabases SelectedDatabases + ON tmpDatabases.DatabaseName LIKE REPLACE(SelectedDatabases.DatabaseName,'_','[_]') + AND (tmpDatabases.DatabaseType = SelectedDatabases.DatabaseType OR SelectedDatabases.DatabaseType IS NULL) + WHERE SelectedDatabases.Selected = 1 + + UPDATE tmpDatabases + SET tmpDatabases.Selected = SelectedDatabases.Selected + FROM #tmpDatabases tmpDatabases + INNER JOIN @SelectedDatabases SelectedDatabases + ON tmpDatabases.DatabaseName LIKE REPLACE(SelectedDatabases.DatabaseName,'_','[_]') + AND (tmpDatabases.DatabaseType = SelectedDatabases.DatabaseType OR SelectedDatabases.DatabaseType IS NULL) + WHERE SelectedDatabases.Selected = 0 + + IF @Database_ IS NULL OR NOT EXISTS(SELECT * FROM @SelectedDatabases) OR EXISTS(SELECT * FROM @SelectedDatabases WHERE DatabaseName IS NULL OR DatabaseName = '') + BEGIN + SET @ErrorMessage = 'The value for the parameter @Databases is not supported.' + CHAR(13) + CHAR(10) + ' ' + RAISERROR(@ErrorMessage,16,1) WITH NOWAIT + SET @Error = @@ERROR + END + + END + + --======================================================================================================================================= + -- Full Backups - Last before stop at for each database SELECT - a.database_name - ,MAX(a.backup_start_date) backup_start_date + a.database_name + ,MAX(a.backup_finish_date) AS backup_finish_date + INTO #FullBackups FROM msdb.dbo.backupset a JOIN msdb.dbo.backupmediafamily b - ON a.media_set_id = b.media_set_id - - LEFT OUTER JOIN #BackupFork c - ON c.database_name = a.database_name - + ON a.media_set_id = b.media_set_id + WHERE a.[type] = 'D' - AND device_type IN (7,102,2) + AND (a.database_name IN (SELECT DatabaseName FROM #tmpDatabases WHERE Selected = 1) OR @Database_ IS NULL OR a.database_name = @Database_) + AND device_type IN (SELECT device_type FROM #DeviceTypes) AND a.is_copy_only = 0 + AND b.mirror = 0 AND a.backup_start_date <= @LogShippingStartTime_ - - -- Recovery Forking - AND ISNULL(c.fork_point_lsn,a.database_backup_lsn) >= a.database_backup_lsn - AND ((c.fork_point_lsn IS NOT NULL AND a.database_backup_lsn < c.database_backup_lsn) OR c.fork_point_lsn IS NULL) - - GROUP BY a.database_name - -) x - ON x.database_name = bs.database_name - AND x.backup_start_date = bs.backup_start_date - -JOIN msdb.dbo.backupmediafamily mf - ON mf.media_set_id = bs.media_set_id - AND mf.family_sequence_number Between bs.first_family_number And bs.last_family_number - -WHERE bs.type = 'D' -AND mf.physical_device_name NOT IN ('Nul', 'Nul:') - -UNION - --------------------------------------------------------------- --- Differential backup, most current immediately before @StopAt_ -SELECT - bs.database_name - ,d.[compatibility_level] AS current_compatibility_level - ,bs.last_lsn - ,d.[is_read_only] AS current_is_read_only - ,d.[state_desc] AS current_state_desc - ,d.[recovery_model_desc] current_recovery_model_desc - ,bs.has_backup_checksums - ,bs.backup_size AS backup_size - ,'I' AS [type] - ,bs.media_set_id AS backupmediasetid - ,mf.family_sequence_number - ,x.backup_start_date AS backupstartdate - ,mf.physical_device_name - ,bs.position -FROM msdb.dbo.backupset bs - -INNER JOIN sys.databases d - ON bs.database_name = d.name - + GROUP BY a.database_name; -INNER JOIN -- Last Full in recovery fork before STOPAT -( --------------------------------------------- - SELECT - a.database_name - ,MAX(a.backup_start_date) backup_start_date - FROM msdb.dbo.backupset a + CREATE INDEX IDX_FullBackups ON #FullBackups(database_name); + + --======================================================================================================================================= + -- Backup forking (suppress differential, log file select criteria) + SELECT bs.database_name, first_recovery_fork_guid, MIN(fork_point_lsn) AS fork_point_lsn + INTO #BackupFork + FROM msdb.dbo.backupset bs JOIN msdb.dbo.backupmediafamily b - ON a.media_set_id = b.media_set_id - - LEFT OUTER JOIN #BackupFork c - ON c.database_name = a.database_name - - WHERE a.[type] = 'D' - AND device_type IN (7,102,2) - AND a.is_copy_only = 0 - AND a.backup_start_date <= @LogShippingStartTime_ - - -- Recovery Forking - AND ISNULL(c.fork_point_lsn,a.database_backup_lsn) >= a.database_backup_lsn - AND ((c.fork_point_lsn IS NOT NULL AND a.database_backup_lsn < c.database_backup_lsn) OR c.fork_point_lsn IS NULL) - - GROUP BY a.database_name --------------------------------------------- -) y - ON y.database_name = bs.database_name + ON bs.media_set_id = b.media_set_id + JOIN #FullBackups fb + ON fb.database_name = bs.database_name + WHERE fb.backup_finish_date < bs.backup_start_date + AND bs.backup_finish_date < @LogShippingStartTime_ + AND bs.first_recovery_fork_guid <> bs.last_recovery_fork_guid + GROUP BY bs.database_name, first_recovery_fork_guid; + + -- Only one fork point between the selected full backup and the stop at time supported + SELECT database_name, COUNT(*) AS ForkPoints + INTO #ForkPointsCount + FROM #BackupFork rh + GROUP BY database_name; + + --======================================================================================================================================= + -------------------------------------------------------------- + -- CTE1 Full Backup + -------------------------------------------------------------- + WITH CTE + ( + database_name + ,current_compatibility_level + ,first_lsn + ,last_lsn + ,fork_point_lsn + ,current_is_read_only + ,current_state_desc + ,current_recovery_model_desc + ,has_backup_checksums + ,backup_size + ,[type] + ,backupmediasetid + ,family_sequence_number + ,backupfinishdate + ,physical_device_name + ,position + ,first_recovery_fork_guid + ,last_recovery_fork_guid + ) + AS + ( + -------------------------------------------------------------- + -- Full backup - Most recent before @LogShippingStartTime_ + SELECT + bs.database_name + ,d.[compatibility_level] AS current_compatibility_level + ,bs.first_lsn + ,bs.last_lsn + ,bs.fork_point_lsn + ,d.[is_read_only] AS current_is_read_only + ,d.[state_desc] AS current_state_desc + ,d.[recovery_model_desc] current_recovery_model_desc + ,bs.has_backup_checksums + ,bs.backup_size AS backup_size + ,'D' AS [type] + ,bs.media_set_id AS backupmediasetid + ,mf.family_sequence_number + ,bs.backup_finish_date AS backupfinishdate + ,mf.physical_device_name + ,bs.position + ,bs.first_recovery_fork_guid + ,bs.last_recovery_fork_guid + + FROM msdb.dbo.backupset bs + + INNER JOIN sys.databases d + ON bs.database_name = d.name + + INNER JOIN #FullBackups fb + ON fb.database_name = bs.database_name + AND fb.backup_finish_date = bs.backup_finish_date + + JOIN msdb.dbo.backupmediafamily mf + ON mf.media_set_id = bs.media_set_id + AND mf.family_sequence_number Between bs.first_family_number And bs.last_family_number + + WHERE bs.type = 'D' + AND mf.mirror = 0 + AND mf.physical_device_name NOT IN ('Nul', 'Nul:') + AND bs.is_copy_only = 0 + + UNION + + -------------------------------------------------------------- + -- Differential backup, most current immediately before @StopAt_, suppress if backup fork points exist + SELECT + bs.database_name + ,d.[compatibility_level] AS current_compatibility_level + ,bs.first_lsn + ,bs.last_lsn + ,bs.fork_point_lsn + ,d.[is_read_only] AS current_is_read_only + ,d.[state_desc] AS current_state_desc + ,d.[recovery_model_desc] current_recovery_model_desc + ,bs.has_backup_checksums + ,bs.backup_size AS backup_size + ,'I' AS [type] + ,bs.media_set_id AS backupmediasetid + ,mf.family_sequence_number + ,bs.backup_finish_date AS backupfinishdate + ,mf.physical_device_name + ,bs.position + ,bs.first_recovery_fork_guid + ,bs.last_recovery_fork_guid + FROM msdb.dbo.backupset bs + + INNER JOIN sys.databases d + ON bs.database_name = d.name + + INNER JOIN #FullBackups fb + ON fb.database_name = bs.database_name + AND fb.backup_finish_date < bs.backup_finish_date + + INNER JOIN -- Last Diff before STOPAT / Suppress if backup forkpoints exist + ( + SELECT + a.database_name + ,MAX(backup_start_date) backup_start_date + FROM msdb.dbo.backupset a + JOIN msdb.dbo.backupmediafamily b + ON a.media_set_id = b.media_set_id + + WHERE a.[type] = 'I' + AND (a.database_name IN (SELECT DatabaseName FROM #tmpDatabases WHERE Selected = 1) OR @Database_ IS NULL OR a.database_name = @Database_) + AND device_type IN (SELECT device_type FROM #DeviceTypes) + AND a.is_copy_only = 0 + AND b.mirror = 0 + AND a.backup_start_date <= ISNULL(@StopAt_,GETDATE()) + GROUP BY a.database_name + ) x + ON x.database_name = bs.database_name + AND x.backup_start_date = bs.backup_start_date + + INNER JOIN msdb.dbo.backupmediafamily mf + ON mf.media_set_id = bs.media_set_id + AND mf.family_sequence_number Between bs.first_family_number And bs.last_family_number + + LEFT OUTER JOIN #BackupFork bf + ON bf.database_name = bs.database_name + + WHERE bs.type = 'I' + AND mf.physical_device_name NOT IN ('Nul', 'Nul:') + AND mf.mirror = 0 + AND @StopAt_ = @LogShippingStartTime_ + AND bf.fork_point_lsn IS NULL + + UNION + + -------------------------------------------------------------- + -- Log file backups - after 1st full / before @StopAt_ + SELECT + bs.database_name + ,d.[compatibility_level] AS current_compatibility_level + ,bs.first_lsn + ,bs.last_lsn + ,bs.fork_point_lsn + ,d.[is_read_only] AS current_is_read_only + ,d.[state_desc] AS current_state_desc + ,d.[recovery_model_desc] current_recovery_model_desc + ,bs.has_backup_checksums + ,bs.backup_size AS backup_size + ,'L' AS [type] + ,bs.media_set_id AS backupmediasetid + ,mf.family_sequence_number + ,bs.backup_finish_date as backupfinishdate + ,mf.physical_device_name + ,bs.position + ,bs.first_recovery_fork_guid + ,bs.last_recovery_fork_guid + FROM msdb.dbo.backupset bs + + INNER JOIN sys.databases d + ON bs.database_name = d.name + + INNER JOIN msdb.dbo.backupmediafamily mf + ON mf.media_set_id = bs.media_set_id + AND mf.family_sequence_number Between bs.first_family_number And bs.last_family_number + + INNER JOIN #FullBackups fb + ON bs.database_name = fb.database_name + + LEFT OUTER JOIN -- Select the first log file after STOPAT + ( + SELECT DISTINCT x.database_name, CASE WHEN y.last_Log_After_StopAt IS NULL THEN CONVERT(datetime, '31 Dec 2050') ELSE y.last_Log_After_StopAt END AS last_Log_After_StopAt + FROM msdb.dbo.backupset x + LEFT JOIN + ( + SELECT + database_name + ,MIN(backup_start_date) last_Log_After_StopAt + FROM msdb.dbo.backupset a + JOIN msdb.dbo.backupmediafamily b + ON a.media_set_id = b.media_set_id + WHERE a.[type] = 'L' + AND (a.database_name IN (SELECT DatabaseName FROM #tmpDatabases WHERE Selected = 1) OR @Database_ IS NULL OR a.database_name = @Database_) + AND b.mirror = 0 + AND device_type IN (SELECT device_type FROM #DeviceTypes) + AND a.backup_start_date > ISNULL(@StopAt_,'1 Jan, 1900') + GROUP BY database_name + ) y + ON x.database_name = y.database_name + ) x + ON bs.database_name = x.database_name + + LEFT OUTER JOIN #BackupFork bf + ON bf.database_name = bs.database_name + AND bf.first_recovery_fork_guid = bs.first_recovery_fork_guid + + WHERE bs.backup_start_date <= x.last_Log_After_StopAt -- Include 1st log after stop at + AND bs.backup_start_date >= fb.backup_finish_date -- Full backup finish + --AND bs.backup_finish_date <= @StopAt_ + AND (bs.database_name IN (SELECT DatabaseName FROM #tmpDatabases WHERE Selected = 1) OR @Database_ IS NULL OR bs.database_name = @Database_) + AND mf.physical_device_name NOT IN ('Nul', 'Nul:') + AND mf.mirror = 0 + AND bs.type = 'L' + AND device_type IN (SELECT device_type FROM #DeviceTypes) + AND (bf.fork_point_lsn > bs.first_lsn OR bf.first_recovery_fork_guid IS NULL OR bs.first_recovery_fork_guid <> bs.last_recovery_fork_guid) + ) + + SELECT * INTO #CTE FROM CTE; + CREATE INDEX IDX_CTE ON #CTE(database_name); + + -------------------------------------------------------------- + -- CTE2 Optionally, striped backup file details + -------------------------------------------------------------- + WITH Stripes + ( + database_name, + backupmediasetid, + family_sequence_number, + last_lsn, + S2_pdn, + S3_pdn, + S4_pdn, + S5_pdn, + S6_pdn, + S7_pdn, + S8_pdn, + S9_pdn, + S10_pdn, + S11_pdn, + S12_pdn, + S13_pdn, + S14_pdn, + S15_pdn, + --************************ + S16_pdn, + S17_pdn, + S18_pdn, + S19_pdn, + S20_pdn + --************************ + ) + AS + ( + SELECT + Stripe1.database_name, + Stripe1.backupmediasetid, + Stripe1.family_sequence_number, + Stripe1.last_lsn, + Stripe2.physical_device_name AS S2_pdn, + Stripe3.physical_device_name AS S3_pdn, + Stripe4.physical_device_name AS S4_pdn, + Stripe5.physical_device_name AS S5_pdn, + Stripe6.physical_device_name AS S6_pdn, + Stripe7.physical_device_name AS S7_pdn, + Stripe8.physical_device_name AS S8_pdn, + Stripe9.physical_device_name AS S9_pdn, + Stripe10.physical_device_name AS S10_pdn, + Stripe11.physical_device_name AS S11_pdn, + Stripe12.physical_device_name AS S12_pdn, + Stripe13.physical_device_name AS S13_pdn, + Stripe14.physical_device_name AS S14_pdn, + Stripe15.physical_device_name AS S15_pdn + --************************ + ,Stripe16.physical_device_name AS S16_pdn + ,Stripe17.physical_device_name AS S17_pdn + ,Stripe18.physical_device_name AS S18_pdn + ,Stripe19.physical_device_name AS S19_pdn + ,Stripe20.physical_device_name AS S20_pdn + --************************ + FROM #CTE AS Stripe1 + + LEFT OUTER JOIN #CTE AS Stripe2 + ON Stripe2.database_name = Stripe1.database_name + AND Stripe2.backupmediasetid = Stripe1.backupmediasetid + AND Stripe2.family_sequence_number = 2 + + LEFT OUTER JOIN #CTE AS Stripe3 + ON Stripe3.database_name = Stripe1.database_name + AND Stripe3.backupmediasetid = Stripe1.backupmediasetid + AND Stripe3.family_sequence_number = 3 + + LEFT OUTER JOIN #CTE AS Stripe4 + ON Stripe4.database_name = Stripe1.database_name + AND Stripe4.backupmediasetid = Stripe1.backupmediasetid + AND Stripe4.family_sequence_number = 4 + + LEFT OUTER JOIN #CTE AS Stripe5 + ON Stripe5.database_name = Stripe1.database_name + AND Stripe5.backupmediasetid = Stripe1.backupmediasetid + AND Stripe5.family_sequence_number = 5 + + LEFT OUTER JOIN #CTE AS Stripe6 + ON Stripe6.database_name = Stripe1.database_name + AND Stripe6.backupmediasetid = Stripe1.backupmediasetid + AND Stripe6.family_sequence_number = 6 + + LEFT OUTER JOIN #CTE AS Stripe7 + ON Stripe7.database_name = Stripe1.database_name + AND Stripe7.backupmediasetid = Stripe1.backupmediasetid + AND Stripe7.family_sequence_number = 7 + + LEFT OUTER JOIN #CTE AS Stripe8 + ON Stripe8.database_name = Stripe1.database_name + AND Stripe8.backupmediasetid = Stripe1.backupmediasetid + AND Stripe8.family_sequence_number = 8 + + LEFT OUTER JOIN #CTE AS Stripe9 + ON Stripe9.database_name = Stripe1.database_name + AND Stripe9.backupmediasetid = Stripe1.backupmediasetid + AND Stripe9.family_sequence_number = 9 + + LEFT OUTER JOIN #CTE AS Stripe10 + ON Stripe10.database_name = Stripe1.database_name + AND Stripe10.backupmediasetid = Stripe1.backupmediasetid + AND Stripe10.family_sequence_number = 10 + + LEFT OUTER JOIN #CTE AS Stripe11 + ON Stripe11.database_name = Stripe1.database_name + AND Stripe11.backupmediasetid = Stripe1.backupmediasetid + AND Stripe11.family_sequence_number = 11 + + LEFT OUTER JOIN #CTE AS Stripe12 + ON Stripe12.database_name = Stripe1.database_name + AND Stripe12.backupmediasetid = Stripe1.backupmediasetid + AND Stripe12.family_sequence_number = 12 + + LEFT OUTER JOIN #CTE AS Stripe13 + ON Stripe13.database_name = Stripe1.database_name + AND Stripe13.backupmediasetid = Stripe1.backupmediasetid + AND Stripe13.family_sequence_number = 13 + + LEFT OUTER JOIN #CTE AS Stripe14 + ON Stripe14.database_name = Stripe1.database_name + AND Stripe14.backupmediasetid = Stripe1.backupmediasetid + AND Stripe14.family_sequence_number = 14 + + LEFT OUTER JOIN #CTE AS Stripe15 + ON Stripe15.database_name = Stripe1.database_name + AND Stripe15.backupmediasetid = Stripe1.backupmediasetid + AND Stripe15.family_sequence_number = 15 -INNER JOIN -- Last Diff before STOPAT -( + --************************ + LEFT OUTER JOIN #CTE AS Stripe16 + ON Stripe16.database_name = Stripe1.database_name + AND Stripe16.backupmediasetid = Stripe1.backupmediasetid + AND Stripe16.family_sequence_number = 16 + + LEFT OUTER JOIN #CTE AS Stripe17 + ON Stripe17.database_name = Stripe1.database_name + AND Stripe17.backupmediasetid = Stripe1.backupmediasetid + AND Stripe17.family_sequence_number = 17 + + LEFT OUTER JOIN #CTE AS Stripe18 + ON Stripe18.database_name = Stripe1.database_name + AND Stripe18.backupmediasetid = Stripe1.backupmediasetid + AND Stripe18.family_sequence_number = 18 + + LEFT OUTER JOIN #CTE AS Stripe19 + ON Stripe19.database_name = Stripe1.database_name + AND Stripe19.backupmediasetid = Stripe1.backupmediasetid + AND Stripe19.family_sequence_number = 19 + + LEFT OUTER JOIN #CTE AS Stripe20 + ON Stripe20.database_name = Stripe1.database_name + AND Stripe20.backupmediasetid = Stripe1.backupmediasetid + AND Stripe20.family_sequence_number = 20 +-- ************************ + + ) + + SELECT * INTO #Stripes FROM Stripes; + + CREATE INDEX IDX_Stripes ON #Stripes(database_name); + + -------------------------------------------------------------- + -- Results, T-SQL RESTORE commands, below are based on CTE's above + -------------------------------------------------------------- + SELECT - a.database_name - ,MAX(backup_start_date) backup_start_date - FROM msdb.dbo.backupset a - JOIN msdb.dbo.backupmediafamily b - ON a.media_set_id = b.media_set_id - - LEFT OUTER JOIN #BackupFork c - ON c.database_name = a.database_name - - WHERE a.[type] = 'I' - AND device_type IN (7,102,2) - AND a.is_copy_only = 0 - AND a.backup_start_date <= ISNULL(@StopAt_,GETDATE()) - AND a.database_backup_lsn = ISNULL(c.database_backup_lsn,a.database_backup_lsn ) - AND a.last_lsn <= ISNULL(c.fork_point_lsn, a.last_lsn) - GROUP BY a.database_name - -) x - ON x.database_name = bs.database_name - AND x.backup_start_date = bs.backup_start_date - - -INNER JOIN msdb.dbo.backupmediafamily mf - ON mf.media_set_id = bs.media_set_id - AND mf.family_sequence_number Between bs.first_family_number And bs.last_family_number - -WHERE bs.type = 'I' -AND mf.physical_device_name NOT IN ('Nul', 'Nul:') -AND x.backup_start_date > y.backup_start_date -AND @StopAt_ = @LogShippingStartTime_ - -UNION - --------------------------------------------------------------- --- Log file backups - after 1st full / before @StopAt_ -SELECT - bs.database_name - ,d.[compatibility_level] AS current_compatibility_level - ,bs.last_lsn - ,d.[is_read_only] AS current_is_read_only - ,d.[state_desc] AS current_state_desc - ,d.[recovery_model_desc] current_recovery_model_desc - ,bs.has_backup_checksums - ,bs.backup_size AS backup_size - ,'L' AS [type] - ,bs.media_set_id AS backupmediasetid - ,mf.family_sequence_number - ,bs.backup_start_date as backupstartdate - ,mf.physical_device_name - ,bs.position - -FROM msdb.dbo.backupset bs - -INNER JOIN sys.databases d - ON bs.database_name = d.name - -INNER JOIN msdb.dbo.backupmediafamily mf - ON mf.media_set_id = bs.media_set_id - AND mf.family_sequence_number Between bs.first_family_number And bs.last_family_number - -INNER JOIN -- After the selected full backup -( + CASE WHEN @RestoreScriptReplaceThis_ IS NOT NULL AND @RestoreScriptWithThis_ IS NOT NULL THEN REPLACE(a.Command, @RestoreScriptReplaceThis_, @RestoreScriptWithThis_) ELSE a.Command END AS TSQL, --Allow substitution of a path + CONVERT(nvarchar(30), a.backupfinishdate, 126) + AS BackupDate, + a.BackupDevice, + a.first_lsn, + a.last_lsn, + a.fork_point_lsn, + a.first_recovery_fork_guid, + a.last_recovery_fork_guid, + a.database_name , + ROW_NUMBER() OVER(ORDER BY database_name, Sequence, a.backupfinishdate) AS SortSequence + INTO #RestoreGeneResults + FROM + ( + + -------------------------------------------------------------- + -- Most recent full backup + -------------------------------------------------------------- + SELECT - a.database_name - ,MAX(a.backup_start_date) backup_start_date - FROM msdb.dbo.backupset a - JOIN msdb.dbo.backupmediafamily b - ON a.media_set_id = b.media_set_id - - LEFT OUTER JOIN #BackupFork c - ON c.database_name = a.database_name - - WHERE a.[type] = 'D' - AND device_type IN (7,102,2) - AND a.is_copy_only = 0 - AND a.backup_start_date <= @LogShippingStartTime_ - - -- Recovery Forking - AND ISNULL(c.fork_point_lsn,a.database_backup_lsn) >= a.database_backup_lsn - AND ((c.fork_point_lsn IS NOT NULL AND a.database_backup_lsn < c.database_backup_lsn) OR c.fork_point_lsn IS NULL) - - GROUP BY a.database_name -) y - ON bs.database_name = y.database_name - -LEFT OUTER JOIN #BackupFork r - ON r.database_name = bs.database_name + + 'RESTORE DATABASE [' + CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN d.[name] ELSE @TargetDatabase_ END + ']' + SPACE(1) + CHAR(13) + + + CASE WHEN #CTE.physical_device_name LIKE 'http%' THEN ' FROM URL = N' ELSE ' FROM DISK = N' END + '''' + --Support restore from blob storage in Azure + + CASE ISNULL(@FromFileFullUNC_,'Actual') + WHEN 'Actual' THEN #CTE.physical_device_name + ELSE @FromFileFullUNC_ + SUBSTRING(#CTE.physical_device_name,LEN(#CTE.physical_device_name) - CHARINDEX('\',REVERSE(#CTE.physical_device_name),1) + 2,CHARINDEX('\',REVERSE(#CTE.physical_device_name),1) + 1) + END + '''' + SPACE(1) + CHAR(13) + + + -- Striped backup files + CASE ISNULL(#Stripes.S2_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S2_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S2_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S2_pdn,LEN(#Stripes.S2_pdn) - CHARINDEX('\',REVERSE(#Stripes.S2_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S2_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S3_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S3_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S3_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S3_pdn,LEN(#Stripes.S3_pdn) - CHARINDEX('\',REVERSE(#Stripes.S3_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S3_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S4_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S4_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S4_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S4_pdn,LEN(#Stripes.S4_pdn) - CHARINDEX('\',REVERSE(#Stripes.S4_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S4_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S5_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S5_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S5_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S5_pdn,LEN(#Stripes.S5_pdn) - CHARINDEX('\',REVERSE(#Stripes.S5_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S5_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S6_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S6_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S6_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S6_pdn,LEN(#Stripes.S6_pdn) - CHARINDEX('\',REVERSE(#Stripes.S6_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S6_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S7_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S7_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S7_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S7_pdn,LEN(#Stripes.S7_pdn) - CHARINDEX('\',REVERSE(#Stripes.S7_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S7_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S8_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S8_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S8_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S8_pdn,LEN(#Stripes.S8_pdn) - CHARINDEX('\',REVERSE(#Stripes.S8_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S8_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S9_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S9_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S9_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S9_pdn,LEN(#Stripes.S9_pdn) - CHARINDEX('\',REVERSE(#Stripes.S9_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S9_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S10_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S10_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S10_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S10_pdn,LEN(#Stripes.S10_pdn) - CHARINDEX('\',REVERSE(#Stripes.S10_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S10_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S11_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S11_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S11_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S11_pdn,LEN(#Stripes.S11_pdn) - CHARINDEX('\',REVERSE(#Stripes.S11_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S11_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S12_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S12_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S12_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S12_pdn,LEN(#Stripes.S12_pdn) - CHARINDEX('\',REVERSE(#Stripes.S12_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S12_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S13_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S13_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S13_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S13_pdn,LEN(#Stripes.S13_pdn) - CHARINDEX('\',REVERSE(#Stripes.S13_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S13_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S14_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S14_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S14_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S14_pdn,LEN(#Stripes.S14_pdn) - CHARINDEX('\',REVERSE(#Stripes.S14_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S14_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S15_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S15_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S15_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S15_pdn,LEN(#Stripes.S15_pdn) - CHARINDEX('\',REVERSE(#Stripes.S15_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S15_pdn),1) + 1) END + '''' + END + + + --******* + + CASE ISNULL(#Stripes.S16_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S16_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S16_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S16_pdn,LEN(#Stripes.S16_pdn) - CHARINDEX('\',REVERSE(#Stripes.S16_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S16_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S17_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S17_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S17_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S17_pdn,LEN(#Stripes.S17_pdn) - CHARINDEX('\',REVERSE(#Stripes.S17_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S17_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S18_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S18_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S18_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S18_pdn,LEN(#Stripes.S18_pdn) - CHARINDEX('\',REVERSE(#Stripes.S18_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S18_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S19_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S19_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S19_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S19_pdn,LEN(#Stripes.S19_pdn) - CHARINDEX('\',REVERSE(#Stripes.S19_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S19_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S20_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S20_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S20_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S20_pdn,LEN(#Stripes.S20_pdn) - CHARINDEX('\',REVERSE(#Stripes.S20_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S20_pdn),1) + 1) END + '''' + END + -LEFT OUTER JOIN -- Select the first log file after STOPAT -( - SELECT DISTINCT x.database_name, database_backup_lsn, - CASE WHEN y.last_Log_After_StopAt IS NULL THEN CONVERT(datetime, '31 Dec 2050') ELSE y.last_Log_After_StopAt END AS last_Log_After_StopAt - FROM msdb.dbo.backupset x - LEFT JOIN + --****** + + ' WITH ' + + + CASE WHEN #CTE.physical_device_name LIKE 'http%' AND @BlobCredential_ IS NOT NULL THEN ' CREDENTIAL = ''' + @BlobCredential_ + ''', ' ELSE '' END + + + CASE ISNULL(@WithReplace_,0) WHEN 1 THEN 'REPLACE, ' ELSE '' END + 'FILE = ' + CAST(#CTE.position AS VARCHAR(5)) + ',' + + CASE #CTE.has_backup_checksums WHEN 1 THEN 'CHECKSUM, ' ELSE ' ' END + + + CASE @StandbyMode_ WHEN 0 THEN 'NORECOVERY,' ELSE 'STANDBY =N' + '''' + ISNULL(@FromFileFullUNC_,SUBSTRING(#CTE.physical_device_name,1,LEN(#CTE.physical_device_name) - CHARINDEX('\',REVERSE(#CTE.physical_device_name)))) + '\' + d.name + '_' + REPLACE(REPLACE(SUBSTRING(CONVERT(VARCHAR(24),GETDATE(),127),12,12),':',''),'.','') + '_ROLLBACK_UNDO.bak ' + '''' + ',' END + SPACE(1) + + + 'STATS=10' + SPACE(1) + + + CASE @SuppressWithMove_ WHEN 0 THEN + + ', MOVE N' + '''' + x.LogicalName + '''' + ' TO ' + + '''' + + CASE ISNULL(@WithMoveDataFiles_,'Actual') + WHEN 'Actual' THEN x.PhysicalName + ELSE @WithMoveDataFiles_ + SUBSTRING(x.PhysicalName,LEN(x.PhysicalName) - CHARINDEX('\',REVERSE(x.PhysicalName),1) + 2,CHARINDEX('\',REVERSE(x.PhysicalName),1) + 1) + END + '''' + SPACE(1) + + + ', MOVE N' + '''' + y.LogicalName + '''' + ' TO ' + + '''' + + CASE ISNULL(@WithMoveLogFile_ ,'Actual') + WHEN 'Actual' THEN y.PhysicalName + ELSE @WithMoveLogFile_ + SUBSTRING(y.PhysicalName,LEN(y.PhysicalName) - CHARINDEX('\',REVERSE(y.PhysicalName),1) + 2,CHARINDEX('\',REVERSE(y.PhysicalName),1) + 1) + END + '''' + ELSE ' ' + END + + AS Command, + 1 AS Sequence, + d.name AS database_name, + #CTE.physical_device_name AS BackupDevice, + #CTE.backupfinishdate, + #CTE.backup_size, + #CTE.first_lsn, + #CTE.last_lsn, + #CTE.fork_point_lsn, + #CTE.first_recovery_fork_guid, + #CTE.last_recovery_fork_guid + + FROM sys.databases d + + INNER JOIN ( SELECT - database_name - ,MIN(backup_start_date) last_Log_After_StopAt - FROM msdb.dbo.backupset a - JOIN msdb.dbo.backupmediafamily b - ON a.media_set_id = b.media_set_id - WHERE a.[type] = 'L' - AND device_type IN (7,102,2) - AND a.backup_start_date > ISNULL(@StopAt_,'1 Jan, 1900') - GROUP BY database_name + DB_NAME(mf.database_id) AS name + ,CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN mf.Physical_Name ELSE SUBSTRING(mf.Physical_Name,1,CASE CHARINDEX('.',mf.Physical_Name) WHEN 0 THEN LEN(mf.Physical_Name) ELSE CHARINDEX('.',mf.Physical_Name) - 1 END) + '_' + @TargetDatabase_ + '.mdf' END AS PhysicalName + ,mf.Name AS LogicalName + FROM sys.master_files mf + WHERE type_desc = 'ROWS' + AND mf.file_id = 1 + ) x + ON d.name = x.name + + INNER JOIN + ( + SELECT + DB_NAME(mf.database_id) AS name, type_desc + ,CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN mf.Physical_Name ELSE SUBSTRING(mf.Physical_Name,1,CASE CHARINDEX('.',mf.Physical_Name) WHEN 0 THEN LEN(mf.Physical_Name) ELSE CHARINDEX('.',mf.Physical_Name) - 1 END) + '_' + @TargetDatabase_ + '.ldf' END AS PhysicalName + ,mf.Name AS LogicalName + FROM sys.master_files mf + + -- Fix for multiple log files/with moves + INNER JOIN + ( + SELECT database_id, MIN(file_id) AS logfile_id + FROM sys.master_files + WHERE type_desc = 'LOG' + GROUP BY database_id + ) logfileid + on logfileid.database_id = mf.database_id + AND logfileid.logfile_id = mf.file_id + WHERE type_desc = 'LOG' ) y - ON x.database_name = y.database_name -) x - ON bs.database_name = x.database_name - AND bs.database_backup_lsn = ISNULL(r.database_backup_lsn,bs.database_backup_lsn) - -WHERE bs.backup_start_date <= x.last_Log_After_StopAt -- Include 1st log after stop at -AND bs.backup_start_date >= y.backup_start_date -- After last full backup start date -AND bs.database_backup_lsn = ISNULL(r.database_backup_lsn,bs.database_backup_lsn) -- Recovery Fork -AND NOT (bs.first_lsn < ISNULL(r.fork_point_lsn,'99999999999999999') AND bs.last_lsn > ISNULL(r.fork_point_lsn,'00000000000000000') AND bs.last_lsn <> ISNULL(r.last_lsn,bs.last_lsn)) - + ON d.name = y.name + + LEFT OUTER JOIN #CTE + ON #CTE.database_name = d.name + AND #CTE.family_sequence_number = 1 + + INNER JOIN #Stripes + ON #Stripes.database_name = d.name + AND #Stripes.backupmediasetid = #CTE.backupmediasetid + AND #Stripes.last_lsn = #CTE.last_lsn + + LEFT OUTER JOIN #ForkPointsCount fpc + ON fpc.database_name = #CTE.database_name + + WHERE #CTE.[type] = 'D' + AND #CTE.family_sequence_number = 1 + AND ISNULL(fpc.ForkPoints,0) < 2 + AND @ExcludeDiffAndLogBackups_ IN (0,1,2,3) + + -------------------------------------------------------------- + -- Most recent differential backup + -------------------------------------------------------------- + UNION + + SELECT + + 'RESTORE DATABASE [' + CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN d.[name] ELSE @TargetDatabase_ END + ']' + SPACE(1) + CHAR(13) + + CASE WHEN #CTE.physical_device_name LIKE 'http%' THEN ' FROM URL = N' ELSE ' FROM DISK = N' END + '''' + + + CASE ISNULL(@FromFileDiffUNC_,'Actual') + WHEN 'Actual' THEN #CTE.physical_device_name + ELSE @FromFileDiffUNC_ + SUBSTRING(#CTE.physical_device_name,LEN(#CTE.physical_device_name) - CHARINDEX('\',REVERSE(#CTE.physical_device_name),1) + 2,CHARINDEX('\',REVERSE(#CTE.physical_device_name),1) + 1) + END + '''' + SPACE(1) + CHAR(13) + + + -- Striped backup files + CASE ISNULL(#Stripes.S2_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S2_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S2_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S2_pdn,LEN(#Stripes.S2_pdn) - CHARINDEX('\',REVERSE(#Stripes.S2_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S2_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S3_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S3_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S3_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S3_pdn,LEN(#Stripes.S3_pdn) - CHARINDEX('\',REVERSE(#Stripes.S3_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S3_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S4_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S4_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S4_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S4_pdn,LEN(#Stripes.S4_pdn) - CHARINDEX('\',REVERSE(#Stripes.S4_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S4_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S5_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S5_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S5_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S5_pdn,LEN(#Stripes.S5_pdn) - CHARINDEX('\',REVERSE(#Stripes.S5_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S5_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S6_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S6_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S6_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S6_pdn,LEN(#Stripes.S6_pdn) - CHARINDEX('\',REVERSE(#Stripes.S6_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S6_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S7_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S7_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S7_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S7_pdn,LEN(#Stripes.S7_pdn) - CHARINDEX('\',REVERSE(#Stripes.S7_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S7_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S8_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S8_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S8_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S8_pdn,LEN(#Stripes.S8_pdn) - CHARINDEX('\',REVERSE(#Stripes.S8_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S8_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S9_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S9_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S9_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S9_pdn,LEN(#Stripes.S9_pdn) - CHARINDEX('\',REVERSE(#Stripes.S9_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S9_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S10_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S10_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S10_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S10_pdn,LEN(#Stripes.S10_pdn) - CHARINDEX('\',REVERSE(#Stripes.S10_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S10_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S11_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S11_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S11_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S11_pdn,LEN(#Stripes.S11_pdn) - CHARINDEX('\',REVERSE(#Stripes.S11_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S11_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S12_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S12_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S12_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S12_pdn,LEN(#Stripes.S12_pdn) - CHARINDEX('\',REVERSE(#Stripes.S12_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S12_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S13_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S13_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S13_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S13_pdn,LEN(#Stripes.S13_pdn) - CHARINDEX('\',REVERSE(#Stripes.S13_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S13_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S14_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S14_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S14_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S14_pdn,LEN(#Stripes.S14_pdn) - CHARINDEX('\',REVERSE(#Stripes.S14_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S14_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S15_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S15_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S15_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S15_pdn,LEN(#Stripes.S15_pdn) - CHARINDEX('\',REVERSE(#Stripes.S15_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S15_pdn),1) + 1) END + '''' + END + + + --************************** + + CASE ISNULL(#Stripes.S16_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S16_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S16_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S16_pdn,LEN(#Stripes.S16_pdn) - CHARINDEX('\',REVERSE(#Stripes.S16_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S16_pdn),1) + 1) END + '''' + END + + + + CASE ISNULL(#Stripes.S17_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S17_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S17_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S17_pdn,LEN(#Stripes.S17_pdn) - CHARINDEX('\',REVERSE(#Stripes.S17_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S17_pdn),1) + 1) END + '''' + END + + + + CASE ISNULL(#Stripes.S18_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S18_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S18_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S18_pdn,LEN(#Stripes.S18_pdn) - CHARINDEX('\',REVERSE(#Stripes.S18_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S18_pdn),1) + 1) END + '''' + END + + + + CASE ISNULL(#Stripes.S19_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S19_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S19_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S19_pdn,LEN(#Stripes.S19_pdn) - CHARINDEX('\',REVERSE(#Stripes.S19_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S19_pdn),1) + 1) END + '''' + END + + + + CASE ISNULL(#Stripes.S20_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S20_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S20_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S20_pdn,LEN(#Stripes.S20_pdn) - CHARINDEX('\',REVERSE(#Stripes.S20_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S20_pdn),1) + 1) END + '''' + END + + + --************************** + + ' WITH FILE = ' + CAST(#CTE.position AS VARCHAR(5)) + ',' + + CASE #CTE.has_backup_checksums WHEN 1 THEN 'CHECKSUM, ' ELSE ' ' END + + + CASE WHEN #CTE.physical_device_name LIKE 'http%' AND @BlobCredential_ IS NOT NULL THEN ' CREDENTIAL = ''' + @BlobCredential_ + ''', ' ELSE '' END + + + CASE @StandbyMode_ WHEN 0 THEN 'NORECOVERY,' ELSE 'STANDBY =N' + '''' + ISNULL(@FromFileFullUNC_,SUBSTRING(#CTE.physical_device_name,1,LEN(#CTE.physical_device_name) - CHARINDEX('\',REVERSE(#CTE.physical_device_name)))) + '\' + d.name + '_' + REPLACE(REPLACE(SUBSTRING(CONVERT(VARCHAR(24),GETDATE(),127),12,12),':',''),'.','') + '_ROLLBACK_UNDO.bak ' + '''' + ',' END + SPACE(1) + + + 'STATS=10' + SPACE(1) + + AS Command, + 750000 AS Sequence, + d.name AS database_name, + #CTE.physical_device_name AS BackupDevice, + #CTE.backupfinishdate, + #CTE.backup_size, + #CTE.first_lsn, + #CTE.last_lsn, + #CTE.fork_point_lsn, + #CTE.first_recovery_fork_guid, + #CTE.last_recovery_fork_guid + + + FROM sys.databases d + + INNER JOIN #CTE + ON #CTE.database_name = d.name + AND #CTE.family_sequence_number = 1 + + LEFT OUTER JOIN #Stripes + ON #Stripes.database_name = d.name + AND #Stripes.backupmediasetid = #CTE.backupmediasetid + AND #Stripes.last_lsn = #CTE.last_lsn + + LEFT OUTER JOIN #ForkPointsCount fpc + ON fpc.database_name = #CTE.database_name + + WHERE #CTE.[type] = 'I' + AND #CTE.family_sequence_number = 1 + AND @ExcludeDiffAndLogBackups_ IN (0,2,4) + AND ISNULL(fpc.ForkPoints,0) < 2 + + -------------------------------------------------------------- + UNION -- Log backups taken since most recent full or diff + -------------------------------------------------------------- + + SELECT + + 'RESTORE LOG [' + CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN d.[name] ELSE @TargetDatabase_ END + ']' + SPACE(1) + CHAR(13) + + + CASE WHEN #CTE.physical_device_name LIKE 'http%' THEN ' FROM URL = N' ELSE ' FROM DISK = N' END + '''' + + + CASE ISNULL(@FromFileLogUNC_,'Actual') + WHEN 'Actual' THEN #CTE.physical_device_name + ELSE @FromFileLogUNC_ + SUBSTRING(#CTE.physical_device_name,LEN(#CTE.physical_device_name) - CHARINDEX('\',REVERSE(#CTE.physical_device_name),1) + 2,CHARINDEX('\',REVERSE(#CTE.physical_device_name),1) + 1) + END + '''' + CHAR(13) + + + -- Striped backup files + CASE ISNULL(#Stripes.S2_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S2_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S2_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S2_pdn,LEN(#Stripes.S2_pdn) - CHARINDEX('\',REVERSE(#Stripes.S2_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S2_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S3_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S3_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S3_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S3_pdn,LEN(#Stripes.S3_pdn) - CHARINDEX('\',REVERSE(#Stripes.S3_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S3_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S4_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S4_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S4_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S4_pdn,LEN(#Stripes.S4_pdn) - CHARINDEX('\',REVERSE(#Stripes.S4_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S4_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S5_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S5_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S5_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S5_pdn,LEN(#Stripes.S5_pdn) - CHARINDEX('\',REVERSE(#Stripes.S5_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S5_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S6_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S6_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S6_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S6_pdn,LEN(#Stripes.S6_pdn) - CHARINDEX('\',REVERSE(#Stripes.S6_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S6_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S7_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S7_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S7_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S7_pdn,LEN(#Stripes.S7_pdn) - CHARINDEX('\',REVERSE(#Stripes.S7_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S7_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S8_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S8_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S8_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S8_pdn,LEN(#Stripes.S8_pdn) - CHARINDEX('\',REVERSE(#Stripes.S8_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S8_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S9_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S9_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S9_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S9_pdn,LEN(#Stripes.S9_pdn) - CHARINDEX('\',REVERSE(#Stripes.S9_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S9_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S10_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S10_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S10_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S10_pdn,LEN(#Stripes.S10_pdn) - CHARINDEX('\',REVERSE(#Stripes.S10_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S10_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S11_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S11_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S11_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S11_pdn,LEN(#Stripes.S10_pdn) - CHARINDEX('\',REVERSE(#Stripes.S11_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S11_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S12_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S12_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S12_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S12_pdn,LEN(#Stripes.S12_pdn) - CHARINDEX('\',REVERSE(#Stripes.S12_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S12_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S13_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S13_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S13_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S13_pdn,LEN(#Stripes.S13_pdn) - CHARINDEX('\',REVERSE(#Stripes.S13_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S13_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S14_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S14_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S14_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S14_pdn,LEN(#Stripes.S14_pdn) - CHARINDEX('\',REVERSE(#Stripes.S14_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S14_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S15_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S15_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S15_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S15_pdn,LEN(#Stripes.S15_pdn) - CHARINDEX('\',REVERSE(#Stripes.S15_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S15_pdn),1) + 1) END + '''' + END + -AND mf.physical_device_name NOT IN ('Nul', 'Nul:') -AND bs.type = 'L' -AND device_type IN (7,102,2) -) - -SELECT * INTO #CTE FROM CTE; -CREATE INDEX IDX_CTE ON #CTE(database_name); - --------------------------------------------------------------- --- CTE2 Optionally, striped backup file details --------------------------------------------------------------- -WITH Stripes -( - database_name, - backupmediasetid, - family_sequence_number, - last_lsn, - S2_pdn, - S3_pdn, - S4_pdn, - S5_pdn, - S6_pdn, - S7_pdn, - S8_pdn, - S9_pdn, - S10_pdn -) -AS -( -SELECT - Stripe1.database_name, - Stripe1.backupmediasetid, - Stripe1.family_sequence_number, - Stripe1.last_lsn, - Stripe2.physical_device_name AS S2_pdn, - Stripe3.physical_device_name AS S3_pdn, - Stripe4.physical_device_name AS S4_pdn, - Stripe5.physical_device_name AS S5_pdn, - Stripe6.physical_device_name AS S6_pdn, - Stripe7.physical_device_name AS S7_pdn, - Stripe8.physical_device_name AS S8_pdn, - Stripe9.physical_device_name AS S9_pdn, - Stripe10.physical_device_name AS S10_pdn -FROM #CTE AS Stripe1 - -LEFT OUTER JOIN #CTE AS Stripe2 - ON Stripe2.database_name = Stripe1.database_name - AND Stripe2.backupmediasetid = Stripe1.backupmediasetid - AND Stripe2.family_sequence_number = 2 - -LEFT OUTER JOIN #CTE AS Stripe3 - ON Stripe3.database_name = Stripe1.database_name - AND Stripe3.backupmediasetid = Stripe1.backupmediasetid - AND Stripe3.family_sequence_number = 3 - -LEFT OUTER JOIN #CTE AS Stripe4 - ON Stripe4.database_name = Stripe1.database_name - AND Stripe4.backupmediasetid = Stripe1.backupmediasetid - AND Stripe4.family_sequence_number = 4 - -LEFT OUTER JOIN #CTE AS Stripe5 - ON Stripe5.database_name = Stripe1.database_name - AND Stripe5.backupmediasetid = Stripe1.backupmediasetid - AND Stripe5.family_sequence_number = 5 - -LEFT OUTER JOIN #CTE AS Stripe6 - ON Stripe6.database_name = Stripe1.database_name - AND Stripe6.backupmediasetid = Stripe1.backupmediasetid - AND Stripe6.family_sequence_number = 6 - -LEFT OUTER JOIN #CTE AS Stripe7 - ON Stripe7.database_name = Stripe1.database_name - AND Stripe7.backupmediasetid = Stripe1.backupmediasetid - AND Stripe7.family_sequence_number = 7 - -LEFT OUTER JOIN #CTE AS Stripe8 - ON Stripe8.database_name = Stripe1.database_name - AND Stripe8.backupmediasetid = Stripe1.backupmediasetid - AND Stripe8.family_sequence_number = 8 - -LEFT OUTER JOIN #CTE AS Stripe9 - ON Stripe9.database_name = Stripe1.database_name - AND Stripe9.backupmediasetid = Stripe1.backupmediasetid - AND Stripe9.family_sequence_number = 9 - -LEFT OUTER JOIN #CTE AS Stripe10 - ON Stripe10.database_name = Stripe1.database_name - AND Stripe10.backupmediasetid = Stripe1.backupmediasetid - AND Stripe10.family_sequence_number = 10 -) - -SELECT * INTO #Stripes FROM Stripes; + --*************** + CASE ISNULL(#Stripes.S16_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S16_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S16_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S16_pdn,LEN(#Stripes.S16_pdn) - CHARINDEX('\',REVERSE(#Stripes.S16_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S16_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S17_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S17_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S17_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S17_pdn,LEN(#Stripes.S17_pdn) - CHARINDEX('\',REVERSE(#Stripes.S17_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S17_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S18_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S18_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S18_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S18_pdn,LEN(#Stripes.S18_pdn) - CHARINDEX('\',REVERSE(#Stripes.S18_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S18_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S19_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S19_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S19_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S19_pdn,LEN(#Stripes.S19_pdn) - CHARINDEX('\',REVERSE(#Stripes.S19_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S19_pdn),1) + 1) END + '''' + END + + + CASE ISNULL(#Stripes.S20_pdn,'') + WHEN '' THEN '' + ELSE ',' + CASE WHEN #Stripes.S20_pdn LIKE 'http%' THEN ' URL = N' ELSE ' DISK = N' END + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S20_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S20_pdn,LEN(#Stripes.S20_pdn) - CHARINDEX('\',REVERSE(#Stripes.S20_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S20_pdn),1) + 1) END + '''' + END + -CREATE INDEX IDX_Stripes ON #Stripes(database_name); - --------------------------------------------------------------- --- Results, T-SQL RESTORE commands, below are based on CTE's above --------------------------------------------------------------- - -SELECT - a.Command AS TSQL, - CONVERT(nvarchar(30), a.backupstartdate, 126) - AS BackupDate, - a.BackupDevice, - a.last_lsn, - a.database_name , - --ROW_NUMBER() OVER(ORDER BY database_name, Sequence, last_lsn) AS SortSequence - ROW_NUMBER() OVER(ORDER BY database_name, Sequence, a.backupstartdate) AS SortSequence -FROM -( - --------------------------------------------------------------- --- Most recent full backup --------------------------------------------------------------- - -SELECT - ';RESTORE DATABASE [' + CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN d.[name] ELSE @TargetDatabase_ END + ']' + SPACE(1) + - 'FROM DISK = N' + '''' + - CASE ISNULL(@FromFileFullUNC_,'Actual') - WHEN 'Actual' THEN #CTE.physical_device_name - ELSE @FromFileFullUNC_ + SUBSTRING(#CTE.physical_device_name,LEN(#CTE.physical_device_name) - CHARINDEX('\',REVERSE(#CTE.physical_device_name),1) + 2,CHARINDEX('\',REVERSE(#CTE.physical_device_name),1) + 1) - END + '''' + SPACE(1) + - - -- Striped backup files - CASE ISNULL(#Stripes.S2_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S2_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S2_pdn,LEN(#Stripes.S2_pdn) - CHARINDEX('\',REVERSE(#Stripes.S2_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S2_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S3_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S3_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S3_pdn,LEN(#Stripes.S3_pdn) - CHARINDEX('\',REVERSE(#Stripes.S3_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S3_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S4_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S4_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S4_pdn,LEN(#Stripes.S4_pdn) - CHARINDEX('\',REVERSE(#Stripes.S4_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S4_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S5_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S5_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S5_pdn,LEN(#Stripes.S5_pdn) - CHARINDEX('\',REVERSE(#Stripes.S5_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S5_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S6_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S6_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S6_pdn,LEN(#Stripes.S6_pdn) - CHARINDEX('\',REVERSE(#Stripes.S6_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S6_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S7_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S7_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S7_pdn,LEN(#Stripes.S7_pdn) - CHARINDEX('\',REVERSE(#Stripes.S7_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S7_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S8_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S8_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S8_pdn,LEN(#Stripes.S8_pdn) - CHARINDEX('\',REVERSE(#Stripes.S8_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S8_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S9_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S9_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S9_pdn,LEN(#Stripes.S9_pdn) - CHARINDEX('\',REVERSE(#Stripes.S9_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S9_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S10_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileFullUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S10_pdn ELSE @FromFileFullUNC_ + SUBSTRING(#Stripes.S10_pdn,LEN(#Stripes.S10_pdn) - CHARINDEX('\',REVERSE(#Stripes.S10_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S10_pdn),1) + 1) END + '''' - END + - - ' WITH ' + CASE ISNULL(@WithReplace_,0) WHEN 1 THEN 'REPLACE, ' ELSE '' END + 'FILE = ' + CAST(#CTE.position AS VARCHAR(5)) + ',' + - CASE #CTE.has_backup_checksums WHEN 1 THEN 'CHECKSUM, ' ELSE ' ' END + - - CASE @StandbyMode_ WHEN 0 THEN 'NORECOVERY,' ELSE 'STANDBY =N' + '''' + ISNULL(@FromFileFullUNC_,SUBSTRING(#CTE.physical_device_name,1,LEN(#CTE.physical_device_name) - CHARINDEX('\',REVERSE(#CTE.physical_device_name)))) + '\' + d.name + '_ROLLBACK_UNDO.bak ' + '''' + ',' END + SPACE(1) + - - 'STATS=10,' + SPACE(1) + - 'MOVE N' + '''' + x.LogicalName + '''' + ' TO ' + - '''' + - CASE ISNULL(@WithMoveDataFiles_,'Actual') - WHEN 'Actual' THEN x.PhysicalName - ELSE @WithMoveDataFiles_ + SUBSTRING(x.PhysicalName,LEN(x.PhysicalName) - CHARINDEX('\',REVERSE(x.PhysicalName),1) + 2,CHARINDEX('\',REVERSE(x.PhysicalName),1) + 1) - END + '''' + ',' + SPACE(1) + - - 'MOVE N' + '''' + y.LogicalName + '''' + ' TO ' + - '''' + - CASE ISNULL(@WithMoveLogFile_ ,'Actual') - WHEN 'Actual' THEN y.PhysicalName - ELSE @WithMoveLogFile_ + SUBSTRING(y.PhysicalName,LEN(y.PhysicalName) - CHARINDEX('\',REVERSE(y.PhysicalName),1) + 2,CHARINDEX('\',REVERSE(y.PhysicalName),1) + 1) - END + '''' AS Command, - 1 AS Sequence, - d.name AS database_name, - #CTE.physical_device_name AS BackupDevice, - #CTE.backupstartdate, - #CTE.backup_size, - #CTE.last_lsn - -FROM sys.databases d - -JOIN -( + --***************** + + CASE @StandbyMode_ WHEN 0 THEN ' WITH NORECOVERY,' ELSE ' WITH STANDBY =N' + '''' + ISNULL(@FromFileFullUNC_,SUBSTRING(#CTE.physical_device_name,1,LEN(#CTE.physical_device_name) - CHARINDEX('\',REVERSE(#CTE.physical_device_name)))) + '\' + d.name + '_' + REPLACE(REPLACE(SUBSTRING(CONVERT(VARCHAR(24),GETDATE(),127),12,12),':',''),'.','') + '_ROLLBACK_UNDO.bak ' + '''' + ',' END + SPACE(1) + + + CASE WHEN #CTE.physical_device_name LIKE 'http%' AND @BlobCredential_ IS NOT NULL THEN ' CREDENTIAL = ''' + @BlobCredential_ + ''', ' ELSE '' END + + + CASE #CTE.has_backup_checksums WHEN 1 THEN ' CHECKSUM, ' ELSE ' ' END + + + + 'FILE = ' + CAST(#CTE.position AS VARCHAR(5)) + + ' ,STOPAT = ' + '''' + CONVERT(VARCHAR(21),@StopAt_,120) + '''' + + AS Command, + 1000000 AS Sequence, + d.name AS database_name, + #CTE.physical_device_name AS BackupDevice, + #CTE.backupfinishdate, + #CTE.backup_size, + #CTE.first_lsn, + #CTE.last_lsn, + #CTE.fork_point_lsn, + #CTE.first_recovery_fork_guid, + #CTE.last_recovery_fork_guid + + + FROM sys.databases d + + INNER JOIN #CTE + ON #CTE.database_name = d.name + AND #CTE.family_sequence_number = 1 + + LEFT OUTER JOIN #Stripes + ON #Stripes.database_name = d.name + AND #Stripes.backupmediasetid = #CTE.backupmediasetid + AND #Stripes.last_lsn = #CTE.last_lsn + + LEFT OUTER JOIN + ( + SELECT database_name, MAX(last_lsn) last_lsn + FROM #CTE + WHERE [type] = 'I' + + GROUP BY database_name + ) after_diff + ON after_diff.database_name = #CTE.database_name + + LEFT OUTER JOIN #ForkPointsCount fpc + ON fpc.database_name = #CTE.database_name + + WHERE #CTE.[type] = 'L' + AND #CTE.family_sequence_number = 1 + AND #CTE.last_lsn >= CASE WHEN @ExcludeDiffAndLogBackups_ IN(0,4) THEN ISNULL(after_diff.last_lsn,'0') ELSE 0 END + AND @ExcludeDiffAndLogBackups_ IN (0,3,4) + + AND ISNULL(fpc.ForkPoints,0) < 2 + + -------------------------------------------------------------- + UNION -- SET SINGLE USER WITH ROLLBACK IMMEDIATE + -------------------------------------------------------------- SELECT - DB_NAME(mf.database_id) AS name - ,mf.Physical_Name AS PhysicalName - ,mf.Name AS LogicalName - FROM sys.master_files mf - WHERE type_desc = 'ROWS' - AND mf.file_id = 1 -) x - ON d.name = x.name - -JOIN -( + + 'BEGIN TRY ALTER DATABASE [' + CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN d.[name] ELSE @TargetDatabase_ END + ']' + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE END TRY BEGIN CATCH PRINT' + '''' + 'SET SINGLE USER FAILED' + '''' + ' END CATCH' AS Command, + 0 AS Sequence, + d.name AS database_name, + '' AS BackupDevice, + GETDATE() AS backupfinishdate, + #CTE.backup_size, + '0' AS first_lsn, + '0' AS last_lsn, + '0' AS fork_point_lsn , + '00000000-0000-0000-0000-000000000000' AS first_recovery_fork_guid, + '00000000-0000-0000-0000-000000000000' AS last_recovery_fork_guid + + FROM sys.databases d + + INNER JOIN #CTE + ON #CTE.database_name = d.name + + LEFT OUTER JOIN #ForkPointsCount fpc + ON fpc.database_name = #CTE.database_name + + WHERE #CTE.[type] = 'D' + AND @SetSingleUser_ = 1 + AND ISNULL(fpc.ForkPoints,0) < 2 + + -------------------------------------------------------------- + UNION -- Restore WITH RECOVERY + -------------------------------------------------------------- SELECT - DB_NAME(mf.database_id) AS name, type_desc - ,mf.Physical_Name PhysicalName - ,mf.Name AS LogicalName - FROM sys.master_files mf - WHERE type_desc = 'LOG' -) y - ON d.name = y.name - -LEFT OUTER JOIN #CTE - ON #CTE.database_name = d.name - AND #CTE.family_sequence_number = 1 - -JOIN #Stripes - ON #Stripes.database_name = d.name - AND #Stripes.backupmediasetid = #CTE.backupmediasetid - AND #Stripes.last_lsn = #CTE.last_lsn - -WHERE #CTE.[type] = 'D' -AND #CTE.family_sequence_number = 1 - --------------------------------------------------------------- --- Most recent differential backup --------------------------------------------------------------- -UNION - -SELECT - ';RESTORE DATABASE [' + CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN d.[name] ELSE @TargetDatabase_ END + ']' + SPACE(1) + - 'FROM DISK = N' + '''' + - CASE ISNULL(@FromFileDiffUNC_,'Actual') - WHEN 'Actual' THEN #CTE.physical_device_name - ELSE @FromFileDiffUNC_ + SUBSTRING(#CTE.physical_device_name,LEN(#CTE.physical_device_name) - CHARINDEX('\',REVERSE(#CTE.physical_device_name),1) + 2,CHARINDEX('\',REVERSE(#CTE.physical_device_name),1) + 1) - END + '''' + SPACE(1) + - - -- Striped backup files - CASE ISNULL(#Stripes.S2_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S2_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S2_pdn,LEN(#Stripes.S2_pdn) - CHARINDEX('\',REVERSE(#Stripes.S2_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S2_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S3_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S3_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S3_pdn,LEN(#Stripes.S3_pdn) - CHARINDEX('\',REVERSE(#Stripes.S3_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S3_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S4_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S4_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S4_pdn,LEN(#Stripes.S4_pdn) - CHARINDEX('\',REVERSE(#Stripes.S4_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S4_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S5_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S5_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S5_pdn,LEN(#Stripes.S5_pdn) - CHARINDEX('\',REVERSE(#Stripes.S5_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S5_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S6_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S6_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S6_pdn,LEN(#Stripes.S6_pdn) - CHARINDEX('\',REVERSE(#Stripes.S6_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S6_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S7_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S7_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S7_pdn,LEN(#Stripes.S7_pdn) - CHARINDEX('\',REVERSE(#Stripes.S7_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S7_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S8_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S8_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S8_pdn,LEN(#Stripes.S8_pdn) - CHARINDEX('\',REVERSE(#Stripes.S8_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S8_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S9_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S9_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S9_pdn,LEN(#Stripes.S9_pdn) - CHARINDEX('\',REVERSE(#Stripes.S9_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S9_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S10_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileDiffUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S10_pdn ELSE @FromFileDiffUNC_ + SUBSTRING(#Stripes.S10_pdn,LEN(#Stripes.S10_pdn) - CHARINDEX('\',REVERSE(#Stripes.S10_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S10_pdn),1) + 1) END + '''' - END + - - ' WITH FILE = ' + CAST(#CTE.position AS VARCHAR(5)) + ',' + - CASE #CTE.has_backup_checksums WHEN 1 THEN 'CHECKSUM, ' ELSE ' ' END + - - CASE @StandbyMode_ WHEN 0 THEN 'NORECOVERY,' ELSE 'STANDBY =N' + '''' + ISNULL(@FromFileFullUNC_,SUBSTRING(#CTE.physical_device_name,1,LEN(#CTE.physical_device_name) - CHARINDEX('\',REVERSE(#CTE.physical_device_name)))) + '\' + d.name + '_ROLLBACK_UNDO.bak ' + '''' + ',' END + SPACE(1) + - - 'STATS=10,' + SPACE(1) + - 'MOVE N' + '''' + x.LogicalName + '''' + ' TO ' + - '''' + - CASE ISNULL(@WithMoveDataFiles_,'Actual') - WHEN 'Actual' THEN x.PhysicalName - ELSE @WithMoveDataFiles_ + SUBSTRING(x.PhysicalName,LEN(x.PhysicalName) - CHARINDEX('\',REVERSE(x.PhysicalName),1) + 2,CHARINDEX('\',REVERSE(x.PhysicalName),1) + 1) - END + '''' + ',' + SPACE(1) + - - 'MOVE N' + '''' + y.LogicalName + '''' + ' TO ' + - '''' + - CASE ISNULL(@WithMoveLogFile_ ,'Actual') - WHEN 'Actual' THEN y.PhysicalName - ELSE @WithMoveLogFile_ + SUBSTRING(y.PhysicalName,LEN(y.PhysicalName) - CHARINDEX('\',REVERSE(y.PhysicalName),1) + 2,CHARINDEX('\',REVERSE(y.PhysicalName),1) + 1) - END + '''' AS Command, - 32769/2 AS Sequence, - d.name AS database_name, - #CTE.physical_device_name AS BackupDevice, - #CTE.backupstartdate, - #CTE.backup_size, - #CTE.last_lsn - -FROM sys.databases d - -JOIN #CTE -ON #CTE.database_name = d.name -AND #CTE.family_sequence_number = 1 - -LEFT OUTER JOIN #Stripes -ON #Stripes.database_name = d.name -AND #Stripes.backupmediasetid = #CTE.backupmediasetid -AND #Stripes.last_lsn = #CTE.last_lsn - -INNER JOIN -( + + 'RESTORE DATABASE [' + CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN d.[name] ELSE @TargetDatabase_ END + ']' + SPACE(1) + 'WITH RECOVERY' AS Command, + 1000001 AS Sequence, + d.name AS database_name, + '' AS BackupDevice, + GETDATE() AS backupfinishdate, + #CTE.backup_size, + #CTE.first_lsn, + '999999999999999999997' AS last_lsn, + #CTE.fork_point_lsn , + '00000000-0000-0000-0000-000000000000' AS first_recovery_fork_guid, + '00000000-0000-0000-0000-000000000000' AS last_recovery_fork_guid + + FROM sys.databases d + + INNER JOIN #CTE + ON #CTE.database_name = d.name + + LEFT OUTER JOIN #ForkPointsCount fpc + ON fpc.database_name = #CTE.database_name + + WHERE #CTE.[type] = 'D' + AND @WithRecovery_ = 1 + AND ISNULL(fpc.ForkPoints,0) < 2 + + -------------------------------------------------------------- + UNION -- CHECKDB + -------------------------------------------------------------- SELECT - DB_NAME(mf.database_id) AS name - ,mf.Physical_Name AS PhysicalName - ,mf.Name AS LogicalName - FROM sys.master_files mf - WHERE type_desc = 'ROWS' - AND mf.file_id = 1 -) x - ON d.name = x.name - -JOIN -( + + 'DBCC CHECKDB(' + '''' + CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN d.[name] ELSE @TargetDatabase_ END + '''' + ') WITH NO_INFOMSGS, ALL_ERRORMSGS' AS Command, + 1000002 AS Sequence, + d.name AS database_name, + '' AS BackupDevice, + DATEADD(minute,1,GETDATE()) AS backupfinishdate, + #CTE.backup_size, + #CTE.first_lsn, + '999999999999999999998' AS last_lsn, + #CTE.fork_point_lsn, + '00000000-0000-0000-0000-000000000000' AS first_recovery_fork_guid, + '00000000-0000-0000-0000-000000000000' AS last_recovery_fork_guid + + FROM sys.databases d + + INNER JOIN #CTE + ON #CTE.database_name = d.name + + LEFT OUTER JOIN #ForkPointsCount fpc + ON fpc.database_name = #CTE.database_name + + WHERE #CTE.[type] = 'D' + AND @WithCHECKDB_ = 1 + AND @WithRecovery_ = 1 + AND ISNULL(fpc.ForkPoints,0) < 2 + + -------------------------------------------------------------- + UNION -- Drop database after restore + -------------------------------------------------------------- SELECT - DB_NAME(mf.database_id) AS name, type_desc - ,mf.Physical_Name PhysicalName - ,mf.Name AS LogicalName - FROM sys.master_files mf - WHERE type_desc = 'LOG' -) y - ON d.name = y.name - -WHERE #CTE.[type] = 'I' -AND #CTE.family_sequence_number = 1 - --------------------------------------------------------------- -UNION -- Log backups taken since most recent full or diff --------------------------------------------------------------- - -SELECT - ';BEGIN TRY RESTORE LOG [' + CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN d.[name] ELSE @TargetDatabase_ END + ']' + SPACE(1) + - 'FROM DISK = N' + '''' + --#CTE.physical_device_name + '''' + SPACE(1) + - CASE ISNULL(@FromFileLogUNC_,'Actual') - WHEN 'Actual' THEN #CTE.physical_device_name - ELSE @FromFileLogUNC_ + SUBSTRING(#CTE.physical_device_name,LEN(#CTE.physical_device_name) - CHARINDEX('\',REVERSE(#CTE.physical_device_name),1) + 2,CHARINDEX('\',REVERSE(#CTE.physical_device_name),1) + 1) - END + '''' + - - -- Striped backup files - CASE ISNULL(#Stripes.S2_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S2_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S2_pdn,LEN(#Stripes.S2_pdn) - CHARINDEX('\',REVERSE(#Stripes.S2_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S2_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S3_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S3_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S3_pdn,LEN(#Stripes.S3_pdn) - CHARINDEX('\',REVERSE(#Stripes.S3_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S3_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S4_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S4_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S4_pdn,LEN(#Stripes.S4_pdn) - CHARINDEX('\',REVERSE(#Stripes.S4_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S4_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S5_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S5_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S5_pdn,LEN(#Stripes.S5_pdn) - CHARINDEX('\',REVERSE(#Stripes.S5_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S5_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S6_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S6_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S6_pdn,LEN(#Stripes.S6_pdn) - CHARINDEX('\',REVERSE(#Stripes.S6_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S6_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S7_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S7_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S7_pdn,LEN(#Stripes.S7_pdn) - CHARINDEX('\',REVERSE(#Stripes.S7_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S7_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S8_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S8_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S8_pdn,LEN(#Stripes.S8_pdn) - CHARINDEX('\',REVERSE(#Stripes.S8_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S8_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S9_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S9_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S9_pdn,LEN(#Stripes.S9_pdn) - CHARINDEX('\',REVERSE(#Stripes.S9_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S9_pdn),1) + 1) END + '''' - END + - - CASE ISNULL(#Stripes.S10_pdn,'') - WHEN '' THEN '' - ELSE ', DISK = N' + '''' + CASE ISNULL(@FromFileLogUNC_,'Actual') WHEN 'Actual' THEN #Stripes.S10_pdn ELSE @FromFileLogUNC_ + SUBSTRING(#Stripes.S10_pdn,LEN(#Stripes.S10_pdn) - CHARINDEX('\',REVERSE(#Stripes.S10_pdn),1) + 2,CHARINDEX('\',REVERSE(#Stripes.S10_pdn),1) + 1) END + '''' - END + - - CASE @StandbyMode_ WHEN 0 THEN ' WITH NORECOVERY,' ELSE ' WITH STANDBY =N' + '''' + ISNULL(@FromFileFullUNC_,SUBSTRING(#CTE.physical_device_name,1,LEN(#CTE.physical_device_name) - CHARINDEX('\',REVERSE(#CTE.physical_device_name)))) + '\' + d.name + '_ROLLBACK_UNDO.bak ' + '''' + ',' END + SPACE(1) + - - CASE #CTE.has_backup_checksums WHEN 1 THEN ' CHECKSUM, ' ELSE ' ' END + - - + 'FILE = ' + CAST(#CTE.position AS VARCHAR(5)) + - ' ,STOPAT = ' + '''' + CONVERT(VARCHAR(21),@StopAt_,120) + '''' + - ' ,MOVE N' + '''' + x2.LogicalName + '''' + ' TO ' + - '''' + - CASE ISNULL(@WithMoveDataFiles_,'Actual') - WHEN 'Actual' THEN x2.PhysicalName - ELSE @WithMoveDataFiles_ + SUBSTRING(x2.PhysicalName,LEN(x2.PhysicalName) - CHARINDEX('\',REVERSE(x2.PhysicalName),1) + 2,CHARINDEX('\',REVERSE(x2.PhysicalName),1) + 1) - END + '''' + ',' + SPACE(1) + - - ' MOVE N' + '''' + y1.LogicalName + '''' + ' TO ' + - '''' + - CASE ISNULL(@WithMoveLogFile_ ,'Actual') - WHEN 'Actual' THEN y1.PhysicalName - ELSE @WithMoveLogFile_ + SUBSTRING(y1.PhysicalName,LEN(y1.PhysicalName) - CHARINDEX('\',REVERSE(y1.PhysicalName),1) + 2,CHARINDEX('\',REVERSE(y1.PhysicalName),1) + 1) - END + '''' + 'END TRY BEGIN CATCH PRINT ' + '''' + 'Transaction Log File Restore Exclusion - Check Recovery Sequence.' + '''' + ' END CATCH;' AS Command, - 32769 AS Sequence, - d.name AS database_name, - #CTE.physical_device_name AS BackupDevice, - #CTE.backupstartdate, - #CTE.backup_size, - #CTE.last_lsn - -FROM sys.databases d - -INNER JOIN -( + + -- Comment out all commands if multiple forking points exist + --CASE WHEN @CommentOut = 1 THEN ' -- Multipe backup fork points detected, command suppressed -- ' ELSE '' END + + + 'DROP DATABASE [' + CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN d.[name] ELSE @TargetDatabase_ END + ']' + SPACE(1) AS Command, + 1000003 AS Sequence, + d.name AS database_name, + '' AS BackupDevice, + GETDATE() AS backupfinishdate, + #CTE.backup_size, + #CTE.first_lsn, + '999999999999999999999' AS last_lsn, + #CTE.fork_point_lsn, + '00000000-0000-0000-0000-000000000000' AS first_recovery_fork_guid, + '00000000-0000-0000-0000-000000000000' AS last_recovery_fork_guid + + + + FROM sys.databases d + + INNER JOIN #CTE + ON #CTE.database_name = d.name + + LEFT OUTER JOIN #ForkPointsCount fpc + ON fpc.database_name = #CTE.database_name + + WHERE #CTE.[type] = 'D' + AND @DropDatabaseAfterRestore_ = 1 + AND ISNULL(fpc.ForkPoints,0) < 2 + + -------------------------------------------------------------- + UNION -- RAISERROR suppress restore when multiple forkpoints exist + -------------------------------------------------------------- SELECT - DB_NAME(mf.database_id) AS name - ,mf.Physical_Name AS PhysicalName - ,mf.Name AS LogicalName - FROM sys.master_files mf - WHERE type_desc = 'ROWS' - AND mf.file_id = 1 -) x2 -ON d.name = x2.name - -INNER JOIN -( + + 'RAISERROR (' + '''' + 'Multiple restores per performed between the selected full backup and stop at time for database ' + CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN d.[name] ELSE @TargetDatabase_ END + ' - Restore Gene processing aborted.' + '''' + ',0,0);' + + SPACE(1) AS Command, + 1 AS Sequence, + d.name AS database_name, + '' AS BackupDevice, + GETDATE() AS backupfinishdate, + #CTE.backup_size, + '000000000000000000000' AS first_lsn, + '999999999999999999999' AS last_lsn, + #CTE.fork_point_lsn, + '00000000-0000-0000-0000-000000000000' AS first_recovery_fork_guid, + '00000000-0000-0000-0000-000000000000' AS last_recovery_fork_guid + + FROM sys.databases d + + INNER JOIN #CTE + ON #CTE.database_name = d.name + + LEFT OUTER JOIN #ForkPointsCount fpc + ON fpc.database_name = #CTE.database_name + + WHERE #CTE.[type] = 'D' + AND ISNULL(fpc.ForkPoints,0) > 1 + + -------------------------------------------------------------- + UNION -- WITH MOVE secondary data files, allows for up to 32769/2 file groups + -------------------------------------------------------------- + SELECT - DB_NAME(mf.database_id) AS name, type_desc - ,mf.Physical_Name PhysicalName - ,mf.Name AS LogicalName - FROM sys.master_files mf - WHERE type_desc = 'LOG' -) y1 - ON d.name = y1.name - -INNER JOIN #CTE - ON #CTE.database_name = d.name - AND #CTE.family_sequence_number = 1 - -LEFT OUTER JOIN #Stripes - ON #Stripes.database_name = d.name - AND #Stripes.backupmediasetid = #CTE.backupmediasetid - AND #Stripes.last_lsn = #CTE.last_lsn - -LEFT OUTER JOIN -( - SELECT database_name, MAX(last_lsn) last_lsn - FROM #CTE - WHERE [type] = 'I' - GROUP BY database_name -) after_diff - ON after_diff.database_name = #CTE.database_name - -WHERE #CTE.[type] = 'L' -AND #CTE.family_sequence_number = 1 -AND #CTE.last_lsn > ISNULL(after_diff.last_lsn,'0') - --------------------------------------------------------------- -UNION -- Declare @msg_ variable --------------------------------------------------------------- -SELECT --- '; DECLARE @msg_' + d.name + ' VARCHAR(1000)' AS Command, - ';DECLARE @msg_' + REPLACE(REPLACE(REPLACE(d.name,' ','_'),'.','_'),'-','_') + ' VARCHAR(1000)' AS Command, - 0 AS Sequence, - d.name AS database_name, - '' AS BackupDevice, - GETDATE() AS backupstartdate, - #CTE.backup_size, - '0' AS last_lsn - -FROM sys.databases d - -JOIN #CTE -ON #CTE.database_name = d.name - -WHERE #CTE.[type] = 'D' -AND @LogShippingVariableDeclare_ = 1 - --------------------------------------------------------------- -UNION -- Restore WITH RECOVERY --------------------------------------------------------------- -SELECT - ';SET @msg_' + REPLACE(REPLACE(REPLACE(d.name,' ','_'),'.','_'),'-','_') + ' = ' + '''' + @Log_Reference_ + '''' + '; RAISERROR (@msg_' + REPLACE(REPLACE(REPLACE(d.name,' ','_'),'.','_'),'-','_') + ',0,0) WITH LOG' + ';RESTORE DATABASE [' + CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN d.[name] ELSE @TargetDatabase_ END + ']' + SPACE(1) + 'WITH RECOVERY' AS Command, - 32771 AS Sequence, - d.name AS database_name, - '' AS BackupDevice, - GETDATE() AS backupstartdate, - #CTE.backup_size, - '999999999999999999998' AS last_lsn - -FROM sys.databases d - -JOIN #CTE -ON #CTE.database_name = d.name - -WHERE #CTE.[type] = 'D' -AND @WithRecovery_ = 1 - --------------------------------------------------------------- -UNION -- CHECKDB --------------------------------------------------------------- -SELECT - ';SET @msg_' + REPLACE(REPLACE(REPLACE(d.name,' ','_'),'.','_'),'-','_') + ' = ' + '''' + @Log_Reference_ + '''' + '; RAISERROR (@msg_' + REPLACE(REPLACE(REPLACE(d.name,' ','_'),'.','_'),'-','_') + ',0,0) WITH LOG' + ';DBCC CHECKDB(' + '''' + CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN d.[name] ELSE @TargetDatabase_ END + '''' + ') WITH NO_INFOMSGS, ALL_ERRORMSGS' AS Command, - 32772 AS Sequence, - d.name AS database_name, - '' AS BackupDevice, - DATEADD(minute,1,GETDATE()) AS backupstartdate, - #CTE.backup_size, - '999999999999999999999' AS last_lsn - -FROM sys.databases d - -JOIN #CTE -ON #CTE.database_name = d.name - -WHERE #CTE.[type] = 'D' -AND @WithCHECKDB_ = 1 -AND @WithRecovery_ = 1 - --------------------------------------------------------------- -UNION -- WITH MOVE secondary data files, allows for up to 32769/2 file groups --------------------------------------------------------------- -SELECT - ', MOVE N' + '''' + b.name + '''' + ' TO N' + '''' + - CASE ISNULL(@WithMoveDataFiles_,'Actual') - WHEN 'Actual' THEN b.physical_name - ELSE @WithMoveDataFiles_ + SUBSTRING(b.Physical_Name,LEN(b.Physical_Name) - CHARINDEX('\',REVERSE(b.Physical_Name),1) + 2,CHARINDEX('\',REVERSE(b.Physical_Name),1) + 1) - END + '''', - b.file_id AS Sequence, - DB_NAME(b.database_id) AS database_name, - 'SECONDARY FULL' AS BackupDevice, - #CTE.backupstartdate, - #CTE.backup_size, - #CTE.last_lsn - -FROM sys.master_files b -INNER JOIN #CTE -ON #CTE.database_name = DB_NAME(b.database_id) - -WHERE #CTE.[type] = 'D' -AND b.type_desc = 'ROWS' -AND b.file_id > 2 -AND @WithMoveDataFiles_ IS NOT NULL --------------------------------------------------------------- -) a --------------------------------------------------------------- - -WHERE a.database_name = ISNULL(@Database_,a.database_name) -AND (@IncludeSystemDBs_ = 1 OR a.database_name NOT IN('master','model','msdb')) -AND a.last_lsn > @LogShippingLastLSN_ - -ORDER BY - database_name, - Sequence, - --last_lsn - backupstartdate - -END; + -- Comment out all commands if multiple forking points exist + --CASE WHEN @CommentOut = 1 THEN ' -- Multipe backup fork points detected, command suppressed -- ' ELSE '' END + + + ' ,MOVE N' + '''' + b.name + '''' + ' TO N' + '''' + + + CASE b.type_desc + + WHEN 'ROWS' THEN + CASE ISNULL(@WithMoveDataFiles_,'Actual') + WHEN 'Actual' THEN CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN b.Physical_Name ELSE SUBSTRING(b.Physical_Name,1,CASE CHARINDEX('.',b.Physical_Name) WHEN 0 THEN LEN(b.Physical_Name) ELSE CHARINDEX('.',b.Physical_Name) - 1 END) + '_' + @TargetDatabase_ + '.ndf' END + ELSE CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN @WithMoveDataFiles_ + SUBSTRING(b.Physical_Name,LEN(b.Physical_Name) - CHARINDEX('\',REVERSE(b.Physical_Name),1) + 2,CHARINDEX('\',REVERSE(b.Physical_Name),1) + 1) + ELSE @WithMoveDataFiles_ + SUBSTRING (b.Physical_Name, (LEN(b.Physical_Name)-CHARINDEX('\',REVERSE(b.Physical_Name)) + 2),CHARINDEX('\',REVERSE(b.Physical_Name)) - 1 - CHARINDEX('.',REVERSE(b.Physical_Name))) + '_' + @TargetDatabase_ + '.ndf' END + END + + WHEN 'FILESTREAM' THEN + CASE ISNULL(@WithMoveFileStreamFile_,'Actual') + WHEN 'Actual' THEN CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN b.Physical_Name ELSE SUBSTRING(b.Physical_Name,1,CASE CHARINDEX('.',b.Physical_Name) WHEN 0 THEN LEN(b.Physical_Name) ELSE CHARINDEX('.',b.Physical_Name) - 1 END) + '_' + @TargetDatabase_ END + ELSE CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN @WithMoveFileStreamFile_ + SUBSTRING(b.Physical_Name,LEN(b.Physical_Name) - CHARINDEX('\',REVERSE(b.Physical_Name),1) + 2,CHARINDEX('\',REVERSE(b.Physical_Name),1) + 1) + ELSE @WithMoveFileStreamFile_ + SUBSTRING (b.Physical_Name, (LEN(b.Physical_Name)-CHARINDEX('\',REVERSE(b.Physical_Name)) + 2),CHARINDEX('\',REVERSE(b.Physical_Name)) - 1 - CHARINDEX('.',REVERSE(b.Physical_Name))) + '_' + @TargetDatabase_ END + END + + WHEN 'LOG' THEN + CASE ISNULL(@WithMoveLogFile_,'Actual') + WHEN 'Actual' THEN CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN b.Physical_Name ELSE SUBSTRING(b.Physical_Name,1,CASE CHARINDEX('.',b.Physical_Name) WHEN 0 THEN LEN(b.Physical_Name) ELSE CHARINDEX('.',b.Physical_Name) - 1 END) + '_' + @TargetDatabase_ + '.ldf' END + ELSE CASE ISNULL(@TargetDatabase_,'') WHEN '' THEN @WithMoveLogFile_ + SUBSTRING(b.Physical_Name,LEN(b.Physical_Name) - CHARINDEX('\',REVERSE(b.Physical_Name),1) + 2,CHARINDEX('\',REVERSE(b.Physical_Name),1) + 1) + ELSE @WithMoveLogFile_ + SUBSTRING (b.Physical_Name, (LEN(b.Physical_Name)-CHARINDEX('\',REVERSE(b.Physical_Name)) + 2),CHARINDEX('\',REVERSE(b.Physical_Name)) - 1 - CHARINDEX('.',REVERSE(b.Physical_Name))) + '_' + @TargetDatabase_ + '.ldf' END + + END + + END + + + '''', + b.file_id AS Sequence, + DB_NAME(b.database_id) AS database_name, + 'SECONDARY FULL' AS BackupDevice, + #CTE.backupfinishdate, + #CTE.backup_size, + #CTE.first_lsn, + #CTE.last_lsn, + #CTE.fork_point_lsn, + #CTE.first_recovery_fork_guid, + #CTE.last_recovery_fork_guid + + FROM sys.master_files b + INNER JOIN #CTE + ON #CTE.database_name = DB_NAME(b.database_id) + + LEFT OUTER JOIN #ForkPointsCount fpc + ON fpc.database_name = #CTE.database_name + + WHERE #CTE.[type] = 'D' + AND b.type_desc IN ('ROWS','FILESTREAM','LOG') + AND b.file_id > 2 + AND ISNULL(fpc.ForkPoints,0) < 2 + + -------------------------------------------------------------- + ) a + LEFT OUTER JOIN #tmpDatabases b + ON a.database_name = b.DatabaseName + -------------------------------------------------------------- + + WHERE (@Database_ IS NULL OR b.Selected = 1 OR @Database_ = a.database_name) + AND (@IncludeSystemDBs_ = 1 OR a.database_name NOT IN('master','model','msdb')) + AND a.last_lsn >= @LogShippingLastLSN_; + + CREATE INDEX IDX_RestoreGeneResults ON #RestoreGeneResults (database_name,SortSequence,BackupDate); + + -------------------------------------------------------------- + -- Result Set + IF @SuppressWithMove_ = 1 + BEGIN + IF @RestoreScriptOnly_ = 0 + BEGIN + + SELECT x4.TSQL, x4.BackupDate, x4.BackupDevice, x4.first_lsn, x4.last_lsn, x4.fork_point_lsn, x4.first_recovery_fork_guid, x4.last_recovery_fork_guid, x4.database_name, x4.SortSequence + FROM #RestoreGeneResults x4 + WHERE ISNULL(x4.BackupDevice,'') <> 'SECONDARY FULL' + ORDER BY + x4.database_name, + x4.SortSequence, + x4.BackupDate + END + ELSE + BEGIN + SELECT x4.TSQL AS [--TSQL] + FROM #RestoreGeneResults x4 + WHERE ISNULL(x4.BackupDevice,'') <> 'SECONDARY FULL' + ORDER BY + x4.database_name, + x4.SortSequence, + x4.BackupDate + END + END + ELSE + BEGIN + IF @PivotWithMove_ = 1 + BEGIN + + IF @RestoreScriptOnly_ = 0 + BEGIN + SELECT + x4.TSQL, x4.BackupDate, x4.BackupDevice, x4.first_lsn, x4.last_lsn, x4.fork_point_lsn, x4.first_recovery_fork_guid, x4.last_recovery_fork_guid, x4.database_name, x4.SortSequence + FROM #RestoreGeneResults x4 + ORDER BY + x4.database_name, + x4.SortSequence, + x4.BackupDate + END + ELSE + BEGIN + SELECT + x4.TSQL AS [--TSQL] + FROM #RestoreGeneResults x4 + ORDER BY + x4.database_name, + x4.SortSequence, + x4.BackupDate + END + + END + ELSE + BEGIN + IF @RestoreScriptOnly_ = 0 + BEGIN + WITH WithMoves AS + ( + SELECT + last_lsn, + STUFF((SELECT ' ' + TSQL FROM #RestoreGeneResults x3 WHERE x3.last_lsn = x2.last_lsn AND ISNULL(x3.BackupDevice,'') = 'SECONDARY FULL' ORDER BY x3.SortSequence FOR XML PATH, TYPE).value('.[1]', 'nvarchar(max)'), 1,1,'') AS WithoveCmds + FROM #RestoreGeneResults x2 + GROUP BY last_lsn + ) + + SELECT + CASE @SuppressWithMove_ WHEN 0 THEN CASE ISNULL(x5.WithoveCmds,'') WHEN '' THEN x4.TSQL ELSE x4.TSQL + ' ' + x5.WithoveCmds END + ELSE x4.TSQL + END AS TSQL, + x4.BackupDate, x4.BackupDevice, x4.first_lsn, x4.last_lsn, x4.fork_point_lsn, x4.first_recovery_fork_guid, x4.last_recovery_fork_guid, x4.database_name, x4.SortSequence + FROM #RestoreGeneResults x4 + LEFT OUTER JOIN WithMoves x5 + ON x4.last_lsn = x5.last_lsn + WHERE ISNULL(x4.BackupDevice,'') <> 'SECONDARY FULL' + ORDER BY + x4.database_name, + x4.SortSequence, + x4.BackupDate + END + ELSE + BEGIN + WITH WithMoves AS + ( + SELECT + last_lsn, + STUFF((SELECT ' ' + TSQL FROM #RestoreGeneResults x3 WHERE x3.last_lsn = x2.last_lsn AND ISNULL(x3.BackupDevice,'') = 'SECONDARY FULL' ORDER BY x3.SortSequence FOR XML PATH, TYPE).value('.[1]', 'nvarchar(max)'), 1,1,'') AS WithoveCmds + FROM #RestoreGeneResults x2 + GROUP BY last_lsn + ) + + SELECT + CASE @SuppressWithMove_ WHEN 0 THEN CASE ISNULL(x5.WithoveCmds,'') WHEN '' THEN x4.TSQL ELSE x4.TSQL + ' ' + x5.WithoveCmds END + ELSE x4.TSQL + END AS [--TSQL] + FROM #RestoreGeneResults x4 + LEFT OUTER JOIN WithMoves x5 + ON x4.last_lsn = x5.last_lsn + WHERE ISNULL(x4.BackupDevice,'') <> 'SECONDARY FULL' + ORDER BY + x4.database_name, + x4.SortSequence, + x4.BackupDate + END + END + END +END GO From 6bb99b2a260e66f2b689204fbf9b80e040f70309 Mon Sep 17 00:00:00 2001 From: Konstantin Taranov Date: Tue, 11 Jul 2023 16:50:44 +0300 Subject: [PATCH 05/39] Add SSMS Object Explorer Menu addin --- SSMS/SSMS_Addins.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/SSMS/SSMS_Addins.md b/SSMS/SSMS_Addins.md index eb39238d..4d2ae8aa 100644 --- a/SSMS/SSMS_Addins.md +++ b/SSMS/SSMS_Addins.md @@ -1,5 +1,5 @@ # SQL Server Management Studio add-ins -Complete list of useful and must have add-ins for SQL Server Management Studio - **36** SSMS add-ins +Complete list of useful and must have add-ins for SQL Server Management Studio - **37** SSMS add-ins | Name | Download page | Release Date | Support SSMS Version | Developer | Free version | Price | |-------------------------------------------------------|-------------------------------|--------------|:---------------------|----------------------|--------------|------:| @@ -40,6 +40,8 @@ Complete list of useful and must have add-ins for SQL Server Management Studio - | [SSMS Schema Folders](#ssms-schema-folders) | [SSMS Schema Folders] | 2018-10-06 | 2012-2018 | Nicholas Ross | Yes | No | | [Statistics Reporter](#statistics-reporter) | [Statistics Reporter] | 2019-04-17 | 2014-2018 | Analytics Bar | Yes | No | | [SSMS Lizard](#ssms-lizard) | [SSMS Lizard] | 2020-06-15 | 2018-2018 | Lizard Labs Software | Yes | No | +| [SSMS Object Explorer Menu](#ssms-lizard) | [SSMS Object Explorer Menu] | 2023-07-10 | 2018-2022 | +Daniel Brink | Yes | No | @@ -656,6 +658,18 @@ SSMS Lizard extends SQL Server Management Studio with a number of new features n - Quickly attach the query results to an e-mail, FTP or even Google Drive with a single click of a button; and more. + +## SSMS Object Explorer Menu +Download page: [SSMS Object Explorer Menu]
+Release date: 2023-07-10
+Support Version: 2018-2023
+Developer: Daniel Brink
+Free version: Yes
+Price: No + +SSMS extension for adding custom menu items to the Object Explorer's right-click context menu. + + [SSMSBoost]:http://www.ssmsboost.com/ [SqlSmash]:http://www.sqlsmash.com/ [Red Gate SQL Code Guard]:https://www.red-gate.com/products/sql-development/sql-code-guard/ @@ -694,6 +708,7 @@ SSMS Lizard extends SQL Server Management Studio with a number of new features n [Michel Max - SSMS Tools]:https://sourceforge.net/projects/michelmaxssmstools2017/ [SSMS Schema Folders]:https://github.com/nicholas-ross/SSMS-Schema-Folders [Statistics Reporter]:https://analyticsbar.com/blog/statistics-reporter-ssms-extension/ +[SSMS Object Explorer Menu]:https://github.com/brink-daniel/ssms-object-explorer-menu [SQL_Search Download]:https://download.red-gate.com/SQL_Search.exe [Apex SQL Search Download]:https://www.apexsql.com/zips/ApexSQLSearch.exe From 5ea3f8628ad57f64a909201cb4dd1f2f39816a72 Mon Sep 17 00:00:00 2001 From: denver-ua <143743067+denver-ua@users.noreply.github.com> Date: Thu, 31 Aug 2023 20:53:03 +0300 Subject: [PATCH 06/39] Update SQL Server Trace Flag.md Added info on TF 9265 --- SQL Server Trace Flag.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/SQL Server Trace Flag.md b/SQL Server Trace Flag.md index 197ffdc8..bebf58d5 100644 --- a/SQL Server Trace Flag.md +++ b/SQL Server Trace Flag.md @@ -4787,6 +4787,15 @@ Link: [New Undocumented Trace Flags]
Scope: ? + +#### Trace Flag: 9265 +**Undocumented trace flag**
+Function: MS engineering team has decided to generate a DUMP from SQL 2019+ every time a “PLAN cannot be generated”. Once a Dump freezes connections during the generation, the cluster will probably lost the connectivity to the cluster and the AG can be down/failover if it has automatic failover configured. The mitigation for this issue (avoid DUMP generation) is to enable TF Trace Flag 9265 on Startup. +Once TF 9265 is enabled, SQL Server stops generating DUMP on the “PLAN cannot be generated” error but only writes a message to ERRORLOG file (Internal Query Processor Error: The query processor could not produce a query plan. For more information, contact Customer Support Services). +
+Link: None + + #### Trace Flag: 9268 Function: SQL 8 - When SQL Server runs a parameterized query that contains several IN clauses, each with a large number of values, SQL Server may return the following error message after a minute or more of high CPU utilization: KB 325658. Server: Msg 8623, Level 16, State 1. Internal Query Processor Error: The query processor could not produce a query plan. Contact your primary support provider for more information.
From e0a6cc9e50349c18c7ff3c03ed9c687c16be1c0a Mon Sep 17 00:00:00 2001 From: Michael <9100146+MikeTV@users.noreply.github.com> Date: Thu, 7 Sep 2023 10:04:18 -0500 Subject: [PATCH 07/39] feat: Add SQL Shades Added SQL Shades, a true dark mode add-in. Also updated VersionSQL's company name and price, which has changed, and fixed another add-in's anchor tag. --- SSMS/SSMS_Addins.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/SSMS/SSMS_Addins.md b/SSMS/SSMS_Addins.md index 4d2ae8aa..0912328d 100644 --- a/SSMS/SSMS_Addins.md +++ b/SSMS/SSMS_Addins.md @@ -34,14 +34,14 @@ Complete list of useful and must have add-ins for SQL Server Management Studio - | [Tabs Studio](#tabs-studio) | [Tabs Studio] | 2017-08-24 | 2012-2017 | Vlasov Studio | No | $49 | | [Workload Addin](#workload-addin) | [Workload Addin] | 2017-02-07 | 2008-2012 | Tomáš Bauer | Yes | No | | [SQL Server Diagnostics](#sql-server-diagnostics) | [SQL Server Diagnostics] | 2017-06-22 | 2016-2017 | Microsoft | Yes | No | -| [VersionSQL](#versionsql) | [VersionSQL] | 2017-02-16 | 2012-2017 | VersionSQL | Yes | $149 | +| [VersionSQL](#versionsql) | [VersionSQL] | 2017-02-16 | 2012-2017 | Wrism Innovations | Yes | $199 | | [Spotlight Tuning Pack](#spotlight-tuning-pack) | [Spotlight Tuning Pack] | 2018-06-01 | 2012-2017 | Quest Software Inc | Yes | $180 | | [Michel Max - SSMS Tools](#michel-max) | [Michel Max - SSMS Tools] | 2018-11-16 | 2012-2018 | Michel Max | Yes | No | | [SSMS Schema Folders](#ssms-schema-folders) | [SSMS Schema Folders] | 2018-10-06 | 2012-2018 | Nicholas Ross | Yes | No | | [Statistics Reporter](#statistics-reporter) | [Statistics Reporter] | 2019-04-17 | 2014-2018 | Analytics Bar | Yes | No | | [SSMS Lizard](#ssms-lizard) | [SSMS Lizard] | 2020-06-15 | 2018-2018 | Lizard Labs Software | Yes | No | -| [SSMS Object Explorer Menu](#ssms-lizard) | [SSMS Object Explorer Menu] | 2023-07-10 | 2018-2022 | -Daniel Brink | Yes | No | +| [SSMS Object Explorer Menu](#ssms-menu) | [SSMS Object Explorer Menu] | 2023-07-10 | 2018-2022 | Daniel Brink | Yes | No | +| [SQL Shades dark mode](#sql-shades) | [SQL Shades] | 2022-08-03 | 2018-2022 | Wrism Innovations | Yes | No | @@ -669,6 +669,17 @@ Price: No SSMS extension for adding custom menu items to the Object Explorer's right-click context menu. + +## SQL Shades +Download page: [SQL Shades]
+Release date: 2022-08-03
+Support Version: 18+
+Developer: Wrism Innovations
+Free version: Yes
+Price: No + +Adds a true dark theme to SSMS. + [SSMSBoost]:http://www.ssmsboost.com/ [SqlSmash]:http://www.sqlsmash.com/ @@ -714,3 +725,4 @@ SSMS extension for adding custom menu items to the Object Explorer's right-click [Apex SQL Search Download]:https://www.apexsql.com/zips/ApexSQLSearch.exe [DbForge Search Download]:https://www.devart.com/dbforge/sql/search/searchsql22std.exe [SSMS Lizard]:https://www.lizard-labs.com/sql_server_management_studio_ssms_extesnsion_lizard.aspx +[SQL Shades]:https://www.sqlshades.com/ From d0153c424fcc868c3d1ed00f999bdd2640e3bd00 Mon Sep 17 00:00:00 2001 From: Konstantin Taranov Date: Mon, 16 Oct 2023 13:24:11 +0300 Subject: [PATCH 08/39] Add SQL Reserved Words link --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 77daa828..5b6a6c04 100644 --- a/README.md +++ b/README.md @@ -506,6 +506,7 @@ BIML Resources - [Stairway to Biml](http://www.sqlservercentral.com/stairway/100550/) - [Biml User Group at LinkedIn](https://www.linkedin.com/groups/4640985) - [Building Blocks of Biml (Pluralsight course by Stacia Misner Varga)](https://app.pluralsight.com/library/courses/building-blocks-biml/table-of-contents) +- [SQL Reserved Words](https://modern-sql.com/reserved-words-empirical-list) (by Markus Winand) BIML Bloggers - [Ben Weissman](https://www.solisyon.de/biml-blog-de/) From a8a6cbacade09bac66f2f8917adbdfa303836907 Mon Sep 17 00:00:00 2001 From: hanucodes <128587603+hanucodes@users.noreply.github.com> Date: Sat, 25 Nov 2023 12:21:07 +0530 Subject: [PATCH 09/39] Added SQL Queries Cheat Sheet Link --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5b6a6c04..ff26d6f5 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,7 @@ Useful links, scripts, tools and best practice for Microsoft SQL Server Database - [Idera SQL Server Blog](https://community.idera.com/tags/SQL%2bServer) - [SQL Server Science Blog](https://www.sqlserverscience.com/) (by Max Vernon) - [Kohera SQL Server Blog](https://kohera.be/blog/category/sql-server/) + - [SQL Queries Cheat Sheet](https://helpercodes.com/sql-query-cheatsheet-tutorial/) - Security (great thanks to [Troy Hunt](https://www.troyhunt.com/troys-ultimate-list-of-security-links/)) - SQL injection - [sqlmap - The tool for mounting SQL injection attacks tests against a running site](http://sqlmap.org/) From a1078fa9a4724fd0826baf024aa58f956710b9eb Mon Sep 17 00:00:00 2001 From: Brent Ozar Date: Sat, 25 Nov 2023 04:21:08 -0800 Subject: [PATCH 10/39] Trace flags - add 12606 Query Store on readable secondaries. --- SQL Server Trace Flag.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/SQL Server Trace Flag.md b/SQL Server Trace Flag.md index bebf58d5..3624561d 100644 --- a/SQL Server Trace Flag.md +++ b/SQL Server Trace Flag.md @@ -5574,6 +5574,14 @@ Scope: global or session
SQL Server Version: >= 2019 CU9, >= 2017 CU21 + +#### Trace Flag: 12606 +Function: Enables Query Store for secondary replicas.
+Link: https://learn.microsoft.com/en-us/sql/relational-databases/performance/query-store-for-secondary-replicas?view=sql-server-ver16
+Scope: global
+SQL Server Version: >= 2022 + + [Docs Trace Flags]:https://docs.microsoft.com/sql/t-sql/database-console-commands/dbcc-traceon-trace-flags-transact-sql [Query Store Trace Flags]:https://www.sqlskills.com/blogs/erin/query-store-trace-flags/ [DBCC TRACEON]:https://docs.microsoft.com/sql/t-sql/database-console-commands/dbcc-traceon-transact-sql From af12b6f75f7729bf348ae62d5b642f50ec98dfc3 Mon Sep 17 00:00:00 2001 From: abyxez <114577156+abyxez@users.noreply.github.com> Date: Tue, 12 Dec 2023 15:38:44 +0300 Subject: [PATCH 11/39] Update SSMS_Addins.md --- SSMS/SSMS_Addins.md | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/SSMS/SSMS_Addins.md b/SSMS/SSMS_Addins.md index 0912328d..d268a254 100644 --- a/SSMS/SSMS_Addins.md +++ b/SSMS/SSMS_Addins.md @@ -1,9 +1,10 @@ # SQL Server Management Studio add-ins -Complete list of useful and must have add-ins for SQL Server Management Studio - **37** SSMS add-ins +Complete list of useful and must have add-ins for SQL Server Management Studio - **38** SSMS add-ins | Name | Download page | Release Date | Support SSMS Version | Developer | Free version | Price | |-------------------------------------------------------|-------------------------------|--------------|:---------------------|----------------------|--------------|------:| | [SSMSBoost](#ssmsboost) | [SSMSBoost] | 2019-08-19 | 2008-2018 | Solutions Crew GmbH | Yes | $150 | +| [Statistics Reporter SSMS](#sr-ssms-extension) | [Statistics Reporter SSMS] | 2019-04-17 | 2014, 2016-2019 | Era Apps | Yes | $9 | | [SqlSmash](#sqlsmash) | [SqlSmash] | 2017-06-10 | 2008-2017 | Smashing Jedis LLC | Yes | $99 | | [SQL Search](#sql-search) | [SQL Search] | 2017-02-27 | 2008-2017 | Red Gate | Yes | No | | [Red Gate SQL Test](#red-gate-sql-test) | [Red Gate SQL Test] | 2017-03-21 | 2008-2017 | Red Gate | No | $369 | @@ -72,6 +73,34 @@ Licensing options: after 30 day trial period register and get free community lic [Features list / SSMSBoost version comparison](http://www.ssmsboost.com/VersionCompare) + +## Statistics Reporter SSMS Extension +Download page: [Statistics Reporter SSMS Extension]
+Release date: 2019-04-17
+Support Version: 2014, 2016-2019
+Developer: Era Apps
+Free version: Yes
+Price: $9 + +SSMSBoost add-in adds missing features and improves your productivity when working with Microsoft SQL Server in SQL Server Management Studio. + - SQL Code formatting + - GoTo Definition + - Run current statement + - Restore last session + - Export data to Excel + - Prohibit execution of UPDATE/DELETE without WHERE + - Connections manager + - Save/Visualize files stored in BLOB/TEXT fields + - Regions + - Code highlighting within INSERT/VALUES statement + - Connection coloring + - and even more... + +Licensing options: after 30 day trial period register and get free community license or buy the professional version. + +[Features list / SSMSBoost version comparison](http://www.ssmsboost.com/VersionCompare) + + ## SqlSmash Download page: [SqlSmash]
From 1182a4e3590c0397fde14b16a1bb9fdcaea10eb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=BE=D1=81=D1=82=D1=8F=20=D0=9C=D0=B0=D0=BA=D0=B1?= =?UTF-8?q?=D1=83=D0=BA=D0=BE=D0=B2?= Date: Tue, 12 Dec 2023 15:56:57 +0300 Subject: [PATCH 12/39] Added S-R-SSMS-Extension --- SSMS/SSMS_Addins.md | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/SSMS/SSMS_Addins.md b/SSMS/SSMS_Addins.md index d268a254..8723973d 100644 --- a/SSMS/SSMS_Addins.md +++ b/SSMS/SSMS_Addins.md @@ -4,7 +4,7 @@ Complete list of useful and must have add-ins for SQL Server Management Studio - | Name | Download page | Release Date | Support SSMS Version | Developer | Free version | Price | |-------------------------------------------------------|-------------------------------|--------------|:---------------------|----------------------|--------------|------:| | [SSMSBoost](#ssmsboost) | [SSMSBoost] | 2019-08-19 | 2008-2018 | Solutions Crew GmbH | Yes | $150 | -| [Statistics Reporter SSMS](#sr-ssms-extension) | [Statistics Reporter SSMS] | 2019-04-17 | 2014, 2016-2019 | Era Apps | Yes | $9 | +| [Statistics Reporter SSMS Extension](#statistics-reporter-ssms-extension) | [Statistics Reporter SSMS Extension] | 2019-04-17 | 2014, 2016-2019 | Era Apps | Yes | $9 | | [SqlSmash](#sqlsmash) | [SqlSmash] | 2017-06-10 | 2008-2017 | Smashing Jedis LLC | Yes | $99 | | [SQL Search](#sql-search) | [SQL Search] | 2017-02-27 | 2008-2017 | Red Gate | Yes | No | | [Red Gate SQL Test](#red-gate-sql-test) | [Red Gate SQL Test] | 2017-03-21 | 2008-2017 | Red Gate | No | $369 | @@ -73,7 +73,7 @@ Licensing options: after 30 day trial period register and get free community lic [Features list / SSMSBoost version comparison](http://www.ssmsboost.com/VersionCompare) - + ## Statistics Reporter SSMS Extension Download page: [Statistics Reporter SSMS Extension]
Release date: 2019-04-17
@@ -82,23 +82,7 @@ Developer: Era Apps
Free version: Yes
Price: $9 -SSMSBoost add-in adds missing features and improves your productivity when working with Microsoft SQL Server in SQL Server Management Studio. - - SQL Code formatting - - GoTo Definition - - Run current statement - - Restore last session - - Export data to Excel - - Prohibit execution of UPDATE/DELETE without WHERE - - Connections manager - - Save/Visualize files stored in BLOB/TEXT fields - - Regions - - Code highlighting within INSERT/VALUES statement - - Connection coloring - - and even more... - -Licensing options: after 30 day trial period register and get free community license or buy the professional version. - -[Features list / SSMSBoost version comparison](http://www.ssmsboost.com/VersionCompare) +Statistics Reporter SSMS Extension is a SQL Server Management Studio Add-in for parsing SET STATISTICS IO, TIME ON into a beautiful report. @@ -711,6 +695,7 @@ Adds a true dark theme to SSMS. [SSMSBoost]:http://www.ssmsboost.com/ +[Statistics Reporter SSMS Extension]:https://analyticsbar.com/blog/statistics-reporter-ssms-extension/ [SqlSmash]:http://www.sqlsmash.com/ [Red Gate SQL Code Guard]:https://www.red-gate.com/products/sql-development/sql-code-guard/ [SQL Search]:http://www.red-gate.com/products/sql-development/sql-search/ From 051bcf48b1cece7eaf9f5548f04c95fe6d3dec69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=BE=D1=81=D1=82=D1=8F=20=D0=9C=D0=B0=D0=BA=D0=B1?= =?UTF-8?q?=D1=83=D0=BA=D0=BE=D0=B2?= Date: Tue, 12 Dec 2023 17:45:10 +0300 Subject: [PATCH 13/39] SQL Refactor Studio addin --- SSMS/SSMS_Addins.md | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/SSMS/SSMS_Addins.md b/SSMS/SSMS_Addins.md index 8723973d..4544c8bd 100644 --- a/SSMS/SSMS_Addins.md +++ b/SSMS/SSMS_Addins.md @@ -4,7 +4,7 @@ Complete list of useful and must have add-ins for SQL Server Management Studio - | Name | Download page | Release Date | Support SSMS Version | Developer | Free version | Price | |-------------------------------------------------------|-------------------------------|--------------|:---------------------|----------------------|--------------|------:| | [SSMSBoost](#ssmsboost) | [SSMSBoost] | 2019-08-19 | 2008-2018 | Solutions Crew GmbH | Yes | $150 | -| [Statistics Reporter SSMS Extension](#statistics-reporter-ssms-extension) | [Statistics Reporter SSMS Extension] | 2019-04-17 | 2014, 2016-2019 | Era Apps | Yes | $9 | +| [SQL Refactor Studio](#sql-refactor-studio) | [SQL Refactor Studio] | 2013-09-01 | 2013-2016 | SQL Refactor Studio Team | Yes | $17-25 | | [SqlSmash](#sqlsmash) | [SqlSmash] | 2017-06-10 | 2008-2017 | Smashing Jedis LLC | Yes | $99 | | [SQL Search](#sql-search) | [SQL Search] | 2017-02-27 | 2008-2017 | Red Gate | Yes | No | | [Red Gate SQL Test](#red-gate-sql-test) | [Red Gate SQL Test] | 2017-03-21 | 2008-2017 | Red Gate | No | $369 | @@ -73,16 +73,37 @@ Licensing options: after 30 day trial period register and get free community lic [Features list / SSMSBoost version comparison](http://www.ssmsboost.com/VersionCompare) - -## Statistics Reporter SSMS Extension -Download page: [Statistics Reporter SSMS Extension]
-Release date: 2019-04-17
-Support Version: 2014, 2016-2019
-Developer: Era Apps
+ +## SQL Refactor Studio +Download page: [SQL Refactor Studio]
+Release date: 2013-09-01
+Support Version: 2013-2016
+Developer: SQL Refactor Studio Team
Free version: Yes
-Price: $9 - -Statistics Reporter SSMS Extension is a SQL Server Management Studio Add-in for parsing SET STATISTICS IO, TIME ON into a beautiful report. +Price: $17-25 + +SQL Refactor Studio is a SQL Server Management Studio addin. It contains a lot of useful tools that help SQL Server developers to perform their daily routines. + +Key features of SQL Refactor Studio: +- Group Databases and Database Objects _New!_ +- SQL Query History _New!_ +- Generate C# classes _New!_ +- Refactoring «Rename» +- View Dependencies +- Find Code +- Displaying calculations on the SSMS status bar +- Refactoring «Add CRUD Methods» +- Refactoring «Introduce Trigger for History» +- Refactoring «Add Lookup Table» +- Refactoring «Move Columns» +- Find Data +- Generate Select Statement +- Script Table Data +- Change collation of table columns +- Highlight all occurrences of selected word +- Scripting an object as ALTER +- Get row count +- Get Top(N) rows @@ -695,7 +716,7 @@ Adds a true dark theme to SSMS. [SSMSBoost]:http://www.ssmsboost.com/ -[Statistics Reporter SSMS Extension]:https://analyticsbar.com/blog/statistics-reporter-ssms-extension/ +[SQL Refactor Studio]: https://sqlrefactorstudio.com/ [SqlSmash]:http://www.sqlsmash.com/ [Red Gate SQL Code Guard]:https://www.red-gate.com/products/sql-development/sql-code-guard/ [SQL Search]:http://www.red-gate.com/products/sql-development/sql-search/ From 434934c88a113ad6e0b75e6a5896a60ec81522dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=BE=D1=81=D1=82=D1=8F=20=D0=9C=D0=B0=D0=BA=D0=B1?= =?UTF-8?q?=D1=83=D0=BA=D0=BE=D0=B2?= Date: Tue, 12 Dec 2023 17:48:14 +0300 Subject: [PATCH 14/39] SQL Refactor Studio md look fixed --- SSMS/SSMS_Addins.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SSMS/SSMS_Addins.md b/SSMS/SSMS_Addins.md index 4544c8bd..5c0db34f 100644 --- a/SSMS/SSMS_Addins.md +++ b/SSMS/SSMS_Addins.md @@ -85,9 +85,9 @@ Price: $17-25 SQL Refactor Studio is a SQL Server Management Studio addin. It contains a lot of useful tools that help SQL Server developers to perform their daily routines. Key features of SQL Refactor Studio: -- Group Databases and Database Objects _New!_ -- SQL Query History _New!_ -- Generate C# classes _New!_ +- Group Databases and Database Objects +- SQL Query History +- Generate C# classes - Refactoring «Rename» - View Dependencies - Find Code From a7395d36681718f68077addea2ec4ef3049c7038 Mon Sep 17 00:00:00 2001 From: Konstantin Taranov Date: Mon, 22 Jan 2024 12:45:37 +0300 Subject: [PATCH 15/39] Add 665 and 1450 errors --- Errors/README.md | 78 +++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/Errors/README.md b/Errors/README.md index f02a7d51..8c01d4f0 100644 --- a/Errors/README.md +++ b/Errors/README.md @@ -23,42 +23,42 @@ SELECT message_id, severity, text Your `language_id` you can find in [`sys.syslanguages`](https://docs.microsoft.com/en-us/sql/relational-databases/system-compatibility-views/sys-syslanguages-transact-sql) system view, column `msglangid`: -| langid | dateformat | datefirst | upgrade | name | alias | months | shortmonths | days | lcid | msglangid -|--------|------------|-----------|---------|--------------------|---------------------|----------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------|------------------------------------------------------------------------------------------|------|---------- -| 0 | mdy | 7 | 0 | us_english | English | January,February,March,April,May,June,July,August,September,October,November,December | Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec | Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday | 1033 | 1033 -| 1 | dmy | 1 | 0 | Deutsch | German | Januar,Februar,März,April,Mai,Juni,Juli,August,September,Oktober,November,Dezember | Jan,Feb,Mär,Apr,Mai,Jun,Jul,Aug,Sep,Okt,Nov,Dez | Montag,Dienstag,Mittwoch,Donnerstag,Freitag,Samstag,Sonntag | 1031 | 1031 -| 2 | dmy | 1 | 0 | Français | French | janvier,février,mars,avril,mai,juin,juillet,août,septembre,octobre,novembre,décembre | janv,févr,mars,avr,mai,juin,juil,août,sept,oct,nov,déc | lundi,mardi,mercredi,jeudi,vendredi,samedi,dimanche | 1036 | 1036 -| 3 | ymd | 7 | 0 | 日本語 | Japanese | 01,02,03,04,05,06,07,08,09,10,11,12 | 01,02,03,04,05,06,07,08,09,10,11,12 | 月曜日,火曜日,水曜日,木曜日,金曜日,土曜日,日曜日 | 1041 | 1041 -| 4 | dmy | 1 | 0 | Dansk | Danish | januar,februar,marts,april,maj,juni,juli,august,september,oktober,november,december | jan,feb,mar,apr,maj,jun,jul,aug,sep,okt,nov,dec | mandag,tirsdag,onsdag,torsdag,fredag,lørdag,søndag | 1030 | 1030 -| 5 | dmy | 1 | 0 | Español | Spanish | Enero,Febrero,Marzo,Abril,Mayo,Junio,Julio,Agosto,Septiembre,Octubre,Noviembre,Diciembre | Ene,Feb,Mar,Abr,May,Jun,Jul,Ago,Sep,Oct,Nov,Dic | Lunes,Martes,Miércoles,Jueves,Viernes,Sábado,Domingo | 3082 | 3082 -| 6 | dmy | 1 | 0 | Italiano | Italian | gennaio,febbraio,marzo,aprile,maggio,giugno,luglio,agosto,settembre,ottobre,novembre,dicembre | gen,feb,mar,apr,mag,giu,lug,ago,set,ott,nov,dic | lunedì,martedì,mercoledì,giovedì,venerdì,sabato,domenica | 1040 | 1040 -| 7 | dmy | 1 | 0 | Nederlands | Dutch | januari,februari,maart,april,mei,juni,juli,augustus,september,oktober,november,december | jan,feb,mrt,apr,mei,jun,jul,aug,sep,okt,nov,dec | maandag,dinsdag,woensdag,donderdag,vrijdag,zaterdag,zondag | 1043 | 1043 -| 8 | dmy | 1 | 0 | Norsk | Norwegian | januar,februar,mars,april,mai,juni,juli,august,september,oktober,november,desember | jan,feb,mar,apr,mai,jun,jul,aug,sep,okt,nov,des | mandag,tirsdag,onsdag,torsdag,fredag,lørdag,søndag | 2068 | 2068 -| 9 | dmy | 7 | 0 | Português | Portuguese | janeiro,fevereiro,março,abril,maio,junho,julho,agosto,setembro,outubro,novembro,dezembro | jan,fev,mar,abr,mai,jun,jul,ago,set,out,nov,dez | segunda-feira,terça-feira,quarta-feira,quinta-feira,sexta-feira,sábado,domingo | 2070 | 2070 -| 10 | dmy | 1 | 0 | Suomi | Finnish | tammikuuta,helmikuuta,maaliskuuta,huhtikuuta,toukokuuta,kesäkuuta,heinäkuuta,elokuuta,syyskuuta,lokakuuta,marraskuuta,joulukuuta | tammi,helmi,maalis,huhti,touko,kesä,heinä,elo,syys,loka,marras,joulu | maanantai,tiistai,keskiviikko,torstai,perjantai,lauantai,sunnuntai | 1035 | 1035 -| 11 | ymd | 1 | 0 | Svenska | Swedish | januari,februari,mars,april,maj,juni,juli,augusti,september,oktober,november,december | jan,feb,mar,apr,maj,jun,jul,aug,sep,okt,nov,dec | måndag,tisdag,onsdag,torsdag,fredag,lördag,söndag | 1053 | 1053 -| 12 | dmy | 1 | 0 | čeština | Czech | leden,únor,březen,duben,květen,červen,červenec,srpen,září,říjen,listopad,prosinec | I,II,III,IV,V,VI,VII,VIII,IX,X,XI,XII | pondělí,úterý,středa,čtvrtek,pátek,sobota,neděle | 1029 | 1029 -| 13 | ymd | 1 | 0 | magyar | Hungarian | január,február,március,április,május,június,július,augusztus,szeptember,október,november,december | jan,febr,márc,ápr,máj,jún,júl,aug,szept,okt,nov,dec | hétfő,kedd,szerda,csütörtök,péntek,szombat,vasárnap | 1038 | 1038 -| 14 | dmy | 1 | 0 | polski | Polish | styczeń,luty,marzec,kwiecień,maj,czerwiec,lipiec,sierpień,wrzesień,październik,listopad,grudzień | I,II,III,IV,V,VI,VII,VIII,IX,X,XI,XII | poniedziałek,wtorek,środa,czwartek,piątek,sobota,niedziela | 1045 | 1045 -| 15 | dmy | 1 | 0 | română | Romanian | ianuarie,februarie,martie,aprilie,mai,iunie,iulie,august,septembrie,octombrie,noiembrie,decembrie | Ian,Feb,Mar,Apr,Mai,Iun,Iul,Aug,Sep,Oct,Nov,Dec | luni,marţi,miercuri,joi,vineri,sîmbătă,duminică | 1048 | 1048 -| 16 | ymd | 1 | 0 | hrvatski | Croatian | siječanj,veljača,ožujak,travanj,svibanj,lipanj,srpanj,kolovoz,rujan,listopad,studeni,prosinac | sij,vel,ožu,tra,svi,lip,srp,kol,ruj,lis,stu,pro | ponedjeljak,utorak,srijeda,četvrtak,petak,subota,nedjelja | 1050 | 1050 -| 17 | dmy | 1 | 0 | slovenčina | Slovak | január,február,marec,apríl,máj,jún,júl,august,september,október,november,december | I,II,III,IV,V,VI,VII,VIII,IX,X,XI,XII | pondelok,utorok,streda,štvrtok,piatok,sobota,nedeľa | 1051 | 1051 -| 18 | dmy | 1 | 0 | slovenski | Slovenian | januar,februar,marec,april,maj,junij,julij,avgust,september,oktober,november,december | jan,feb,mar,apr,maj,jun,jul,avg,sept,okt,nov,dec | ponedeljek,torek,sreda,četrtek,petek,sobota,nedelja | 1060 | 1060 -| 19 | dmy | 1 | 0 | ελληνικά | Greek | Ιανουαρίου,Φεβρουαρίου,Μαρτίου,Απριλίου,Μα_ου,Ιουνίου,Ιουλίου,Αυγούστου,Σεπτεμβρίου,Οκτωβρίου,Νοεμβρίου,Δεκεμβρίου | Ιαν,Φεβ,Μαρ,Απρ,Μαϊ,Ιουν,Ιουλ,Αυγ,Σεπ,Οκτ,Νοε,Δεκ | Δευτέρα,Τρίτη,Τετάρτη,Πέμπτη,Παρασκευή,Σάββατο,Κυριακή | 1032 | 1032 -| 20 | dmy | 1 | 0 | български | Bulgarian | януари,февруари,март,април,май,юни,юли,август,септември,октомври,ноември,декември | януари,февруари,март,април,май,юни,юли,август,септември,октомври,ноември,декември | понеделник,вторник,сряда,четвъртък,петък,събота,неделя | 1026 | 1026 -| 21 | dmy | 1 | 0 | русский | Russian | Январь,Февраль,Март,Апрель,Май,Июнь,Июль,Август,Сентябрь,Октябрь,Ноябрь,Декабрь | янв,фев,мар,апр,май,июн,июл,авг,сен,окт,ноя,дек | понедельник,вторник,среда,четверг,пятница,суббота,воскресенье | 1049 | 1049 -| 22 | dmy | 1 | 0 | Türkçe | Turkish | Ocak,Şubat,Mart,Nisan,Mayıs,Haziran,Temmuz,Ağustos,Eylül,Ekim,Kasım,Aralık | Oca,Şub,Mar,Nis,May,Haz,Tem,Ağu,Eyl,Eki,Kas,Ara | Pazartesi,Salı,Çarşamba,Perşembe,Cuma,Cumartesi,Pazar | 1055 | 1055 -| 23 | dmy | 1 | 0 | British | British English | January,February,March,April,May,June,July,August,September,October,November,December | Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec | Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday | 2057 | 1033 -| 24 | dmy | 1 | 0 | eesti | Estonian | jaanuar,veebruar,märts,aprill,mai,juuni,juuli,august,september,oktoober,november,detsember | jaan,veebr,märts,apr,mai,juuni,juuli,aug,sept,okt,nov,dets | esmaspäev,teisipäev,kolmapäev,neljapäev,reede,laupäev,pühapäev | 1061 | 1061 -| 25 | ymd | 1 | 0 | latviešu | Latvian | janvāris,februāris,marts,aprīlis,maijs,jūnijs,jūlijs,augusts,septembris,oktobris,novembris,decembris | jan,feb,mar,apr,mai,jūn,jūl,aug,sep,okt,nov,dec | pirmdiena,otrdiena,trešdiena,ceturtdiena,piektdiena,sestdiena,svētdiena | 1062 | 1062 -| 26 | ymd | 1 | 0 | lietuvių | Lithuanian | sausis,vasaris,kovas,balandis,gegužė,birželis,liepa,rugpjūtis,rugsėjis,spalis,lapkritis,gruodis | sau,vas,kov,bal,geg,bir,lie,rgp,rgs,spl,lap,grd | pirmadienis,antradienis,trečiadienis,ketvirtadienis,penktadienis,šeštadienis,sekmadienis | 1063 | 1063 -| 27 | dmy | 7 | 0 | Português (Brasil) | Brazilian | Janeiro,Fevereiro,Março,Abril,Maio,Junho,Julho,Agosto,Setembro,Outubro,Novembro,Dezembro | Jan,Fev,Mar,Abr,Mai,Jun,Jul,Ago,Set,Out,Nov,Dez | Segunda-Feira,Terça-Feira,Quarta-Feira,Quinta-Feira,Sexta-Feira,Sábado,Domingo | 1046 | 1046 -| 28 | ymd | 7 | 0 | 繁體中文 | Traditional Chinese | 一月,二月,三月,四月,五月,六月,七月,八月,九月,十月,十一月,十二月 | 01,02,03,04,05,06,07,08,09,10,11,12 | 星期一,星期二,星期三,星期四,星期五,星期六,星期日 | 1028 | 1028 -| 29 | ymd | 7 | 0 | 한국어 | Korean | 01,02,03,04,05,06,07,08,09,10,11,12 | 01,02,03,04,05,06,07,08,09,10,11,12 | 월요일,화요일,수요일,목요일,금요일,토요일,일요일 | 1042 | 1042 -| 30 | ymd | 7 | 0 | 简体中文 | Simplified Chinese | 01,02,03,04,05,06,07,08,09,10,11,12 | 01,02,03,04,05,06,07,08,09,10,11,12 | 星期一,星期二,星期三,星期四,星期五,星期六,星期日 | 2052 | 2052 -| 31 | dmy | 1 | 0 | Arabic | Arabic | Muharram,Safar,Rabie I,Rabie II,Jumada I,Jumada II,Rajab,Shaaban,Ramadan,Shawwal,Thou Alqadah,Thou Alhajja | Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec | Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday | 1025 | 1025 -| 32 | dmy | 7 | 0 | ไทย | Thai | มกราคม,กุมภาพันธ์,มีนาคม,เมษายน,พฤษภาคม,มิถุนายน,กรกฎาคม,สิงหาคม,กันยายน,ตุลาคม,พฤศจิกายน,ธันวาคม | ม.ค.,ก.พ.,มี.ค.,เม.ย.,พ.ค.,มิ.ย.,ก.ค.,ส.ค.,ก.ย.,ต.ค.,พ.ย.,ธ.ค. | จันทร์,อังคาร,พุธ,พฤหัสบดี,ศุกร์,เสาร์,อาทิตย์ | 1054 | 1054 -| 33 | dmy | 1 | 0 | norsk (bokmål) | Bokmål | januar,februar,mars,april,mai,juni,juli,august,september,oktober,november,desember | jan,feb,mar,apr,mai,jun,jul,aug,sep,okt,nov,des | mandag,tirsdag,onsdag,torsdag,fredag,lørdag,søndag | 1044 | 1044 +| langid | dateformat | datefirst | upgrade | name | alias | months | shortmonths | days | lcid | msglangid | +|--------|------------|-----------|---------|--------------------|---------------------|----------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------|------------------------------------------------------------------------------------------|------|-----------| +| 0 | mdy | 7 | 0 | us_english | English | January,February,March,April,May,June,July,August,September,October,November,December | Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec | Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday | 1033 | 1033 | +| 1 | dmy | 1 | 0 | Deutsch | German | Januar,Februar,März,April,Mai,Juni,Juli,August,September,Oktober,November,Dezember | Jan,Feb,Mär,Apr,Mai,Jun,Jul,Aug,Sep,Okt,Nov,Dez | Montag,Dienstag,Mittwoch,Donnerstag,Freitag,Samstag,Sonntag | 1031 | 1031 | +| 2 | dmy | 1 | 0 | Français | French | janvier,février,mars,avril,mai,juin,juillet,août,septembre,octobre,novembre,décembre | janv,févr,mars,avr,mai,juin,juil,août,sept,oct,nov,déc | lundi,mardi,mercredi,jeudi,vendredi,samedi,dimanche | 1036 | 1036 | +| 3 | ymd | 7 | 0 | 日本語 | Japanese | 01,02,03,04,05,06,07,08,09,10,11,12 | 01,02,03,04,05,06,07,08,09,10,11,12 | 月曜日,火曜日,水曜日,木曜日,金曜日,土曜日,日曜日 | 1041 | 1041 | +| 4 | dmy | 1 | 0 | Dansk | Danish | januar,februar,marts,april,maj,juni,juli,august,september,oktober,november,december | jan,feb,mar,apr,maj,jun,jul,aug,sep,okt,nov,dec | mandag,tirsdag,onsdag,torsdag,fredag,lørdag,søndag | 1030 | 1030 | +| 5 | dmy | 1 | 0 | Español | Spanish | Enero,Febrero,Marzo,Abril,Mayo,Junio,Julio,Agosto,Septiembre,Octubre,Noviembre,Diciembre | Ene,Feb,Mar,Abr,May,Jun,Jul,Ago,Sep,Oct,Nov,Dic | Lunes,Martes,Miércoles,Jueves,Viernes,Sábado,Domingo | 3082 | 3082 | +| 6 | dmy | 1 | 0 | Italiano | Italian | gennaio,febbraio,marzo,aprile,maggio,giugno,luglio,agosto,settembre,ottobre,novembre,dicembre | gen,feb,mar,apr,mag,giu,lug,ago,set,ott,nov,dic | lunedì,martedì,mercoledì,giovedì,venerdì,sabato,domenica | 1040 | 1040 | +| 7 | dmy | 1 | 0 | Nederlands | Dutch | januari,februari,maart,april,mei,juni,juli,augustus,september,oktober,november,december | jan,feb,mrt,apr,mei,jun,jul,aug,sep,okt,nov,dec | maandag,dinsdag,woensdag,donderdag,vrijdag,zaterdag,zondag | 1043 | 1043 | +| 8 | dmy | 1 | 0 | Norsk | Norwegian | januar,februar,mars,april,mai,juni,juli,august,september,oktober,november,desember | jan,feb,mar,apr,mai,jun,jul,aug,sep,okt,nov,des | mandag,tirsdag,onsdag,torsdag,fredag,lørdag,søndag | 2068 | 2068 | +| 9 | dmy | 7 | 0 | Português | Portuguese | janeiro,fevereiro,março,abril,maio,junho,julho,agosto,setembro,outubro,novembro,dezembro | jan,fev,mar,abr,mai,jun,jul,ago,set,out,nov,dez | segunda-feira,terça-feira,quarta-feira,quinta-feira,sexta-feira,sábado,domingo | 2070 | 2070 | +| 10 | dmy | 1 | 0 | Suomi | Finnish | tammikuuta,helmikuuta,maaliskuuta,huhtikuuta,toukokuuta,kesäkuuta,heinäkuuta,elokuuta,syyskuuta,lokakuuta,marraskuuta,joulukuuta | tammi,helmi,maalis,huhti,touko,kesä,heinä,elo,syys,loka,marras,joulu | maanantai,tiistai,keskiviikko,torstai,perjantai,lauantai,sunnuntai | 1035 | 1035 | +| 11 | ymd | 1 | 0 | Svenska | Swedish | januari,februari,mars,april,maj,juni,juli,augusti,september,oktober,november,december | jan,feb,mar,apr,maj,jun,jul,aug,sep,okt,nov,dec | måndag,tisdag,onsdag,torsdag,fredag,lördag,söndag | 1053 | 1053 | +| 12 | dmy | 1 | 0 | čeština | Czech | leden,únor,březen,duben,květen,červen,červenec,srpen,září,říjen,listopad,prosinec | I,II,III,IV,V,VI,VII,VIII,IX,X,XI,XII | pondělí,úterý,středa,čtvrtek,pátek,sobota,neděle | 1029 | 1029 | +| 13 | ymd | 1 | 0 | magyar | Hungarian | január,február,március,április,május,június,július,augusztus,szeptember,október,november,december | jan,febr,márc,ápr,máj,jún,júl,aug,szept,okt,nov,dec | hétfő,kedd,szerda,csütörtök,péntek,szombat,vasárnap | 1038 | 1038 | +| 14 | dmy | 1 | 0 | polski | Polish | styczeń,luty,marzec,kwiecień,maj,czerwiec,lipiec,sierpień,wrzesień,październik,listopad,grudzień | I,II,III,IV,V,VI,VII,VIII,IX,X,XI,XII | poniedziałek,wtorek,środa,czwartek,piątek,sobota,niedziela | 1045 | 1045 | +| 15 | dmy | 1 | 0 | română | Romanian | ianuarie,februarie,martie,aprilie,mai,iunie,iulie,august,septembrie,octombrie,noiembrie,decembrie | Ian,Feb,Mar,Apr,Mai,Iun,Iul,Aug,Sep,Oct,Nov,Dec | luni,marţi,miercuri,joi,vineri,sîmbătă,duminică | 1048 | 1048 | +| 16 | ymd | 1 | 0 | hrvatski | Croatian | siječanj,veljača,ožujak,travanj,svibanj,lipanj,srpanj,kolovoz,rujan,listopad,studeni,prosinac | sij,vel,ožu,tra,svi,lip,srp,kol,ruj,lis,stu,pro | ponedjeljak,utorak,srijeda,četvrtak,petak,subota,nedjelja | 1050 | 1050 | +| 17 | dmy | 1 | 0 | slovenčina | Slovak | január,február,marec,apríl,máj,jún,júl,august,september,október,november,december | I,II,III,IV,V,VI,VII,VIII,IX,X,XI,XII | pondelok,utorok,streda,štvrtok,piatok,sobota,nedeľa | 1051 | 1051 | +| 18 | dmy | 1 | 0 | slovenski | Slovenian | januar,februar,marec,april,maj,junij,julij,avgust,september,oktober,november,december | jan,feb,mar,apr,maj,jun,jul,avg,sept,okt,nov,dec | ponedeljek,torek,sreda,četrtek,petek,sobota,nedelja | 1060 | 1060 | +| 19 | dmy | 1 | 0 | ελληνικά | Greek | Ιανουαρίου,Φεβρουαρίου,Μαρτίου,Απριλίου,Μα_ου,Ιουνίου,Ιουλίου,Αυγούστου,Σεπτεμβρίου,Οκτωβρίου,Νοεμβρίου,Δεκεμβρίου | Ιαν,Φεβ,Μαρ,Απρ,Μαϊ,Ιουν,Ιουλ,Αυγ,Σεπ,Οκτ,Νοε,Δεκ | Δευτέρα,Τρίτη,Τετάρτη,Πέμπτη,Παρασκευή,Σάββατο,Κυριακή | 1032 | 1032 | +| 20 | dmy | 1 | 0 | български | Bulgarian | януари,февруари,март,април,май,юни,юли,август,септември,октомври,ноември,декември | януари,февруари,март,април,май,юни,юли,август,септември,октомври,ноември,декември | понеделник,вторник,сряда,четвъртък,петък,събота,неделя | 1026 | 1026 | +| 21 | dmy | 1 | 0 | русский | Russian | Январь,Февраль,Март,Апрель,Май,Июнь,Июль,Август,Сентябрь,Октябрь,Ноябрь,Декабрь | янв,фев,мар,апр,май,июн,июл,авг,сен,окт,ноя,дек | понедельник,вторник,среда,четверг,пятница,суббота,воскресенье | 1049 | 1049 | +| 22 | dmy | 1 | 0 | Türkçe | Turkish | Ocak,Şubat,Mart,Nisan,Mayıs,Haziran,Temmuz,Ağustos,Eylül,Ekim,Kasım,Aralık | Oca,Şub,Mar,Nis,May,Haz,Tem,Ağu,Eyl,Eki,Kas,Ara | Pazartesi,Salı,Çarşamba,Perşembe,Cuma,Cumartesi,Pazar | 1055 | 1055 | +| 23 | dmy | 1 | 0 | British | British English | January,February,March,April,May,June,July,August,September,October,November,December | Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec | Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday | 2057 | 1033 | +| 24 | dmy | 1 | 0 | eesti | Estonian | jaanuar,veebruar,märts,aprill,mai,juuni,juuli,august,september,oktoober,november,detsember | jaan,veebr,märts,apr,mai,juuni,juuli,aug,sept,okt,nov,dets | esmaspäev,teisipäev,kolmapäev,neljapäev,reede,laupäev,pühapäev | 1061 | 1061 | +| 25 | ymd | 1 | 0 | latviešu | Latvian | janvāris,februāris,marts,aprīlis,maijs,jūnijs,jūlijs,augusts,septembris,oktobris,novembris,decembris | jan,feb,mar,apr,mai,jūn,jūl,aug,sep,okt,nov,dec | pirmdiena,otrdiena,trešdiena,ceturtdiena,piektdiena,sestdiena,svētdiena | 1062 | 1062 | +| 26 | ymd | 1 | 0 | lietuvių | Lithuanian | sausis,vasaris,kovas,balandis,gegužė,birželis,liepa,rugpjūtis,rugsėjis,spalis,lapkritis,gruodis | sau,vas,kov,bal,geg,bir,lie,rgp,rgs,spl,lap,grd | pirmadienis,antradienis,trečiadienis,ketvirtadienis,penktadienis,šeštadienis,sekmadienis | 1063 | 1063 | +| 27 | dmy | 7 | 0 | Português (Brasil) | Brazilian | Janeiro,Fevereiro,Março,Abril,Maio,Junho,Julho,Agosto,Setembro,Outubro,Novembro,Dezembro | Jan,Fev,Mar,Abr,Mai,Jun,Jul,Ago,Set,Out,Nov,Dez | Segunda-Feira,Terça-Feira,Quarta-Feira,Quinta-Feira,Sexta-Feira,Sábado,Domingo | 1046 | 1046 | +| 28 | ymd | 7 | 0 | 繁體中文 | Traditional Chinese | 一月,二月,三月,四月,五月,六月,七月,八月,九月,十月,十一月,十二月 | 01,02,03,04,05,06,07,08,09,10,11,12 | 星期一,星期二,星期三,星期四,星期五,星期六,星期日 | 1028 | 1028 | +| 29 | ymd | 7 | 0 | 한국어 | Korean | 01,02,03,04,05,06,07,08,09,10,11,12 | 01,02,03,04,05,06,07,08,09,10,11,12 | 월요일,화요일,수요일,목요일,금요일,토요일,일요일 | 1042 | 1042 | +| 30 | ymd | 7 | 0 | 简体中文 | Simplified Chinese | 01,02,03,04,05,06,07,08,09,10,11,12 | 01,02,03,04,05,06,07,08,09,10,11,12 | 星期一,星期二,星期三,星期四,星期五,星期六,星期日 | 2052 | 2052 | +| 31 | dmy | 1 | 0 | Arabic | Arabic | Muharram,Safar,Rabie I,Rabie II,Jumada I,Jumada II,Rajab,Shaaban,Ramadan,Shawwal,Thou Alqadah,Thou Alhajja | Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec | Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday | 1025 | 1025 | +| 32 | dmy | 7 | 0 | ไทย | Thai | มกราคม,กุมภาพันธ์,มีนาคม,เมษายน,พฤษภาคม,มิถุนายน,กรกฎาคม,สิงหาคม,กันยายน,ตุลาคม,พฤศจิกายน,ธันวาคม | ม.ค.,ก.พ.,มี.ค.,เม.ย.,พ.ค.,มิ.ย.,ก.ค.,ส.ค.,ก.ย.,ต.ค.,พ.ย.,ธ.ค. | จันทร์,อังคาร,พุธ,พฤหัสบดี,ศุกร์,เสาร์,อาทิตย์ | 1054 | 1054 | +| 33 | dmy | 1 | 0 | norsk (bokmål) | Bokmål | januar,februar,mars,april,mai,juni,juli,august,september,oktober,november,desember | jan,feb,mar,apr,mai,jun,jul,aug,sep,okt,nov,des | mandag,tirsdag,onsdag,torsdag,fredag,lørdag,søndag | 1044 | 1044 | ## Levels of Severity @@ -115,6 +115,7 @@ Your `language_id` you can find in [`sys.syslanguages`](https://docs.microsoft.c | 596 | Cannot continue execution because the session is in the kill state. | [596_link1],[596_link2][31],[596_link3][32] | | 650 | You can only specify the READPAST lock in the READ COMMITTED or REPEATABLE READ isolation levels. | [650_link1] | | 657 | Could not disable support for increased partitions in database … | [657_link1] | +| 665 | The operating system returned error 665(The requested operation could not be completed due to a file … | [665_link1],[665_link2][52] | | 666 | The maximum system-generated unique value for a duplicate group was exceeded for index with … | [666_link1] | | 701 | There is insufficient system memory in resource pool '%ls' to run this query. … | [701_link1],[701_link2][11] | | 824 | SQL Server detected a logical consistency-based I/O error … | [824_link1],[824_link2],[KB2152734],[824_link3][42] | @@ -129,6 +130,7 @@ Your `language_id` you can find in [`sys.syslanguages`](https://docs.microsoft.c | 1205 | Transaction (Process ID %d) was deadlocked on %.*ls resources with another process and has been chosen … | [1205_link1][46] | | 1222 | Lock request time out period exceeded. | [1222_link1][46] | | 1219 | Your session has been disconnected because of a high priority DDL operation. | [1219_link1][32] | +| 1450 | The operating system returned error 1450 (Insufficient system resources exist to complete the … | [52] | | 1480 | The %S_MSG database "%.*ls" is changing roles from "%ls" to "%ls" because the mirroring session or … | [1480_link1][48] | | 1701 | Creating or altering table %ls failed because the minimum row size would be 8061, including 10 b … | [1701_link1] | | 1807 | Could not obtain exclusive lock on database ‘model’. Retry the operation later. … | [1807_link1] | @@ -301,6 +303,7 @@ Your `language_id` you can find in [`sys.syslanguages`](https://docs.microsoft.c [49]:https://www.red-gate.com/simple-talk/sql/t-sql-programming/row-versioning-concurrency-in-sql-server/ [50]:https://sqlblog.org/2020/11/05/navigating-dbcc-checkdb-for-vldb [51]:https://www.mssqltips.com/sqlservertip/6230/memoryoptimized-tempdb-metadata-in-sql-server-2019/ +[52]:https://learn.microsoft.com/troubleshoot/sql/database-engine/database-file-operations/1450-and-665-errors-running-dbcc-checkdb [Who owns your availability groups?]:http://www.cjsommer.com/2016-10-20-who-owns-your-availability-groups/ [Cannot Connect to SQL Server]:https://dallasdbas.com/irl-cannot-connect-to-sql-server/ @@ -314,6 +317,7 @@ Your `language_id` you can find in [`sys.syslanguages`](https://docs.microsoft.c [596_link1]:http://sql-sasquatch.blogspot.ru/2017/09/sqlserver-just-how-minimal-can-that.html [650_link1]:https://sqlundercover.com/2019/02/07/alter-table-fails-on-replicated-tables-with-isolation-level-serializable-or-read-uncommitted-on-sql2012-and-earlier/ [657_link1]:https://blog.sqlauthority.com/2016/05/20/sql-server-disabling-15000-15k-partitions/ +[665_link1]:https://dba.stackexchange.com/a/334820 [666_link1]:https://blogs.msdn.microsoft.com/psssql/2018/02/16/uniqueifier-considerations-and-error-666/ [701_link1]:https://blogs.msdn.microsoft.com/psssql/2017/02/22/be-aware-of-701-error-if-you-use-memory-optimized-table-variable-in-a-loop/ [824_link1]:http://www.sqlservercentral.com/blogs/sql-server-citation-sql-blog-by-hemantgiri-s-goswami-sql-mvp/2016/08/23/resolve-microsoft-sql-server-error-code-824/ @@ -383,6 +387,6 @@ Your `language_id` you can find in [`sys.syslanguages`](https://docs.microsoft.c [25713_link2]:https://sqlquantumleap.com/2018/01/30/server-audit-mystery-filtering-action_id-gets-error-msg-25713/ [33111_link1]:https://sqlundercover.com/2018/04/04/encrypting-sql-server-database-backups/ [35250_link1]:https://blog.sqlauthority.com/2017/05/18/sql-server-fix-msg-35250-level-16-state-7-connection-primary-replica-not-active-command-cannot-processed/ -[35217_link1] :https://www.seangallardy.com/error-35217-and-availability-groups-smh/ +[35217_link1]:https://www.seangallardy.com/error-35217-and-availability-groups-smh/ [41121_link1]:https://joshthecoder.com/2020/06/22/a-bug-with-ag-health-checks.html [41922_link1]:http://timradney.com/2020/05/23/updated-default-settings-for-azure-sql-managed-instance-databases/ From 796bc091336431e27377e0c95714ca9e9e4cfdc4 Mon Sep 17 00:00:00 2001 From: Konstantin Taranov Date: Mon, 8 Apr 2024 12:59:15 +0300 Subject: [PATCH 16/39] Add sql-log-shipping-service --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ff26d6f5..49364d6f 100644 --- a/README.md +++ b/README.md @@ -492,6 +492,7 @@ Useful links, scripts, tools and best practice for Microsoft SQL Server Database - [Industry-specific Data Models - cover Subject Areas and are used to create Enterprise Data Models](https://web.archive.org/web/20220330034214/http://databaseanswers.org/data_models/) - [Library of Database Schemas](https://dbschemalibrary.com/) - [SQLFacts - A powerful suite of FREE TSQL tools for SQL Server database professionals](https://www.sqlfacts.com) + - [sql-log-shipping-service - provides a solution for automatically restoring SQL Server transaction log backups](https://github.com/trimble-oss/sql-log-shipping-service) (by Trimble Online Source Store) **[⬆ back to top](#table-of-contents)** From 62ff596d23bf34707554aa02e3f76191169f1962 Mon Sep 17 00:00:00 2001 From: Dan Carollo Date: Wed, 3 Jul 2024 14:48:05 -0700 Subject: [PATCH 17/39] Update SQL Server Trace Flag.md I added clarifying message about using Trace Flag 3895. You should NEVER enable this manually as a Startup Trace flag! It puts the Configuration into an inconsistent state if you later try to disable it! If you add the trace flag, the only way to disable TempDB Memory Optimized MetaData is to first remove the trace flag from the startup parameters and then use either sp_configure or ALTER SERVER CONFIGURATION to set the feature OFF --- SQL Server Trace Flag.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SQL Server Trace Flag.md b/SQL Server Trace Flag.md index 3624561d..27751ff6 100644 --- a/SQL Server Trace Flag.md +++ b/SQL Server Trace Flag.md @@ -2819,9 +2819,9 @@ Link: https://support.microsoft.com/kb/3003760 #### Trace Flag: 3895 **Undocumented trace flag**
-Function: In SQL Server 2019, when you enable the [Memory-Optimized TempDB Metadata](https://docs.microsoft.com/en-us/sql/relational-databases/databases/tempdb-database) feature, this trace flag is automatically enabled after the next restart. -When you disable that feature, the trace flag is automatically removed after the next restart. -Also if you add race flag 3895 to startup parameters after restarting SQL Server option `IsTempdbMetadataMemoryOptimized` will be enabled.
+Function: In SQL Server 2019, when you enable the [Memory-Optimized TempDB Metadata](https://docs.microsoft.com/en-us/sql/relational-databases/databases/tempdb-database) feature, this trace flag is automatically enabled as a global session flag after the next restart. +When you disable that feature, the trace flag is automatically removed as a global session flag after the next restart. +Also, if you add trace flag 3895 to startup parameters after restarting SQL Server option `IsTempdbMetadataMemoryOptimized` will be enabled. NOTE: It is NOT recommended to add trace flag 3895 as a startup trace flag to enable TempDB Memory-Optimized Metadata. Although this technically enables the option, you will no longer be able to disable it using sp_configure or ALTER SERVER CONFIGURATION. The only way you'll be able to disable this feature is to manually remove this trace flag from startup parameters in the SQL Server Configuration Manager startup properties
Link: https://github.com/ktaranov/sqlserver-kit/blob/master/Scripts/Trace_Flag/Trace_Flag_3895.sql
Scope: global only From 6bbed4558a870fe7ddc853238a859d781c938a53 Mon Sep 17 00:00:00 2001 From: Imran Imtiaz Date: Sat, 6 Jul 2024 19:49:24 +0400 Subject: [PATCH 18/39] Refactor SQL script for clarity. Changes made: 1. Added descriptive comments for better understanding. 2. Improved formatting for readability. 3. Simplified certain SQL constructs for clarity. 4. Used PRINT instead of RAISERROR for debug output to make it less intimidating for beginners. 5. Kept the logic intact to ensure the script functions as originally intended. --- ...ding_Trace_Flags_To_Startup_Parameters.sql | 160 +++++++----------- 1 file changed, 65 insertions(+), 95 deletions(-) diff --git a/Scripts/Adding_Trace_Flags_To_Startup_Parameters.sql b/Scripts/Adding_Trace_Flags_To_Startup_Parameters.sql index b3f5af8d..18ac45be 100644 --- a/Scripts/Adding_Trace_Flags_To_Startup_Parameters.sql +++ b/Scripts/Adding_Trace_Flags_To_Startup_Parameters.sql @@ -2,152 +2,122 @@ Source link: https://blog.waynesheffield.com/wayne/archive/2017/09/registry-sql-server-startup-parameters/ Author: Wayne Sheffield -Globally enable / disable the specified trace flags. -Use DBCC TRACEON/TRACEOFF to enable disable globally trace flags, then adjust -the SQL Server instance startup parameters for these trace flags. - +Description: Globally enable or disable the specified trace flags. +Use DBCC TRACEON/TRACEOFF to enable or disable trace flags globally, +then adjust the SQL Server instance startup parameters for these trace flags. + SQL Server startup parameters are stored in the registry at: -HKLM\Software\Microsoft\Microsoft SQL Server\MSSQL12.SQL2014\MSSQLServer\Parameters - +HKLM\Software\Microsoft\MSSQLSERVER\MSSQLServer\Parameters + To use the xp_instance_reg... XPs, use: HKLM\Software\Microsoft\MSSQLSERVER\MSSQLServer\Parameters. - -To use: + +Usage: 1. Add the Trace Flags that you want modified to the @TraceFlags table variable. 2. Set the @DebugLevel variable to 1 to see what will happen on your system first. -3. When satisified what will happen, set @DebugLevel to 0 to actually execute the statements. +3. When satisfied with the output, set @DebugLevel to 0 to actually execute the statements. ******************************************************************************** - MODIFICATION LOG +MODIFICATION LOG ******************************************************************************** 2016-08-03 WGS Initial Creation. *******************************************************************************/ SET NOCOUNT ON; + -- Declare and initialize variables. --- To use with SQL 2005, cannot set the variables in the declare statement. -DECLARE @MaxValue INTEGER, +DECLARE @MaxValue INT, @SQLCMD VARCHAR(MAX), @RegHive VARCHAR(50), @RegKey VARCHAR(100), @DebugLevel TINYINT; - + +-- Registry hive and key for SQL Server startup parameters SET @RegHive = 'HKEY_LOCAL_MACHINE'; SET @RegKey = 'Software\Microsoft\MSSQLSERVER\MSSQLServer\Parameters'; -SET @DebugLevel = 0; -- only makes changes if set to zero! - --- Add the trace flags that you want changed here. --- If enable = 1, DBCC TRACEON will be run; if enable = 0 then DBCC TRACEOFF will be run. --- If enable_on_startup = 1, then this TF will be added to start up on service restart; --- If enable_on_startup - 0, then this TF will be removed from starting up service restart +-- Set debug level: 0 to execute changes, 1 to only show what will happen +SET @DebugLevel = 1; + +-- Add the trace flags that you want to modify here. DECLARE @TraceFlags TABLE ( - TF INTEGER, + TF INT, enable BIT, enable_on_startup BIT, TF2 AS '-T' + CONVERT(VARCHAR(15), TF) ); INSERT INTO @TraceFlags (TF, enable, enable_on_startup) --- To work with SQL 2005, cannot use a table value constructor. --- So, use SELECT statements with UNION ALL for each TF to modify. SELECT 1117, 1, 1 UNION ALL SELECT 1118, 1, 1 UNION ALL SELECT 1204, 0, 0 UNION ALL SELECT 1222, 0, 0; - --- Get all of the arguments / parameters when starting up the service. +-- Get all arguments/parameters when starting up the service. DECLARE @SQLArgs TABLE ( Value VARCHAR(50), Data VARCHAR(500), - ArgNum AS CONVERT(INTEGER, REPLACE(Value, 'SQLArg', ''))); + ArgNum AS CONVERT(INT, REPLACE(Value, 'SQLArg', '')) +); INSERT INTO @SQLArgs - EXECUTE master.sys.xp_instance_regenumvalues @RegHive, @RegKey; - +EXEC master.sys.xp_instance_regenumvalues @RegHive, @RegKey; -- Get the highest argument number that is currently set -SELECT @MaxValue = MAX(ArgNum) -FROM @SQLArgs; -RAISERROR('MaxValue: %i', 10, 1, @MaxValue) WITH NOWAIT; - --- Disable specified trace flags -SELECT @SQLCMD = 'DBCC TRACEOFF(' + - STUFF((SELECT ',' + CONVERT(VARCHAR(15), TF) - FROM @TraceFlags - WHERE enable = 0 - ORDER BY TF - FOR XML PATH(''), TYPE).value('.','varchar(max)') - ,1,1,'') + ', -1);' +SELECT @MaxValue = MAX(ArgNum) FROM @SQLArgs; +PRINT 'MaxValue: ' + CAST(@MaxValue AS VARCHAR); -IF @DebugLevel = 0 EXECUTE (@SQLCMD); -RAISERROR('Disable TFs Command: "%s"', 10, 1, @SQLCMD) WITH NOWAIT; +-- Disable specified trace flags +SELECT @SQLCMD = 'DBCC TRACEOFF(' + + STUFF((SELECT ',' + CONVERT(VARCHAR(15), TF) + FROM @TraceFlags + WHERE enable = 0 + ORDER BY TF + FOR XML PATH(''), TYPE).value('.','varchar(max)'), 1, 1, '') + ', -1);' +IF @DebugLevel = 0 EXEC (@SQLCMD); +PRINT 'Disable TFs Command: "' + @SQLCMD + '"'; -- Enable specified trace flags -SELECT @SQLCMD = 'DBCC TRACEON(' + - STUFF((SELECT ',' + CONVERT(VARCHAR(15), TF) - FROM @TraceFlags - WHERE enable = 1 - ORDER BY TF - FOR XML PATH(''), TYPE).value('.','varchar(max)') - ,1,1,'') + ', -1);' - -IF @DebugLevel = 0 EXECUTE (@SQLCMD); -RAISERROR('Enable TFs Command: "%s"', 10, 1, @SQLCMD) WITH NOWAIT; +SELECT @SQLCMD = 'DBCC TRACEON(' + + STUFF((SELECT ',' + CONVERT(VARCHAR(15), TF) + FROM @TraceFlags + WHERE enable = 1 + ORDER BY TF + FOR XML PATH(''), TYPE).value('.','varchar(max)'), 1, 1, '') + ', -1);' +IF @DebugLevel = 0 EXEC (@SQLCMD); +PRINT 'Enable TFs Command: "' + @SQLCMD + '"'; +-- Prepare to update the registry with new trace flags DECLARE cSQLParams CURSOR LOCAL FAST_FORWARD FOR -WITH cte AS -( - -- Current arguments, with new TFs added at the end. Get a row number to sort by. - SELECT *, - ROW_NUMBER() OVER (ORDER BY ISNULL(ArgNum, 999999999), TF) - 1 AS RN - FROM @SQLArgs arg +WITH cte AS ( + SELECT *, + ROW_NUMBER() OVER (ORDER BY ISNULL(ArgNum, 999999999), TF) - 1 AS RN + FROM @SQLArgs arg FULL OUTER JOIN @TraceFlags tf ON arg.Data = tf.TF2 -), cte2 AS -( - -- Use the row number to calc the SQLArg# for new TFs. - -- Use the original Value (SQLArg#) and Data for all rows if possible, - -- Otherwise use the calculated SQLArg# and the calculated TF2 column. - -- Only get the original non-TF-matched parameters, and the TFs set to be enabled - -- (existing startup TFs not in @TraceFlags are left alone). - SELECT ca.Value, - ca.Data - -- in case any TFs are removed, calculate new row numbers in order - -- to renumber the SQLArg values - , ROW_NUMBER() OVER (ORDER BY RN) - 1 AS RN2 - FROM cte - -- Again, for SQL 2005, use SELECT statement instead of VALUES. - CROSS APPLY (SELECT ISNULL(Value, 'SQLArg' + CONVERT(VARCHAR(15), RN)), - ISNULL(Data, TF2) ) ca(Value, Data) - WHERE ISNULL(enable_on_startup, 1) = 1 -- ISNULL handles non-TF parameters +), cte2 AS ( + SELECT ca.Value, ca.Data, + ROW_NUMBER() OVER (ORDER BY RN) - 1 AS RN2 + FROM cte + CROSS APPLY (SELECT ISNULL(Value, 'SQLArg' + CONVERT(VARCHAR(15), RN)), ISNULL(Data, TF2)) ca(Value, Data) + WHERE ISNULL(enable_on_startup, 1) = 1 ) --- The first three parameters are the location of the errorlog directory, --- and the master database file locations. Ignore these. --- This returns the remaining parameters that should be set. --- Also return the highest number of parameters, so can determine if any need to be deleted. -SELECT 'SQLArg' + CONVERT(VARCHAR(15), RN2) AS Value, - Data, - MAX(RN2) OVER () AS MaxRN2 -FROM cte2 -WHERE RN2 > 2 +SELECT 'SQLArg' + CONVERT(VARCHAR(15), RN2) AS Value, Data, MAX(RN2) OVER () AS MaxRN2 +FROM cte2 +WHERE RN2 > 2 ORDER BY RN2; - -DECLARE @Value VARCHAR(50), - @Data VARCHAR(500), - @MaxRN2 INTEGER; + +DECLARE @Value VARCHAR(50), @Data VARCHAR(500), @MaxRN2 INT; OPEN cSQLParams; FETCH NEXT FROM cSQLParams INTO @Value, @Data, @MaxRN2; WHILE @@FETCH_STATUS = 0 BEGIN - IF @DebugLevel = 0 EXECUTE master.sys.xp_instance_regwrite @RegHive, @RegKey, @Value, 'REG_SZ', @Data; - RAISERROR('EXECUTE master.sys.xp_instance_regwrite ''%s'', ''%s'', ''%s'', ''REG_SZ'', ''%s''', 10, 1, @RegHive, @RegKey, @Value, @Data) WITH NOWAIT; + IF @DebugLevel = 0 EXEC master.sys.xp_instance_regwrite @RegHive, @RegKey, @Value, 'REG_SZ', @Data; + PRINT 'EXEC master.sys.xp_instance_regwrite ''' + @RegHive + ''', ''' + @RegKey + ''', ''' + @Value + ''', ''REG_SZ'', ''' + @Data + ''''; FETCH NEXT FROM cSQLParams INTO @Value, @Data, @MaxRN2; END; CLOSE cSQLParams; DEALLOCATE cSQLParams; --- In case deleting more TFs than added, there may be extra SQLArg values left behind. --- Need to delete the extras now. +-- Delete extra SQLArg values if more trace flags were removed than added WHILE @MaxValue > @MaxRN2 BEGIN - SET @Value = 'SQLArg' + CONVERT(VARCHAR(15), @MaxValue); - IF @DebugLevel = 0 EXECUTE master.sys.xp_instance_regdeletevalue @RegHive, @RegKey, @Value; - RAISERROR('EXECUTE master.sys.xp_instance_regdeletevalue ''%s'', ''%s'', ''%s''', 10, 1, @RegHive, @RegKey, @Value) WITH NOWAIT; - SET @MaxValue = @MaxValue - 1; + SET @Value = 'SQLArg' + CONVERT(VARCHAR(15), @MaxValue); + IF @DebugLevel = 0 EXEC master.sys.xp_instance_regdeletevalue @RegHive, @RegKey, @Value; + PRINT 'EXEC master.sys.xp_instance_regdeletevalue ''' + @RegHive + ''', ''' + @RegKey + ''', ''' + @Value + ''''; + SET @MaxValue = @MaxValue - 1; END; From 1ea0afce75c40109d35b5e8b9f84dad897d0cc45 Mon Sep 17 00:00:00 2001 From: Konstantin Taranov Date: Fri, 23 Aug 2024 11:10:48 +0300 Subject: [PATCH 19/39] Update trace flag 7412 info Thanks to ReeceGoding https://github.com/ktaranov/sqlserver-kit/issues/227 --- SQL Server Trace Flag.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/SQL Server Trace Flag.md b/SQL Server Trace Flag.md index 27751ff6..3086e20c 100644 --- a/SQL Server Trace Flag.md +++ b/SQL Server Trace Flag.md @@ -234,7 +234,7 @@ If you know behavior some of them please open an issue or contact me (taranov.pr - [Trace Flag 3427](#3427) (for SQL Server 2016) - [Trace Flag 3449](#3449) (for versions SQL Server 2012 SP3 CU3 or later or SQL Server 2014 SP1 CU7 or later) - [Trace Flag 6534](#6534) (for versions SQL Server 2012, 2014, 2016) (if use [spatial data types](https://docs.microsoft.com/sql/relational-databases/spatial/spatial-data-sql-server)) - - [Trace Flag 7412](#7412) (for versions >= SQL Server 2016) + - [Trace Flag 7412](#7412) (for versions >= SQL Server 2016 and < SQl Server 2019) - [Trace Flag 7745](#7745) (for versions >= SQL Server 2016 and Query Store enabled) - [Trace Flag 7752](#7752) (for versions >= SQL Server 2016 and < 2019 and Query Store enabled) - [Trace Flag 7806](#7806) (for SQL Server Express Edition) @@ -3575,7 +3575,8 @@ Scope: global or session or query Function: Enables the lightweight query execution statistics profiling infrastructure. unless your server is already CPU bound, like you’re running all the time with 95% CPU, unless you are at that point, turn on this trace flag at any server you have. This would be my advice here because this enables that lightweight profiling infrastructure there and then you’ll see in a few minutes what it unleashes here. -So one thing that happens when I enable the lightweight profiling is that the sys.dm_exec_query_profiles DMV, which is something that actually populates the live query stats ability or feature of SSMS, now also is also populated with this lightweight profiling, which means that for all essence, we are now able to run a live query stats on all fashions at any given point in time, and this is extremely useful for let’s say a production DBA that someone calls and says, “Hey, you have a problem. To tap into running system and look at what it’s doing.”
+So one thing that happens when I enable the lightweight profiling is that the sys.dm_exec_query_profiles DMV, which is something that actually populates the live query stats ability or feature of SSMS, now also is also populated with this lightweight profiling, which means that for all essence, we are now able to run a live query stats on all fashions at any given point in time, and this is extremely useful for let’s say a production DBA that someone calls and says, “Hey, you have a problem. To tap into running system and look at what it’s doing.” +**Applies to: SQL Server 2016 (13.x) Service Pack 1 and later versions. Starting with SQL Server 2019 (15.x), this trace flag has no effect because lightweight profiling is enabled by default.**
Link: [Docs Trace Flags]
Link: https://support.microsoft.com/kb/3170113
Link: https://www.brentozar.com/archive/2017/10/get-live-query-plans-sp_blitzwho/
From 944805fcfcae36d021141bda8d7e26ada4fc5336 Mon Sep 17 00:00:00 2001 From: Brent Ozar Date: Sat, 7 Sep 2024 04:11:48 -0700 Subject: [PATCH 20/39] #232 trace flags Added 12618 and 12656. Closes #232. --- SQL Server Trace Flag.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/SQL Server Trace Flag.md b/SQL Server Trace Flag.md index 3086e20c..92e215e5 100644 --- a/SQL Server Trace Flag.md +++ b/SQL Server Trace Flag.md @@ -45,7 +45,7 @@ Source links: **Great thanks to:** - Aaron Morelli ([b](https://sqlcrossjoin.wordpress.com) | [@sqlcrossjoin](https://twitter.com/sqlcrossjoin)) - Steinar Andersen ([b](http://www.sqlservice.se/) | [@SQLSteinar](https://twitter.com/SQLSteinar)) -- Brent Ozar ([b](https://www.brentozar.com/) | [@BrentO](https://twitter.com/BrentO)) +- Brent Ozar ([b](https://www.brentozar.com/)) - Yusuf Anis - Lars Utterström - Martin Höglund @@ -5583,6 +5583,23 @@ Scope: global
SQL Server Version: >= 2022 + +#### Trace Flag: 12618 +Function: Introduces a new plan regression detection model for Automatic Plan Correction that includes multiple consecutive checks.
+Link: [SQL Server 2022 CU4 Documentation](https://learn.microsoft.com/en-us/troubleshoot/sql/releases/sqlserver-2022/cumulativeupdate4#2344871)
+Scope: global
+SQL Server Version: >= 2022 CU4 + + + +#### Trace Flag: 12656 +Function: For Automatic Plan Correction, introduces the ability to use a time-based plan regression check that will occur five minutes after a plan change is discovered, which avoids biasing the regression checks by queries that execute quickly.
+Link: [SQL Server 2022 CU4 Documentation](https://learn.microsoft.com/en-us/troubleshoot/sql/releases/sqlserver-2022/cumulativeupdate4#2344871)
+Scope: global
+SQL Server Version: >= 2022 CU4 + + + [Docs Trace Flags]:https://docs.microsoft.com/sql/t-sql/database-console-commands/dbcc-traceon-trace-flags-transact-sql [Query Store Trace Flags]:https://www.sqlskills.com/blogs/erin/query-store-trace-flags/ [DBCC TRACEON]:https://docs.microsoft.com/sql/t-sql/database-console-commands/dbcc-traceon-transact-sql From 9420b415038f266bedc5d47e88fb94023a83d856 Mon Sep 17 00:00:00 2001 From: abairmj Date: Sun, 20 Oct 2024 11:39:39 -0400 Subject: [PATCH 21/39] Update SQL Server Trace Flag.md Clarity on applicability of TF 8099 --- SQL Server Trace Flag.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SQL Server Trace Flag.md b/SQL Server Trace Flag.md index 92e215e5..f6225770 100644 --- a/SQL Server Trace Flag.md +++ b/SQL Server Trace Flag.md @@ -234,11 +234,11 @@ If you know behavior some of them please open an issue or contact me (taranov.pr - [Trace Flag 3427](#3427) (for SQL Server 2016) - [Trace Flag 3449](#3449) (for versions SQL Server 2012 SP3 CU3 or later or SQL Server 2014 SP1 CU7 or later) - [Trace Flag 6534](#6534) (for versions SQL Server 2012, 2014, 2016) (if use [spatial data types](https://docs.microsoft.com/sql/relational-databases/spatial/spatial-data-sql-server)) - - [Trace Flag 7412](#7412) (for versions >= SQL Server 2016 and < SQl Server 2019) + - [Trace Flag 7412](#7412) (for versions >= SQL Server 2016 and < SQL Server 2019) - [Trace Flag 7745](#7745) (for versions >= SQL Server 2016 and Query Store enabled) - [Trace Flag 7752](#7752) (for versions >= SQL Server 2016 and < 2019 and Query Store enabled) - [Trace Flag 7806](#7806) (for SQL Server Express Edition) - - [Trace Flag 8099](#8099) (for versions >= 2019 CU2) + - [Trace Flag 8099](#8099) (for versions 2019 CU2 and 2019 CU3 only) **Trace Flag 272** prevents identity gap after restarting SQL Server 2012 instance, critical for columns with identity and `tinyint` and `smallint` data types. (Demo for repeating this issue [here](https://github.com/ktaranov/sqlserver-kit/Errors/Identity_gap_sql_server_2012.sql)) @@ -285,7 +285,7 @@ Use this trace flag if SQL Server is experiencing high number of [QDS_LOADDB](ht **Trace Flag: 7806** enables a dedicated administrator connection ([DAC]) on SQL Server Express. -**Trace Flag: 8099** enables a spinlock contention fix for high-end systems running SQL Server 2019 (15.x) serving many concurrent users. +**Trace Flag: 8099** enables a spinlock contention fix for high-end systems running SQL Server 2019 (15.x) serving many concurrent users. Starting with SQL 2019 CU 4 this fix is enabled by default. From 0734add64cecf99ff1945f8496ee1bbf6d2cac44 Mon Sep 17 00:00:00 2001 From: Brent Ozar Date: Thu, 31 Oct 2024 15:44:55 -0700 Subject: [PATCH 22/39] Update SQL Server Trace Flag.md SQL Server 2019 CU29 added a handful! --- SQL Server Trace Flag.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/SQL Server Trace Flag.md b/SQL Server Trace Flag.md index f6225770..e20e43b2 100644 --- a/SQL Server Trace Flag.md +++ b/SQL Server Trace Flag.md @@ -3484,6 +3484,13 @@ Scope: global only
SQL Server Version: >= 2022 + +#### Trace Flag: 6981 +Function: Handle large objects (LOBs) when rebuilding the index that has an assertion issue (Location: blobbase.cpp:345; Expression: IS_ON (BLB_TI_END, m_status)). After turning on this trace flag and rebuilding the affected index, the assertion dump shouldn't be generated again. Added in SQL Server 2019 CU29.
+Link: [SQL Server 2019 CU29 Documentation](https://learn.microsoft.com/en-us/troubleshoot/sql/releases/sqlserver-2019/cumulativeupdate29#3370476)
+SQL Server Version: >= 2019 CU29 + + #### Trace Flag: 7103 **Undocumented trace flag**
@@ -3668,6 +3675,12 @@ Function: SQL 9 - Full-text index population for the indexed view is very slow +#### Trace Flag: 7617 +Function: Skip dropping full-text index fragments marked as deletion during a database recovery process. Added in SQL Server 2019 CU29.
+Link: [SQL Server 2019 CU29 Documentation](https://learn.microsoft.com/en-us/troubleshoot/sql/releases/sqlserver-2019/cumulativeupdate29#3540450) + + #### Trace Flag: 7646 Function: SQL 10 - Avoids blocking when using full text indexing. @@ -4065,6 +4078,12 @@ Function: Writes detailed information about Ms-DTC context & state changes to th Link: None + +#### Trace Flag: 8531 +Function: Fixes a contention issue with high KTM_RECOVERY_MANAGER wait times that you might encounter when running XA distributed transactions. Note: You need to turn on trace flag 8531 as a startup trace flag.
+Link: [SQL Server 2019 CU29 Documentation](https://learn.microsoft.com/en-us/troubleshoot/sql/releases/sqlserver-2019/cumulativeupdate29#3417392) + + #### Trace Flag: 8599 Function: Allows you to use a save-point within a distributed transaction
@@ -5598,6 +5617,12 @@ Link: [SQL Server 2022 CU4 Documentation](https://learn.microsoft.com/en-us/trou Scope: global
SQL Server Version: >= 2022 CU4 + +#### Trace Flag: 15915 +Function: Fixes a performance issue that you might encounter only when sp_lock is called frequently from multiple connections, which might cause a memory leak. The memory isn't cleaned up until you restart the SQL Server service. Added in SQL Server 2019 CU29.
+Link: [SQL Server 2019 CU29 Documentation](https://learn.microsoft.com/en-us/troubleshoot/sql/releases/sqlserver-2019/cumulativeupdate29#3180085)
+SQL Server Version: >= 2019 CU29 + [Docs Trace Flags]:https://docs.microsoft.com/sql/t-sql/database-console-commands/dbcc-traceon-trace-flags-transact-sql From 7b9838273a2c2ebd6562b576f43c1ef288572d30 Mon Sep 17 00:00:00 2001 From: SachinAkash01 Date: Tue, 10 Dec 2024 17:39:59 +0530 Subject: [PATCH 23/39] Add ballerina mssql connector to the SQL server drivers list --- SQL Server Drivers.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/SQL Server Drivers.md b/SQL Server Drivers.md index 72b2f906..43dec2e7 100644 --- a/SQL Server Drivers.md +++ b/SQL Server Drivers.md @@ -26,6 +26,12 @@ This driver is developed, tested, and supported by Microsoft. [Microsoft ADO.NET for SQL Server](https://docs.microsoft.com/en-us/sql/connect/ado-net/microsoft-ado-net-for-sql-server) | [Download .Net Driver](http://www.microsoft.com/net/download/) +### Ballerina +The Ballerina MSSQL Connector provides seamless integration with Microsoft SQL Server, allowing developers to work with databases efficiently in cloud-native and REST-based applications. This connector is an open-source project which is actively developed, tested, and supported by the Ballerina team. + +[ballerinax/mssql connector for SQL Server](https://central.ballerina.io/ballerinax/mssql/latest) | [GitHub](https://github.com/ballerina-platform/module-ballerinax-mssql) + + ### JDBC The JDBC SQL driver is a Java implementation of the TDS protocol, which is supported by all modern versions of SQL Server. This driver is developed, tested, and supported by Microsoft. From f0f80845d3c45763d043a17301f62a42becbc6be Mon Sep 17 00:00:00 2001 From: Imran Imtiaz Date: Sun, 15 Dec 2024 06:28:38 +0400 Subject: [PATCH 24/39] Update Adding_Trace_Flags_To_Startup_Parameters.sql --- ...ding_Trace_Flags_To_Startup_Parameters.sql | 54 +++++++------------ 1 file changed, 20 insertions(+), 34 deletions(-) diff --git a/Scripts/Adding_Trace_Flags_To_Startup_Parameters.sql b/Scripts/Adding_Trace_Flags_To_Startup_Parameters.sql index 18ac45be..9872dd1a 100644 --- a/Scripts/Adding_Trace_Flags_To_Startup_Parameters.sql +++ b/Scripts/Adding_Trace_Flags_To_Startup_Parameters.sql @@ -23,74 +23,61 @@ MODIFICATION LOG *******************************************************************************/ SET NOCOUNT ON; --- Declare and initialize variables. -DECLARE @MaxValue INT, - @SQLCMD VARCHAR(MAX), - @RegHive VARCHAR(50), - @RegKey VARCHAR(100), - @DebugLevel TINYINT; +DECLARE @MaxValue INT, + @SQLCMD VARCHAR(MAX), + @RegHive VARCHAR(50) = 'HKEY_LOCAL_MACHINE', + @RegKey VARCHAR(100) = 'Software\Microsoft\MSSQLSERVER\MSSQLServer\Parameters', + @DebugLevel TINYINT = 1; --- Registry hive and key for SQL Server startup parameters -SET @RegHive = 'HKEY_LOCAL_MACHINE'; -SET @RegKey = 'Software\Microsoft\MSSQLSERVER\MSSQLServer\Parameters'; --- Set debug level: 0 to execute changes, 1 to only show what will happen -SET @DebugLevel = 1; - --- Add the trace flags that you want to modify here. DECLARE @TraceFlags TABLE ( - TF INT, - enable BIT, - enable_on_startup BIT, - TF2 AS '-T' + CONVERT(VARCHAR(15), TF) + TF INT, + enable BIT, + enable_on_startup BIT, + TF2 AS '-T' + CONVERT(VARCHAR(15), TF) ); INSERT INTO @TraceFlags (TF, enable, enable_on_startup) -SELECT 1117, 1, 1 UNION ALL -SELECT 1118, 1, 1 UNION ALL -SELECT 1204, 0, 0 UNION ALL -SELECT 1222, 0, 0; +VALUES (1117, 1, 1), + (1118, 1, 1), + (1204, 0, 0), + (1222, 0, 0); --- Get all arguments/parameters when starting up the service. DECLARE @SQLArgs TABLE ( - Value VARCHAR(50), - Data VARCHAR(500), - ArgNum AS CONVERT(INT, REPLACE(Value, 'SQLArg', '')) + Value VARCHAR(50), + Data VARCHAR(500), + ArgNum AS CONVERT(INT, REPLACE(Value, 'SQLArg', '')) ); INSERT INTO @SQLArgs EXEC master.sys.xp_instance_regenumvalues @RegHive, @RegKey; --- Get the highest argument number that is currently set SELECT @MaxValue = MAX(ArgNum) FROM @SQLArgs; PRINT 'MaxValue: ' + CAST(@MaxValue AS VARCHAR); --- Disable specified trace flags SELECT @SQLCMD = 'DBCC TRACEOFF(' + STUFF((SELECT ',' + CONVERT(VARCHAR(15), TF) FROM @TraceFlags WHERE enable = 0 ORDER BY TF - FOR XML PATH(''), TYPE).value('.','varchar(max)'), 1, 1, '') + ', -1);' + FOR XML PATH(''), TYPE).value('.','varchar(max)'), 1, 1, '') + ', -1);'; IF @DebugLevel = 0 EXEC (@SQLCMD); PRINT 'Disable TFs Command: "' + @SQLCMD + '"'; --- Enable specified trace flags SELECT @SQLCMD = 'DBCC TRACEON(' + STUFF((SELECT ',' + CONVERT(VARCHAR(15), TF) FROM @TraceFlags WHERE enable = 1 ORDER BY TF - FOR XML PATH(''), TYPE).value('.','varchar(max)'), 1, 1, '') + ', -1);' + FOR XML PATH(''), TYPE).value('.','varchar(max)'), 1, 1, '') + ', -1);'; IF @DebugLevel = 0 EXEC (@SQLCMD); PRINT 'Enable TFs Command: "' + @SQLCMD + '"'; --- Prepare to update the registry with new trace flags DECLARE cSQLParams CURSOR LOCAL FAST_FORWARD FOR WITH cte AS ( - SELECT *, + SELECT * , ROW_NUMBER() OVER (ORDER BY ISNULL(ArgNum, 999999999), TF) - 1 AS RN FROM @SQLArgs arg FULL OUTER JOIN @TraceFlags tf ON arg.Data = tf.TF2 ), cte2 AS ( - SELECT ca.Value, ca.Data, + SELECT ca.Value, ca.Data, ROW_NUMBER() OVER (ORDER BY RN) - 1 AS RN2 FROM cte CROSS APPLY (SELECT ISNULL(Value, 'SQLArg' + CONVERT(VARCHAR(15), RN)), ISNULL(Data, TF2)) ca(Value, Data) @@ -113,7 +100,6 @@ END; CLOSE cSQLParams; DEALLOCATE cSQLParams; --- Delete extra SQLArg values if more trace flags were removed than added WHILE @MaxValue > @MaxRN2 BEGIN SET @Value = 'SQLArg' + CONVERT(VARCHAR(15), @MaxValue); From 384311f0e4beb507386aee3bad19d0ea611c8a15 Mon Sep 17 00:00:00 2001 From: Imran Imtiaz Date: Sun, 15 Dec 2024 06:29:53 +0400 Subject: [PATCH 25/39] Update dbo.sp_PrintString.sql Changes Made: 1. Improved Formatting: Enhanced readability by aligning declarations and simplifying inline comments. 2. Default Initializations: Added default initializations to avoid implicit NULL values. 3. Consistent Variable Naming: Ensured variables are consistently formatted and appropriately scoped. 4. Simplified Logic: Removed redundant checks and restructured for clarity. 5. Enhanced Line Splitting: Introduced better segmentation logic for PRINT operations. This procedure is robust for handling strings that exceed PRINT's 4,000-character limit, while respecting line breaks and special characters. --- Stored_Procedure/dbo.sp_PrintString.sql | 86 +++++++++---------------- 1 file changed, 31 insertions(+), 55 deletions(-) diff --git a/Stored_Procedure/dbo.sp_PrintString.sql b/Stored_Procedure/dbo.sp_PrintString.sql index 7fe8ccae..6633031c 100644 --- a/Stored_Procedure/dbo.sp_PrintString.sql +++ b/Stored_Procedure/dbo.sp_PrintString.sql @@ -2,93 +2,69 @@ IF OBJECT_ID('dbo.sp_PrintString', 'P') IS NULL EXEC ('CREATE PROCEDURE dbo.sp_PrintString AS SELECT 1'); GO -ALTER PROCEDURE dbo.sp_PrintString( - @str NVARCHAR(MAX) +ALTER PROCEDURE dbo.sp_PrintString ( + @str NVARCHAR(MAX) ) AS -/* -DECLARE @longStr NVARCHAR(MAX) = REPLICATE(N'R', 5000) + CAST(CHAR(13) AS NVARCHAR(MAX)) + REPLICATE(N'Я', 5000) + CAST(CHAR(13) + N'ё' AS NVARCHAR(MAX)); -PRINT('Microsoft PRINT with string truncating:'); -PRINT(@longStr); -PRINT('Right PRINT using dbo.sp_PrintString without string truncating:'); -EXEC dbo.sp_PrintString @str = @longStr; -*/ BEGIN - DECLARE @line NVARCHAR(MAX) - , @startLocation INT - , @length INT - , @totalLength INT - , @current INT; - - SELECT @startLocation = 1 - ,@totalLength = DATALENGTH(@str) - ,@current = 1 - ,@length = 0 + DECLARE @line NVARCHAR(MAX), + @startLocation INT = 1, + @length INT = 0, + @totalLength INT = DATALENGTH(@str), + @current INT = 1; DECLARE @PrintLine NVARCHAR(MAX) = - N'DECLARE @pos int = 1 - WHILE @pos <= LEN(@line) - BEGIN - PRINT SUBSTRING(@line, @pos, 4000); - SET @pos = @pos + 4000; - END;' + N' + DECLARE @pos INT = 1 + WHILE @pos <= LEN(@line) + BEGIN + PRINT SUBSTRING(@line, @pos, 4000); + SET @pos = @pos + 4000; + END;'; WHILE @current <= @totalLength BEGIN - IF ( - SUBSTRING(@str, @current, 2) IN ( - CHAR(0x0D) + CHAR(0x0A) - ,CHAR(0x0A) + CHAR(0x0D) - ) - ) + IF SUBSTRING(@str, @current, 2) IN ( + CHAR(0x0D) + CHAR(0x0A), + CHAR(0x0A) + CHAR(0x0D) + ) BEGIN IF @length <= 0 PRINT ''; ELSE - BEGIN -- line + BEGIN SELECT @line = SUBSTRING(@str, @startLocation, @length); - - EXEC sp_executesql @PrintLine - ,N'@line NVARCHAR(max)' - ,@line; + EXEC sp_executesql @PrintLine, N'@line NVARCHAR(MAX)', @line; END - SELECT @startLocation = @current + 2 - , @current = @current + 2 - , @length = 0; + SELECT @startLocation = @current + 2, + @current = @current + 2, + @length = 0; CONTINUE; END - ELSE IF ( - SUBSTRING(@str, @current, 1) IN ( - CHAR(0x0D) - ,CHAR(0x0A) - ) - ) + ELSE IF SUBSTRING(@str, @current, 1) IN (CHAR(0x0D), CHAR(0x0A)) BEGIN IF @length <= 0 PRINT ''; ELSE BEGIN SELECT @line = SUBSTRING(@str, @startLocation, @length); - - EXEC sp_executesql @PrintLine - ,N'@line NVARCHAR(max)' - ,@line; + EXEC sp_executesql @PrintLine, N'@line NVARCHAR(MAX)', @line; END - SELECT @startLocation = @current + 1 - ,@current = @current + 1 - ,@length = 0; + SELECT @startLocation = @current + 1, + @current = @current + 1, + @length = 0; CONTINUE; END - SELECT @current = @current + 1 - , @length = @length + 1; + SELECT @current = @current + 1, + @length = @length + 1; END - IF (@startLocation <= DATALENGTH(@str)) + IF @startLocation <= DATALENGTH(@str) PRINT SUBSTRING(@str, @startLocation, DATALENGTH(@str)); END; GO From c100e2dddbbf1bf99b6c07a1e5db5ca5f4d1d49d Mon Sep 17 00:00:00 2001 From: Alex Bochkov Date: Sat, 1 Feb 2025 11:32:26 -0800 Subject: [PATCH 26/39] Add the SSMS addin I maintain --- SSMS/SSMS_Addins.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/SSMS/SSMS_Addins.md b/SSMS/SSMS_Addins.md index 5c0db34f..985fc505 100644 --- a/SSMS/SSMS_Addins.md +++ b/SSMS/SSMS_Addins.md @@ -43,6 +43,7 @@ Complete list of useful and must have add-ins for SQL Server Management Studio - | [SSMS Lizard](#ssms-lizard) | [SSMS Lizard] | 2020-06-15 | 2018-2018 | Lizard Labs Software | Yes | No | | [SSMS Object Explorer Menu](#ssms-menu) | [SSMS Object Explorer Menu] | 2023-07-10 | 2018-2022 | Daniel Brink | Yes | No | | [SQL Shades dark mode](#sql-shades) | [SQL Shades] | 2022-08-03 | 2018-2022 | Wrism Innovations | Yes | No | +| [Axial SQL Tools](#axial-sql-tools) | [Axial SQL Tools] | 2025-01-26 | 2022-2025 | Alex Bochkov | Yes | No | @@ -714,6 +715,31 @@ Price: No Adds a true dark theme to SSMS. + +## Axial SQL Tools +Download page: [Axial SQL Tools]
+Release date: 2025-01-26
+Support Version: 20+
+Developer: Alex Bochkov
+Free version: Yes
+Price: No + +Axial SQL Tools is a productivity add-in for SQL Server Management Studio 20/21, designed to streamline your workflow and address common limitations in SSMS. Built from the personal experience of a seasoned SQL Server engineer, this tool incorporates community feedback to continuously improve and simplify routine tasks. + +Main Features: +- Transaction Warning: Instantly see if you’ve left any transactions open. +- Precise Execution Time: Monitor query execution times down to the millisecond on the status bar. +- Format Any TSQL Code: Validate and format your TSQL code using the Microsoft TSQL parser for improved readability. +- Query Templates and Snippets: Access a library of query templates for common tasks, saving time on routine queries. +- Export Grid to Excel: Quickly export grid results directly into an Excel file. +- Export Grid to Email: Export grid results and send the file via email directly from SSMS. +- Export Grid as Temp Table: Convert grid results into temporary tables using generated INSERT statements. +- Script Selected Object Definition: Easily generate scripts for the definitions of selected objects from your query. +- Server Health Dashboard: Get a quick overview of the server’s key metrics. +- Right Alignment for Numeric Values in Grid: Automatically align numeric values to the right in the grid for better readability. +- BULK Data Transfer Between Two Open Connections: Seamlessly transfer bulk data between two open connections with a single click. +- Query History: Maintain a detailed log of executed queries for auditing and easy retrieval. + [SSMSBoost]:http://www.ssmsboost.com/ [SQL Refactor Studio]: https://sqlrefactorstudio.com/ @@ -761,3 +787,4 @@ Adds a true dark theme to SSMS. [DbForge Search Download]:https://www.devart.com/dbforge/sql/search/searchsql22std.exe [SSMS Lizard]:https://www.lizard-labs.com/sql_server_management_studio_ssms_extesnsion_lizard.aspx [SQL Shades]:https://www.sqlshades.com/ +[Axial SQL Tools]:(https://github.com/Axial-SQL/AxialSqlTools) From fa31b06d83ee4026530534450b54e177dbc58aa1 Mon Sep 17 00:00:00 2001 From: Abair Date: Wed, 23 Apr 2025 14:51:40 -0400 Subject: [PATCH 27/39] Update SQL Server Trace Flag.md added info for trace flag 6773 --- SQL Server Trace Flag.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/SQL Server Trace Flag.md b/SQL Server Trace Flag.md index e20e43b2..b0b9f513 100644 --- a/SQL Server Trace Flag.md +++ b/SQL Server Trace Flag.md @@ -3465,7 +3465,14 @@ Link: https://support.microsoft.com/kb/4517771
Scope: global only
SQL Server Version: >= 2019 CU1, >= 2017 CU18, >= 2016 SP1 CU10 - + + +#### Trace Flag: 6773 +Function: Enables a fix to address an out of memory issue that occurs when bulk copying XML data where the sum of all XML attributes are > 2MB. This flag can help in circumstances where a client is running bulk copy of XML data and it receives sql error 6303 "XML parsing: Document parsing required too much memory".
+Link: https://support.microsoft.com/en-us/topic/kb4019125-fix-system-center-configuration-manager-replication-process-by-using-bcp-apis-fails-when-there-is-a-large-value-in-an-xml-column-53a969d5-801c-63ab-a557-bc89fe264394
+SQL Server Version: >= 2016 CU7, >= 2014 SP2 CU6, >= 2014 SP1 CU13, >= 2012 SP3 CU9 + + #### Trace Flag: 6950 **Undocumented trace flag**
From 1e8cd4f4c3ff47007c6dd5c5b9b60ade078d38e1 Mon Sep 17 00:00:00 2001 From: Konstantin Taranov Date: Thu, 24 Apr 2025 16:39:57 +0300 Subject: [PATCH 28/39] Add Abair into thanks section --- SQL Server Trace Flag.md | 1 + 1 file changed, 1 insertion(+) diff --git a/SQL Server Trace Flag.md b/SQL Server Trace Flag.md index b0b9f513..8aef1d18 100644 --- a/SQL Server Trace Flag.md +++ b/SQL Server Trace Flag.md @@ -83,6 +83,7 @@ Source links: - Wilfred van Dijk - Tracy Boggiano ([b](http://databasesuperhero.com) | [t](https://twitter.com/TracyBoggiano)) - Danilo Zocco (https://github.com/CrazySwimmer) +- Abair (https://github.com/abair34) From f0c0a100e1d21dbbc1cc38972236c6a70b62f79d Mon Sep 17 00:00:00 2001 From: Abair Date: Thu, 24 Apr 2025 13:55:37 -0400 Subject: [PATCH 29/39] Update SQL Server Trace Flag.md --- SQL Server Trace Flag.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SQL Server Trace Flag.md b/SQL Server Trace Flag.md index 8aef1d18..f14ebd75 100644 --- a/SQL Server Trace Flag.md +++ b/SQL Server Trace Flag.md @@ -83,7 +83,7 @@ Source links: - Wilfred van Dijk - Tracy Boggiano ([b](http://databasesuperhero.com) | [t](https://twitter.com/TracyBoggiano)) - Danilo Zocco (https://github.com/CrazySwimmer) -- Abair (https://github.com/abair34) +- Michael Abair (https://github.com/abair34) From 69a2eb515c3f5f386e3968e86a5aaf04edcf16dc Mon Sep 17 00:00:00 2001 From: Konstantin Taranov Date: Mon, 9 Jun 2025 15:44:47 +0300 Subject: [PATCH 30/39] Add 12502 trace flag Thanks to Mikulas Mraz --- SQL Server Trace Flag.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/SQL Server Trace Flag.md b/SQL Server Trace Flag.md index f14ebd75..81d38c77 100644 --- a/SQL Server Trace Flag.md +++ b/SQL Server Trace Flag.md @@ -84,6 +84,7 @@ Source links: - Tracy Boggiano ([b](http://databasesuperhero.com) | [t](https://twitter.com/TracyBoggiano)) - Danilo Zocco (https://github.com/CrazySwimmer) - Michael Abair (https://github.com/abair34) +- Mikulas Mraz (https://github.com/Prohiller) @@ -5602,6 +5603,20 @@ Scope: global or session
SQL Server Version: >= 2019 CU9, >= 2017 CU21 +### Trace Flag: 12502 +Function: Disables external authorization policies for on-premises SQL Server instances. +Use this flag when you see increased PREEMPTIVE_OS_QUERYREGISTRY waits to occur. Due to a bug a SQL Server might lookup Windows Registry values even for a simple queries which do not work with operating system at all. +Link: [Docs Trace Flags](https://docs.microsoft.com/sql/t-sql/database-console-commands/dbcc-traceon-trace-flags-transact-sql) +Link: [SQL Server 2022 CU5 Documentation](https://learn.microsoft.com/en-us/troubleshoot/sql/releases/sqlserver-2022/cumulativeupdate5#2351584) +Scope: global
+SQL Server Version: >= 2022 CU5 + + +Note: In my case vast majority of queries executed against SQL Server started looking up non-existing registry value at: +`HKLM\Software\Microsoft\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQLServer\PurviewConfig` +so this buggy behavior might be triggered only after other software gets integrated with SQL Server 2022. + + #### Trace Flag: 12606 Function: Enables Query Store for secondary replicas.
From 465e8885215d385059c0dfa230be7d33ab143c73 Mon Sep 17 00:00:00 2001 From: DataModelingTools <46059055+datensen@users.noreply.github.com> Date: Fri, 20 Jun 2025 10:14:29 +0200 Subject: [PATCH 31/39] Update README.md Added Luna Modeler - database modeling tool --- Utilities/README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Utilities/README.md b/Utilities/README.md index a293961e..628e4570 100644 --- a/Utilities/README.md +++ b/Utilities/README.md @@ -217,6 +217,7 @@ Utility types (main purpose), in braces `{}` current counts: | [EMS Data Comparer](#ems-data-comparer) | No | No | [DC] | [EMS Data Comparer] | 2012-11-16 | EMS | | No | $47 | | [NitroAccelerator](#nitroaccelerator) | No | No | [?] | [NitroAccelerator] | 2016-07-10 | Nitrosphere | | No | $1265 | | [ERwin Data Modeler](#erwin-data-modeler) | Oracle,MySQL,PostgreSQL,Other | No | [DA] | [ERwin Data Modeler] | 2016-06-03 | ERwin | | No | $810 | +| [Luna Modeler](#luna-modeler) | Oracle,MySQL,PostgreSQL,Other | Linux,Mac | [DA] | [Luna Modeler] | 2022-10-05 | Ideamerit | | No | $99 | | [Toad Data Point](#toad-data-point) | Oracle,MySQL,PostgreSQL,Other | No | [?] | [Toad Data Point] | 2016-06-16 | Quest Software | | No | ? | | [SQL Power Architect](#sql-power-architect) | Oracle,MySQL,PostgreSQL,Other | Linux,Mac | [DA] | [SQL Power Architect] | 2016-02-11 | SQLPower | | Yes | $995 | | [DbWrench](#dbwrench) | Oracle,MySQL,PostgreSQL,Other | Linux,Mac | [DA] | [DbWrench] | 2019-09-17 | Nizana Systems | | No | $99 | @@ -3112,6 +3113,18 @@ Price: $810 ERwin Data Modeler is an industry-leading data modeling solution that provides a simple, visual interface to manage your complex data environment +## Luna Modeler + +Download page: [Luna Modeler]
+Release date: 2022-10-05
+Support Version: 2019/2022
+Author: Ideamerit
+Free version: No
+Price: $99 + +Luna Modeler is a database design and data modeling tool for relational databases. With Luna Modeler, you can create ER diagrams, design and visualize database structures, generate SQL scripts, and document your data models. + + ## Toad Data Point Download page: [Toad Data Point]
@@ -6396,6 +6409,7 @@ SQLWATCH is an Open Source (MIT License) Real-Time monitoring solution for SQL S [EMS Data Comparer]:http://www.sqlmanager.net/en/products/mssql/datacomparer [NitroAccelerator]:http://nitrosphere.com/nitroaccelerator/ [ERwin Data Modeler]:http://erwin.com/products/data-modeler +[Luna Modeler]:https://www.datensen.com/luna-modeler-for-relational-databases.html [Toad Data Point]:https://www.quest.com/products/toad-data-point/ [SQL Power Architect]:http://www.sqlpower.ca/page/architect [DbWrench]:http://www.dbwrench.com/ From 4663dfd1628d52c683dc640b34164dd4072c9158 Mon Sep 17 00:00:00 2001 From: dlucre Date: Thu, 24 Jul 2025 09:44:43 +1000 Subject: [PATCH 32/39] The Enable_Statement was selecting the DisableTriggerStatement column. Seems like a copy/paste error. --- Scripts/Disable_Enable_All_Triggers_In_Database.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/Disable_Enable_All_Triggers_In_Database.sql b/Scripts/Disable_Enable_All_Triggers_In_Database.sql index fe9feb6f..fd6d032b 100644 --- a/Scripts/Disable_Enable_All_Triggers_In_Database.sql +++ b/Scripts/Disable_Enable_All_Triggers_In_Database.sql @@ -33,7 +33,7 @@ EXEC sys.sp_executesql @Disable_Statement; -- Perpare Variable Script for Execution DECLARE @Enable_Statement nvarchar(max) = ( - SELECT tmp.DisableTriggerStatement + CHAR(10) AS "data()" + SELECT tmp.EnableTriggerStatementTriggerStatement + CHAR(10) AS "data()" FROM #Triggers tmp FOR XML PATH('') ); From c32420ad3fe8f09fe15a0a96a5cb75ba80366c11 Mon Sep 17 00:00:00 2001 From: dlucre Date: Thu, 24 Jul 2025 09:49:54 +1000 Subject: [PATCH 33/39] Revert "The Enable_Statement was selecting the DisableTriggerStatement column. Seems like a copy/paste error." This reverts commit 4663dfd1628d52c683dc640b34164dd4072c9158. Accidentally committed a typo. --- Scripts/Disable_Enable_All_Triggers_In_Database.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/Disable_Enable_All_Triggers_In_Database.sql b/Scripts/Disable_Enable_All_Triggers_In_Database.sql index fd6d032b..fe9feb6f 100644 --- a/Scripts/Disable_Enable_All_Triggers_In_Database.sql +++ b/Scripts/Disable_Enable_All_Triggers_In_Database.sql @@ -33,7 +33,7 @@ EXEC sys.sp_executesql @Disable_Statement; -- Perpare Variable Script for Execution DECLARE @Enable_Statement nvarchar(max) = ( - SELECT tmp.EnableTriggerStatementTriggerStatement + CHAR(10) AS "data()" + SELECT tmp.DisableTriggerStatement + CHAR(10) AS "data()" FROM #Triggers tmp FOR XML PATH('') ); From ef4ab5992a9dc02dff0a23d13618bf91bbee2f10 Mon Sep 17 00:00:00 2001 From: dlucre Date: Thu, 24 Jul 2025 09:54:28 +1000 Subject: [PATCH 34/39] Fix Enable_Statement to select the correct EnableTriggerStatement instead of DisableTriggerStatement, Fix a couple of typing mistakes --- Scripts/Disable_Enable_All_Triggers_In_Database.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Scripts/Disable_Enable_All_Triggers_In_Database.sql b/Scripts/Disable_Enable_All_Triggers_In_Database.sql index fe9feb6f..5801e967 100644 --- a/Scripts/Disable_Enable_All_Triggers_In_Database.sql +++ b/Scripts/Disable_Enable_All_Triggers_In_Database.sql @@ -21,7 +21,7 @@ INNER JOIN sys.tables ta ON ta.object_id = tr.parent_id INNER JOIN sys.schemas sc ON sc.schema_id = ta.schema_id WHERE tr.is_disabled = 0; --- Perpare Variable Script for Execution +-- Prepare Variable Script for Execution DECLARE @Disable_Statement nvarchar(max) = ( SELECT tmp.DisableTriggerStatement + CHAR(10) AS "data()" FROM #Triggers tmp @@ -31,9 +31,9 @@ DECLARE @Disable_Statement nvarchar(max) = ( -- Execute SQL EXEC sys.sp_executesql @Disable_Statement; --- Perpare Variable Script for Execution +-- Prepare Variable Script for Execution DECLARE @Enable_Statement nvarchar(max) = ( - SELECT tmp.DisableTriggerStatement + CHAR(10) AS "data()" + SELECT tmp.EnableTriggerStatement + CHAR(10) AS data FROM #Triggers tmp FOR XML PATH('') ); From 05431827a54c5cdb9c1928c416771880cba3a4f8 Mon Sep 17 00:00:00 2001 From: Brent Ozar Date: Tue, 19 Aug 2025 07:18:26 -0700 Subject: [PATCH 35/39] Trace flags 4631 and 4675 --- SQL Server Trace Flag.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/SQL Server Trace Flag.md b/SQL Server Trace Flag.md index 81d38c77..9f741171 100644 --- a/SQL Server Trace Flag.md +++ b/SQL Server Trace Flag.md @@ -3343,6 +3343,21 @@ Function: SQL 9 – After 4610 & 4618 you can still customize the quota for Toke Link: https://support.microsoft.com/kb/959823 + +#### Trace Flag: 4631 +Function: Disables SHA2_256/AES256 for hashing passwords that generate encryption keys. Starting in SQL Server 2017 (14.x), SHA2 is used instead of SHA1. This means extra steps might be necessary to have your SQL Server 2017 (14.x) installation decrypt items that were encrypted by SQL Server 2016 (13.x)
+Link: [Encryption Changes in SQL Server 2017 CU2](https://learn.microsoft.com/en-us/sql/relational-databases/security/encryption/create-identical-symmetric-keys-on-two-servers?view=sql-server-ver17#encryption-changes-in-sql-server-2017-cu2)
+Link: [KB 4053407: SQL Server 2017 cannot decrypt data encrypted by earlier versions of SQL Server using the same symmetric key](https://support.microsoft.com/kb/4053407)
+Scope: global only + + + +#### Trace Flag: 4675 +Function: Enable checks on create credential for managed identity on a SQL Server on Azure VM if Microsoft Entra authentication is enabled. Enables diagnostics for the CREATE CREDENTAIL WITH IDENTITY = 'Managed Identity' statement. The trace flag provides information about the primary managed identity and its setting for SQL Server on Azure VM.
+Link: [DBCC TRACEON Trace Flags](https://learn.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-traceon-trace-flags-transact-sql?view=sql-server-ver17)
+Scope: global or session + + #### Trace Flag: 5004 Function: Pauses TDE encryption scan and causes encryption scan worker to exit without doing any work. From a5e27335b0285df3c261668d79276054203e7214 Mon Sep 17 00:00:00 2001 From: aarunreddy <66240041+aarunreddy@users.noreply.github.com> Date: Tue, 16 Sep 2025 11:08:04 -0700 Subject: [PATCH 36/39] =?UTF-8?q?Update=20Backup=5FRestore=5FWhat=E2=80=99?= =?UTF-8?q?s=5FMy=5FStatus.sql?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add log backup and log restore status --- "Scripts/Backup_Restore_What\342\200\231s_My_Status.sql" | 2 ++ 1 file changed, 2 insertions(+) diff --git "a/Scripts/Backup_Restore_What\342\200\231s_My_Status.sql" "b/Scripts/Backup_Restore_What\342\200\231s_My_Status.sql" index 9d760042..c7560aa7 100644 --- "a/Scripts/Backup_Restore_What\342\200\231s_My_Status.sql" +++ "b/Scripts/Backup_Restore_What\342\200\231s_My_Status.sql" @@ -28,4 +28,6 @@ FROM sys.dm_exec_requests r WHERE command IN ( 'RESTORE DATABASE' , 'BACKUP DATABASE' + ,'RESTORE LOG' + ,'BACKUP LOG' ); From 750c2b48db5401870321bbe79d5472012ea2f9f9 Mon Sep 17 00:00:00 2001 From: samhaese <63563702+samhaese@users.noreply.github.com> Date: Fri, 26 Sep 2025 12:17:53 -0700 Subject: [PATCH 37/39] Typo: Change 'throw' to 'through' --- SQL Server Name Convention and T-SQL Programming Style.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SQL Server Name Convention and T-SQL Programming Style.md b/SQL Server Name Convention and T-SQL Programming Style.md index 5f01ff49..7bbdc746 100644 --- a/SQL Server Name Convention and T-SQL Programming Style.md +++ b/SQL Server Name Convention and T-SQL Programming Style.md @@ -325,7 +325,7 @@ SQL Server T-SQL Coding Conventions, Best Practices, and Programming Guidelines. 4. All [Service Broker statements](https://docs.microsoft.com/sql/t-sql/statements/send-transact-sql): > If the SEND statement isn't the first statement in a batch or stored procedure, the preceding statement must be terminated with a semicolon (;). - - All script files should end with `GO` and line break. This is neccesary for batching scripts run throw `sqlcmd` or another tools. + - All script files should end with `GO` and line break. This is neccesary for batching scripts run through `sqlcmd` or another tools. - Keywords should be in **UPPERCASE**: `SELECT`, `FROM`, `GROUP BY` etc. This increases the readability of the code. - Data types declaration should be in **lowercase**: `varchar(30)`, `int`, `real`, `nvarchar(max)` etc. More details [here](https://www.sentryone.com/blog/aaronbertrand/backtobasics-lower-case-data-types). From c3ec2201f4d12cf4b1a61c4659173c572cf8d582 Mon Sep 17 00:00:00 2001 From: samhaese <63563702+samhaese@users.noreply.github.com> Date: Fri, 26 Sep 2025 12:19:30 -0700 Subject: [PATCH 38/39] Typo: change neccesary to necessary --- SQL Server Name Convention and T-SQL Programming Style.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SQL Server Name Convention and T-SQL Programming Style.md b/SQL Server Name Convention and T-SQL Programming Style.md index 7bbdc746..2e63ae48 100644 --- a/SQL Server Name Convention and T-SQL Programming Style.md +++ b/SQL Server Name Convention and T-SQL Programming Style.md @@ -325,7 +325,7 @@ SQL Server T-SQL Coding Conventions, Best Practices, and Programming Guidelines. 4. All [Service Broker statements](https://docs.microsoft.com/sql/t-sql/statements/send-transact-sql): > If the SEND statement isn't the first statement in a batch or stored procedure, the preceding statement must be terminated with a semicolon (;). - - All script files should end with `GO` and line break. This is neccesary for batching scripts run through `sqlcmd` or another tools. + - All script files should end with `GO` and line break. This is necessary for batching scripts run through `sqlcmd` or another tools. - Keywords should be in **UPPERCASE**: `SELECT`, `FROM`, `GROUP BY` etc. This increases the readability of the code. - Data types declaration should be in **lowercase**: `varchar(30)`, `int`, `real`, `nvarchar(max)` etc. More details [here](https://www.sentryone.com/blog/aaronbertrand/backtobasics-lower-case-data-types). From a81aa19e5f62772144f948b099953dd9c0daa2a6 Mon Sep 17 00:00:00 2001 From: Brent Ozar Date: Mon, 27 Oct 2025 13:33:44 -0400 Subject: [PATCH 39/39] Trace flag 12310 --- SQL Server Trace Flag.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/SQL Server Trace Flag.md b/SQL Server Trace Flag.md index 9f741171..452038d8 100644 --- a/SQL Server Trace Flag.md +++ b/SQL Server Trace Flag.md @@ -5570,6 +5570,14 @@ Scope: global or session
SQL Server Version: >= 2019 CU9, >= 2017 CU21 + +#### Trace Flag: 12310 +Function: Availability groups are designed with flow control gates on the primary replica to avoid excessive resource consumption, such as network and memory resources, on all availability replicas. SQL Server 2022 (16.x) increases the limits to the number of messages that each gate allows. By using trace flag 12310, the increased limit is also available to the following versions of SQL Server: SQL Server 2019 (15.x) CU9, SQL Server 2017 (14.x) CU18, SQL Server 2016 (13.x) SP1 CU16.
+Link: https://learn.microsoft.com/en-us/sql/database-engine/availability-groups/windows/monitor-performance-for-always-on-availability-groups?tabs=new-limits#flow-control-gates
+Scope: global
+SQL Server Version: >= 2019 CU9, >= 2017 CU18, >= 2016 SP1 CU16 + + #### Trace Flag: 12311 Function: After TF [12306](#12306) is enabled, you can further enable 12311 trace flag that represent maximum group commit times of **1ms**. This TF is additive whith [12312](#12312), [12314](#12314), and [12318](#12318). The maximum group commit time setting is capped at 10ms. However, these should not be repeated. For example, do not specify the same TF more than one time.