GithubHelp home page GithubHelp logo

michelleufford / sql-scripts Goto Github PK

View Code? Open in Web Editor NEW
234.0 234.0 97.0 52 KB

Repo for Microsoft SQL Server scripts. These are targeted at both DBAs/admins and at database developers.

Home Page: http://sqlfool.com

License: Apache License 2.0

SQLPL 60.06% PLSQL 10.21% PLpgSQL 29.73%

sql-scripts's People

Contributors

michelleufford avatar pinkduck avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sql-scripts's Issues

Violation of PRIMARY KEY constraint 'PK_indexDefragStatus_v40'

I am seeing the exception:

Looping through our list of databases and checking for fragmentation...
...
working on DBNAME...
Violation of PRIMARY KEY constraint 'PK_indexDefragStatus_v40'. Cannot insert duplicate key in object 'dbo.dba_indexDefragStatus'. The duplicate key value is (9, 50099219, 1, 1). (Line Number: 442)

When executing the SELECT portion of the script on Line 442, I get two rows:

databaseID	databaseName	objectID	indexID	partitionNumber	fragmentation	page_count	range_scan_count	scanDate
9	  	[DBNAME]	50099219	1	1	61.1909650924025	1948	0	2018-07-26 12:19:31.040
9	  	[DBNAME]	50099219	1	1	61.1909650924025	1948	84	2018-07-26 12:19:31.040

These two rows have the same values for all the primary keys in the table (databaseID, indexID, objectID, partitionNumber).

Is this a bug in the script, or is there something wrong the data in the instance I'm running the script on?

Error message: Cannot insert the value NULL into column 'objectName', table 'DBA.dbo.dba_indexDefragLog'; column does not allow nulls."

Hi,

I got the error in the subject line a few weeks back. It might be applicable to others that have the same issue.

In my case it's because I scan a large number of databases and some indexes have been dropped during the scan (due to maintenance processes from a 3rd party application) and no longer available in sys.objects. When dba_indexDefragStatus needs to be updated with the objectName (for instance) from sys.objects it leaves it as null. Therefore when updating dba_indexDefragLog from dba_indexDefragStatus the insert fails because the objectName is null.

The solution is change the Insert statement at the /* Log our actions */ section.
Original section
/ * Log our actions */
INSERT INTO dbo.dba_indexDefragLog
(
databaseID
, databaseName
, objectID
, objectName
, indexID
, indexName
, partitionNumber
, fragmentation
, page_count
, dateTimeStart
, sqlStatement
)
SELECT
@databaseid
, @databaseName
, @objectid
, @objectName
, @indexid
, @indexName
, @partitionNumber
, @fragmentation
, @pageCount
, @datetimestart
, @sqlcommand;
Fix
Add WHERE @objectName IS NOT null

Indexes being built multiple times in a single run

This code seems to have a bug. If you dump the Defrag log, you will see that sometimes the Index Name and the SQL to rebuild or reorganize that index do not match. It turns out, that the SQL command to do the "fix" is from the last index that was determined to need a fix.
Here is SQL to see the problem. It extracts the index name from the Reindex/Reorg SQL command stored to the index that was being evaluated and dumps the ones that don't match:

SELECT TOP (1000) [indexDefrag_id]
,[databaseName]
,[objectName]
,[indexName]
,substring(substring(sqlstatement,CHARINDEX('[',sqlstatement) ,1000),1,CHARINDEX(']',substring(sqlstatement,CHARINDEX('[',sqlstatement) ,1000))) alteredIndexName
,[sqlStatement]
FROM [ITS_Maintenance].[dbo].[dba_indexDefragLog]
where
substring(substring(sqlstatement,CHARINDEX('[',sqlstatement) ,1000),1,CHARINDEX(']',substring(sqlstatement,CHARINDEX('[',sqlstatement) ,1000)))
<> indexName
order by indexDefrag_id desc

The bug seems occure when an index is being evaluated and turns out not to need a fix right now.

    Whenever it passes through this code:
        ELSE
            /* Print an error message if any indexes happen to not meet the criteria above */
            IF @printCommands = 1 OR @debugMode = 1
                RAISERROR('We are unable to defrag this index.', 0, 42) WITH NOWAIT;

If it passes through the code above, the @sqlcommand is never updated from the previous index in the loop, and contains the SQL for the last key that needed a fix. It then falls down into the EXECUTE code. That code has no logic to catch the situation and executes whatever is in @sqlcommand, which is not the current index being evaluated and had already been executed. It then logs that an index was fixed under the name of the current index with the SQL command for a different index.

In my database, several indexes are being rebuilt over and over again, a great waste of resources.

I put in a fix for my system. Inside the BEGIN-END block for the if @executeSQL = 1 I added a check to see if @sqlcommand <> ''. If emtpy then don't execute the SQL but do execute the status update. The same in the print only BEGIN-END block. After it leaves this nested IF and is ready to loop to the next index, I set @sqlcommand to empty.

This fix is not perfect because it puts a defrag date in the log for an index that was determined did not need it. But, you can tell in the log because the SQL command is empty.

My fix trying tonight (scan for RLO 09/24/2020 - not test yet, but will give you an idea of what I think is going on here):

        /* Are we executing the SQL?  IF so, do it */
        IF @executeSQL = 1 
        BEGIN
            -- RLO 09/24/2020 Added to prevent previous SQL command from being executed again if next index was determined not needing a fix
            if @sqlCommand <> ''  
			BEGIN                 -- RLO 09/24/2020 
	                SET @debugMessage = 'Executing: ' + @sqlCommand;
	                
	                /* Print the commands we're executing if specified to do so */
	                IF @printCommands = 1 OR @debugMode = 1
	                    RAISERROR(@debugMessage, 0, 42) WITH NOWAIT;
	
	                /* Grab the time for logging purposes */
	                SET @datetimestart  = GETDATE();
	
	                /* Log our actions */
	                INSERT INTO dbo.dba_indexDefragLog
	                (
	                      databaseID
	                    , databaseName
	                    , objectID
	                    , objectName
	                    , indexID
	                    , indexName
	                    , partitionNumber
	                    , fragmentation
	                    , page_count
	                    , DATETIMEStart
	                    , sqlStatement
	                )
	                SELECT
	                      @databaseID
	                    , @databaseName
	                    , @objectID
	                    , @objectName
	                    , @indexID
	                    , @indexName
	                    , @partitionNumber
	                    , @fragmentation
	                    , @pageCount
	                    , @datetimestart
	                    , @sqlCommand;
	
	                SET @indexDefrag_id = SCOPE_IDENTITY();
	
	                /* Wrap our execution attempt in a TRY/CATCH and log any errors that occur */
	                BEGIN TRY
	
	                    /* Execute our defrag! */
	                    EXECUTE sp_executesql @sqlCommand;
	                    SET @dateTimeEnd = GETDATE();
	                    
	                    /* Update our log with our completion time */
	                    UPDATE dbo.dba_indexDefragLog
	                    SET dateTimeEnd = @dateTimeEnd
	                        , durationSeconds = DATEDIFF(second, @datetimestart, @dateTimeEnd)
	                    WHERE indexDefrag_id = @indexDefrag_id;
	                END TRY
	                BEGIN CATCH
	
	                    /* Update our log with our error message */
	                    UPDATE dbo.dba_indexDefragLog
	                    SET dateTimeEnd = GETDATE()
	                        , durationSeconds = -1
	                        , errorMessage = ERROR_MESSAGE()
	                    WHERE indexDefrag_id = @indexDefrag_id;
	
	                    IF @debugMode = 1 
	                        RAISERROR('  An/error has occurred executing this command! Please review the dba_indexDefragLog table for details.'
	                            , 0, 42) WITH NOWAIT;
	
	                END CATCH
			END -- RLO 09/24/2020

            /* Just a little breather for the server */
            WAITFOR DELAY @defragDelay;

            UPDATE dbo.dba_indexDefragStatus
            SET defragDate = GETDATE()
                , printStatus = 1
            WHERE databaseID       = @databaseID
              AND objectID         = @objectID
              AND indexID          = @indexID
              AND partitionNumber  = @partitionNumber;

        END
        ELSE
        /* Looks like we're not executing, just printing the commands */
        BEGIN
            if @sqlCommand <> ''  --RLO 09/24/2020 
			BEGIN --RLO 09/24/2020 
					IF @debugMode = 1 RAISERROR('  Printing SQL statements...', 0, 42) WITH NOWAIT;
	                
	                IF @printCommands = 1 OR @debugMode = 1 
	                    PRINT ISNULL(@sqlCommand, 'error!');
			END --RLO 09/24/2020 

            UPDATE dbo.dba_indexDefragStatus
            SET printStatus = 1
            WHERE databaseID       = @databaseID
              AND objectID         = @objectID
              AND indexID          = @indexID
              AND partitionNumber  = @partitionNumber;
        END

	--RLO 09/24/2020  If index was determined not to be fixed, the code was exectuting the previous t_SQL again
		set @sqlCommand = '';

    END

Enterprise Edition: Core-based Licensing

Hey, thanks for publishing and the great work.

I was testing abit around creating my own admin database and I'm missing the Enterprise Edition: Core-based Licensing for online rebuild
should be:
IF (SELECT ServerProperty('EditionID')) IN (1804890536, 1872460670, 610778273, -2117995310)

IF (SELECT ServerProperty('EditionID')) IN (1804890536, 610778273, -2117995310)

Error message "String or binary data would be truncated."

Hi,
I recently got the error "String or binary data would be truncated." while executing dba_indexDefrag_sp . This is because the log, status and exclusion tables (plus some variables) have the type NVARCHAR(128) for columns such as database name, index name etc. being the maximum size allowed for object names. However, if the object name is the maximum 128 characters long a failure will occur with an INSERT using QUOTENAME() because adding square brackets to the name takes the length to 130 characters.

I suggest that the DDL for the tables and variables that are set at NVARCHAR(128) are changed to NVARCHAR(130). Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.