Find out when/who dropped an object without auditing

If your environment doesn’t have any kind of auditing and you need to find since when an object was dropped.

If you have the default trace enabled (good practice) you can track when the object was dropped and determine if that was the root cause for some performance issue for example.

The point here is to find the root cause of an issue, not point the finger to who did it ūüėČ

First, let’s check what kind of events the default trace has

SELECT DISTINCT Trace.EventID
        , TraceEvents.NAME AS Event_Desc
 FROM ::fn_trace_geteventinfo(1) Trace
 JOIN sys.trace_events TraceEvents ON Trace.eventID = TraceEvents.trace_event_id 

You are going to see the events

The next step is get the default trace path

SELECT path
 FROM sys.traces
 WHERE is_default = 1;

Knowing the path you can get all the files name using xp_cmdshell for example

EXEC xp_cmdshell 'dir e:\"Program Files"\"Microsoft SQL Server"\"MSSQL10.MSSQLSERVER"\MSSQL\*.trc'

Grab the file name you want and change the script below

SELECT 
    CASE EventClass
        WHEN 46 THEN 'Object:Created'
        WHEN 47 THEN 'Object:Deleted'
        WHEN 164 THEN 'Object:Altered'
    END
    , DatabaseName
    , ObjectName
    , HostName
    , ApplicationName
    , LoginName
    , StartTime
 FROM ::fn_trace_gettable('C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\Log\your_file_name.trc', DEFAULT)
 WHERE 
    EventClass IN (46,47,164) 
    AND EventSubclass = 0 
 ORDER BY StartTime DESC

In my scenario what is showing is the creating object in the bottom with some index creation, drop index, object alter (it’s not telling what kind of change), create a new object and alter (the primary key creates the index and alter the table adding the constraint).

Plus you can see the login name and when the action was made. ūüėČ

How to add Active Directory powershell module

I’m going to show the steps how to add the AD module in your machine and in the server if you need to get information like run Get-ADPrincipalGroupMembership to know what groups a specific user belongs.

To add this module in your local machine is quite easy. Install the Remote Server Administration Tools for Windows 10 package

But, to install it in a Windows Server for example you need to add this feature following the steps .

  1. Open Server Manager Dashboard
  2. Click Manage -> Add Roles and Features Wizard
  3. Click next until to show the picture below in the item features

After install it (no restart needed) you can run import-module ActiveDirectory and run something like this:

Get-ADPrincipalGroupMembership -Identity 'user_name' | Select-Object name

$groups = Get-ADGroup -Filter {name -like 'user_group'} -Properties * | Select -property name

foreach($group in $groups) {
    if($group.name -ceq 'Group trying to find') {
        $group.name
        Get-ADGroupMember -Identity $group.name | Where-Object objectClass -Like 'group' | Select-Object name
    }
}

Common Git situations and how to solve it

Work with Git can be easy, but sometimes we need to know more than just pull, add, commit and push.

So, below you are going to find examples how to solve the most common scenarios you could face working with Git.

Combine with the previous commit

git commit --amend

Committed all those changes to the master branch by mistake

git branch New-branch
git reset HEAD~ --hard
git checkout New-branch

Made a spelling mistake in my branch name

git branch -m New-brunch New-branch

Clean up local commits before pushing

git rebase -i

Reverting pushed commits

git revert HEAD

Edit a commit message

git commit --amend -m ‚Äúnew message‚ÄĚ

Remove a file from git without removing it from your file system

git reset filename

Undo local commits

git reset HEAD

Discard local file modifications

git checkout -- something

Rollback to a specific point

git reflog 
git reset HEAD@{XX} 
-- git add or checkout

Checking the differences between remote and local repository

git diff origin/master master

Method to update LOB data with minimal log

Use the .WRITE (expression, @Offset,@Length) clause to perform a partial or full update of varchar(max), nvarchar(max), and varbinary(max) data types.

For example, a partial update of a varchar(max) column might delete or modify only the first 200 characters of the column, whereas a full update would delete or modify all the data in the column. .WRITE updates that insert or append new data are minimally logged if the database recovery model is set to bulk-logged or simple.

UPDATE <table_or_view_name>
SET column_name.WRITE (expression, @offset, @length)
FROM <table_source>
WHERE <search_condition>

expression is the value that is copied to column_name. expression must evaluate to or be able to be implicitly cast to the column_name type. If expression is set to NULL, @Length is ignored, and the value in column_nameis truncated at the specified @Offset.

@Offset is the starting point in the value of column_name at which expression is written. @Offset is a zero-based ordinal position, is bigint, and cannot be a negative number. If @Offset is NULL, the update operation appends expression at the end of the existing column_name value and @Length is ignored. If @Offset is greater than the length of the column_name value, the Database Engine returns an error. If @Offset plus @Length exceeds the end of the underlying value in the column, the deletion occurs up to the last character of the value. If @Offset plus LEN(expression) is greater than the underlying declared size, an error is raised.

@Length is the length of the section in the column, starting from @Offset, that is replaced by expression. @Length is bigint and cannot be a negative number. If @Length is NULL, the update operation removes all data from @Offset to the end of the column_name value.

The regular update statement results in overwriting the entire string using full logging and it’s very inefficient when dealing with large value updates.

Note: The update using WRITE method will fail if the value is null.

More information about performance in my tip on MSSQLTips

 

 

Execution runtime information for developers ;)

Developers should use this statistics to get more information about what they just did and pay attention to high physical or logical read values.

SQL Server provides commands that are used to return query statistics like SET STATISTICS IO, TIME.

The IO command return information about physical, logical for tables referenced in the query and also worktables, which means tables in tempdb for the duration of the query and are removed automatically when it has finished the operation.

Using statistics time will show the parse, compile time for the query and the actual execution time after the query results. It’s useful to measure the amount of time a query takes to execute from end to end.

How to install SQL Server SQLPS Powershell module

SQLPS module to Powershell helps to do so many things on SQL Server without SSMS and the main objective is to automate tasks for your environment.

This module isn’t installed by default, so there are a couple of steps before use it. First, install the module and the simple cmdlet install-module SQLPS won’t work.

To install the module you need install a couple of things (if you have SQL Server instance there is already installed).

The installation is quite simple and isn’t necessary to restart the system. There are 3 files necessary and need to install in the sequence below.

With all installed let’s try to import the module on powershell.

2018-08-01_20-36-01

Actually that didn’t work (yet). In the error message shows it’s not allowed to run scripts in my system.

Next step is to change the execution policy to run scripts in the system. Let’s try it using the cmdlets Get-ExecutionPolicy to know the actual value and Set-ExecutionPolicy to change it.  ( more information )

2018-08-01_20-45-23

Ok, second error and this time because I’m trying to change to RemoteSigned and only as administrator I can change it.

2018-08-01_20-54-28

Running as administrator the local machine execution policy has changed and the SQLPS module can be imported and use the cmdlets.

2018-08-01_21-00-16

Troubleshooting Transactional Replication – part 1

The common way to replicate data and objects from one server to another is using transactional replication. As you know, SQL Server processes all actions within the database using Transact-SQL statements. Each completed statement is called a transaction. In transactional replication, each committed transaction is replicated to the subscriber as it occurs.

trnsact
“Sometimes” can occur a problem and the process don’t work accordingly. The fist step I like to do is run sp_whoisactive in the servers (Publisher, Distributor and Subscriber), you can see if there are any process blocking the replication.

Next, is to see the publisher and subscriber agents, if there is any issue they will show, like for example login locked.

To have more information what’s happening I like to query the system view MSrepl_Transactions in the distribution database, this view contains one row for each replicated transaction and with that information run the procedure¬†sp_browsereplcmds specifying the seqno start @xact_seqno_start = N’0x0000014F000034B0001C’ for example.

The procedure sp_browserreplcmds returns a record set with the commands stored in the distribution database. It show like a table like below.

2018-07-29_20-31-59