Tag Archives: #SQLServer

All about Microsoft SQL Server

#0218 – SQL Server-Get Help for DBCC commands using DBCC HELP


Database Consistency Check, abbreviated as DBCC commands are perhaps the best friends of any DBA. Following are some of the most common DBCC commands that can be found in almost all the script banks:



  1. CHECKDB
  2. CHECKIDENT
  3. CHECKALLOC
  4. CHECKTABLE
  5. TRACEON
  6. TRACEOFF
  7. SHOWCONTIG

I am poor at remembering the syntax of these commands and therefore take occasional help of the SQL Server Books On Line (BOL) to get a hint on the parameters that a particular DBCC command uses. However, there are cases when one is working directly off the development or quality assurance servers, which generally do not have BOL installed. In such cases, the easiest way to obtain help for the DBCC commands is to use another, obvious DBCC command – DBCC HELP!


Here’s a quick example:

DBCC HELP (‘CHECKIDENT’)
GO

Running the above returns the following text, which is essentially the syntax help for DBCC CHECKIDENT:


dbcc CHECKIDENT
(
    ‘table_name’
    [ , { NORESEED
        | { RESEED [ , new_reseed_value ] }
    } ]
)
    [ WITH NO_INFOMSGS ]


DBCC execution completed. If DBCC printed error messages, contact your system administrator.


So the next time you are stuck with the syntax for a DBCC command, ask DBCC for HELP before reaching out for the BOL.


(The catch: To the best of my knowledge DBCC HELP only works for the documented DBCC commands, similar to the BOL.)


Until we meet next time,


Be courteous. Drive responsibly.

#0217-SQL Server-Script-Identify SQL Server Agent jobs no longer targeted to a database


Today’s post is a short one – a quick tip/script that would come to use in most development/quality assurance environments.

Most non-production environments see a constant change to the number and nature of the databases that are deployed on a given SQL Server instance. There would be a copy of the database for maintenance teams, another one for the team working on newer enhancements to a product and a few other copies for special purposes, targeted to study and resolve a specific issue or deployment. Once the particular task is completed, these databases are dropped. What is left behind are the components of that deployment that are not directly “contained” (for lack of a better word) by SQL Server.

One of many such “non-contained” components are the SQL Server Agent jobs. When a database is dropped, the jobs remain active in the SQL Server Agent and if a schedule is associated to the job, failures would be reported whenever the jobs are automatically executed. As part of the standard process that I follow whenever I drop a database, I run the following script to identify SQL Server Agent jobs which are no longer targeted to any database:

USE msdb;
GO
--Query to identify orphaned jobs!
SELECT sj.database_name AS OriginalTargetDBName,
       sj.job_id AS JobId,
       sj.step_id AS JobStepId,
       sj.step_name AS StepName,
       sj.subsystem AS SubSystem,
       sj.command AS JobStepCommand,
       sj.last_run_date AS LastExecutionDate
FROM msdb.dbo.sysjobsteps AS sj
WHERE DB_ID(sj.database_name) IS NULL AND   --If the database no longer exists,
                                            --DB_ID() would return NULL
      sj.database_name IS NOT NULL
GO

I trust that you have found (or will find) the above query useful. If you use any other query/mechanism or have faced similar issues with cleanup of other objects related to the SQL Server Agent, I would like to know. Do share your experiences in the comments below.

Until we meet next time,

Be courteous. Drive responsibly.

#0216 – SQL Server – Use APP_NAME() to change application behavior based on connection properties


Recently, I wrote a couple of posts around some of the best practices that should be followed when working with Connection Strings. In case you missed them earlier, they are linked below for your kind reference:



In these posts, I mentioned that the application name parameter (and connection strings in general) can be used to alter the behavior of an application. One of the follow-up questions I received was around this topic, and today, I would briefly demonstrate a practical use of this functionality.



How can you modify the application behavior by using the application name parameter of a connection string?


A common requirement that I have encountered in many home-grown enterprise systems which share the same database is to exhibit different auditing behavior based on which application or interface is inserting/updating a piece of data. Most legacy applications implement auditing via database triggers, and checking for the application name in these triggers is the solution to realizing this requirement. Today, I will explore with you how the APP_NAME() function can be used to alter the behavior of an application based on the application name set by the connection string.


Using APP_NAME()


Consider the following trigger that is executed whenever an Employee record is updated. The only purpose of this is to audit the changes made to the Employee record by applications other than the “MyEnterpriseProduct”. These updates could be through interfaces or through any other applications that the organization may be using.


This demo will walk you through using the APP_NAME() function, which returns the application name for the current session if set by the application, within a DDL trigger.


The following code creates an auditing table followed by an update trigger on the Employee table.

USE AdventureWorks2008R2
GO

–Step 01: Prepare the environment
— : Create the auditing table
— : Create the update trigger
IF OBJECT_ID(‘HumanResources.uEmployee’,’TR’) IS NOT NULL
BEGIN
DROP TRIGGER [HumanResources].[uEmployee];
END
GO

IF OBJECT_ID(‘HumanResources.Audit’) IS NOT NULL
BEGIN
DROP TABLE [HumanResources].[Audit];
END
GO

CREATE TABLE [HumanResources].[Audit] (AuditDate DATETIME,
BeforeJobTitleValue VARCHAR(100),
AfterJobTitleValue VARCHAR(100),
ApplicationName VARCHAR(100)
);
GO

CREATE TRIGGER [HumanResources].[uEmployee]
ON [HumanResources].[Employee]
FOR UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @appName VARCHAR(100);
SET @appName = APP_NAME();

IF (@appName != ‘MyEnterpriseProduct’)
BEGIN
INSERT INTO [HumanResources].[Audit]
(AuditDate, BeforeJobTitleValue, AfterJobTitleValue, ApplicationName)
SELECT GETUTCDATE() AS AuditDate,
deleted.JobTitle AS BeforeJobTitleValue,
inserted.JobTitle AS AfterJobTitleValue,
@appName AS ApplicationName
FROM [HumanResources].[Employee] AS Employee
INNER JOIN deleted ON deleted.BusinessEntityID = Employee.BusinessEntityID
INNER JOIN inserted ON deleted.BusinessEntityID = inserted.BusinessEntityID
WHERE Employee.BusinessEntityID = inserted.BusinessEntityID;
END
END
GO


Now, using the methods described in the post “How to test your Connection String using SSMS?”, establish two connections from the SSMS to the test AdventureWorks database – one using the Application Name – “MyEnterpriseProduct” and other using “OtherApplication”. Execute the queries shown below using the respective connections:

–Step 02: Using a connection with Application Name = “MyEnterpriseProduct”,
— update the Employee record
— Confirm that no auditing has been performed
USE AdventureWorks2008R2
GO
–Chief Executive Officer
UPDATE HumanResources.Employee SET JobTitle = ‘CEO’ WHERE BusinessEntityID = 1;
GO

SELECT NULL AS AuditDate,
NULL AS BeforeJobTitleValue,
NULL AS AfterJobTitleValue,
APP_NAME() AS ApplicationName
UNION
SELECT AuditDate,
BeforeJobTitleValue,
AfterJobTitleValue,
ApplicationName
FROM [HumanResources].[Audit];
GO

–Step 03: Using a connection with Application Name = “OtherApplication”,
— update the Employee record
— Confirm that auditing has been performed
USE AdventureWorks2008R2
GO
–Chief Executive Officer
UPDATE HumanResources.Employee SET JobTitle = ‘Chief Executive Officer’ WHERE BusinessEntityID = 1;
GO

SELECT NULL AS AuditDate,
NULL AS BeforeJobTitleValue,
NULL AS AfterJobTitleValue,
APP_NAME() AS ApplicationName
UNION
SELECT AuditDate,
BeforeJobTitleValue,
AfterJobTitleValue,
ApplicationName
FROM [HumanResources].[Audit];
GO


Here’s what one would see in the two different connections:



























Query Window Audit Date BeforeJobTitleValue AfterJobTitleValue Application Name
1 NULL NULL NULL MyEnterpriseProduct
2 NULL NULL NULL OtherApplication
2 11/16/2012 CEO Chief Executive Officer OtherApplication

0216


Notice that in the second result set (in the connection with Application Name set to “OtherApplication”, the BeforeJobValue is set to “CEO”, indicating that the first query did actually update the data, but the activity was not logged.


Finally, it’s cleanup time!

–Step 04: Cleanup!
USE AdventureWorks2008R2
GO
IF OBJECT_ID(‘HumanResources.uEmployee’,’TR’) IS NOT NULL
BEGIN
DROP TRIGGER [HumanResources].[uEmployee];
END
GO

IF OBJECT_ID(‘HumanResources.Audit’) IS NOT NULL
BEGIN
DROP TABLE [HumanResources].[Audit];
END
GO


Conclusion


As can be seen in the demonstration above, we were able to change the behavior of the auditing mechanism built into the application based on the parameter (Application Name) supplied within the connection string. Connection strings are therefore very powerful, and I urge all readers to go back, explore and share the results of your experiments through your comments on this post.


Disclaimer: The above example is only intended to demonstrate the use of the system function APP_NAME() and should not be used as a guidance for designing an auditing solution. An auditing solution requires capturing many more parameters and is outside the scope of this discussion.


Until we meet next time,


Be courteous. Drive responsibly.

#0215-SQL Server-Testing your connection strings using SSMS


Earlier, I wrote a post about how adding the Application Name and the Workstation ID in a connection string are recommended best practices because these would help system administrators troubleshoot problems faster by being able to identify which application and which workstation actually initiated a SQL Server connection. In most teams, the connection string is constructed and provided to the development team by the administrators/DBAs and therefore, as soon as the post was up, I received a couple of questions from these DBAs, one of which included:



Is there a way to test connection strings before an application is built to consume the connection string?


This is a very interesting question. A connection string has many different parameters which can influence the overall behaviour of the application and therefore, testing the connection strings before actually using them makes complete sense. In today’s post, I explore the answer to this question.


Using the “Connect To…” window of SSMS to test connection strings


If you work frequently with the SQL Server Management Studio (Tutorial on “Getting Started with SSMS”), you would notice that one of the first windows that the user encounters is the “Connect To” window. By default, the window looks similar to the screenshot shown below and allows the user to choose the SQL Server instance to connect to, the mode of the connection (windows authentication/SQL Server authentication) and the user credentials.


image


This window collects what is the “bare-minimum” information to establish a connection. Clicking on the “Options” button exposes a window that enables the user to tweak the connection parameters in greater detail. As you can see, the window consists of three tabs:



  • Login
  • Connection Properties
  • Additional Connection Parameters














Login Tab:
This is essentially the same as the compact version of the window.
image

Connection Properties Tab:
Allows a user to:



  • Define an initial catalog/database
  • Modify the network protocol to be used and choose the network packet size
  • Modify the timeout parameters
image
Additional Connection Parameters:
This allows a user to free-form type connection string options that are not available on the UI (for example, the Application Name and the Workstation Id)
NOTE: Please note that any information entered here would override the information specified in the UI on the other tabs of the “Connect To…” window.
image

When preparing the demonstrations shown in my earlier post on connection strings, I used these options to test out the changes and tweaks to the connection strings. In a similar way, administrators/DBAs can now use the SSMS to test out their connection strings before they hand them over to the application development teams.


I trust you found this feature of the SSMS useful – I use it on a regular basis, and would like to know if you have ever used it. Do drop in a line as you go.


Until we meet next time,


Be courteous. Drive responsibly.

#0214-SQL Server-Connection Strings-Profiling Best Practice-Application Name, Workstation ID


The glue that holds the connection between an application and a SQL Server instance is just a simple string, called the “connection string”. The connection string serves a purpose much greater than simply connecting the two together. Connecting Strings have the power to influence:



  • Application Security
  • Application behaviour
  • Help in auditing and troubleshooting

To most developers, a simple ADO connecting string would be something like:



Provider=SQLNCLI10;Data Source=WINDOWS8RPSQL2K12;Initial Catalog=AdventureWorks2012;User ID=someuser;Password=userpassword


If we try to highlight the different parts of the connection string, we see that we know the following:



  • the library to use for the connection
  • the data source (i.e. the instance name) to connect to
  • the database to use by default once the connection has been established and,
  • the credentials for a successful SQL authentication

All of the above constitute required information, and includes all the essential information about the SQL Server instance. What it does not have is the information about the calling application. To the SQL Server, the originator of the request is essentially unknown. The request could have come from almost anywhere and it would have honoured the request provided the details were correct.


Not only is this bad from a security standpoint, it is also not recommended from an auditing and troubleshooting perspective also. Let’s just see an example of this situation.


A small demo


For this demo, I launched multiple query editors within the SQL Server Management Studio, connected to the same instance of SQL Server. I then executed the same T-SQL query from these query editor windows, and attempt to identify each connection using the SQL Server Profiler (Refer tutorial here).


You can also develop a test application and run multiple instances of the application to observe a similar behaviour.


image


Now, we know that each query editor will open it’s own connection to the SQL Server. Therefore if the associated SPID is known, auditing is not a difficult task. In production systems, this is not the case and therefore, an alternate approach becomes necessary.


The solution – Modify your connection string!


From an auditing and troubleshooting standpoint, it is therefore, always a good practice to include the application name of the calling application and the workstation Id of the workstation. For the ADO connection string shown above, a simple modification like the following would work wonders:



Provider=SQLNCLI10;Data Source=WINDOWS8RPSQL2K12;Initial Catalog=AdventureWorks2012;User ID=someuser;Password=userpassword;Application Name=”MyTestApp”;Workstation Id=”SSMS01”


image


Running the same test again shows us that the Profiler can now distinguish between the calls coming in via “MyTestApp” through it’s the various sessions (represented as the HostName) v/s the calls coming in from the SQL Server Management Studio itself.


Now, the SQL Server can be programmed to only log connections not originating from certain applications, or can be programmed to respond differently when the same database/stored procedure is being executed over different connections – the possibilities are endless!


It is therefore a best practice to also set the Application Name and Workstation Id as part of the connection string of your application.


To know more about connection strings and their anatomy


A couple of years ago, I wrote a piece on SQLServerCentral.com (Connection Strings 101). That article address, at length the various components of a connection string and the areas they influence. I also provide a consolidated list of connection string components for ADO, ODBC and OLE DB libraries to download!


May the power of the connection string be with you!


Until we meet next time,


Be courteous. Drive responsibly.