Showing posts with label T-SQL. Show all posts
Showing posts with label T-SQL. Show all posts

May 04, 2016

SQL Tranlog shipping age check

I have a database setup with frequent tranlog shipping.  I then have a query running in some monitoring software (currently utilizing PRTG... it's cheap!).  There's probably a way to query the actual restore table, however we're more interested in the timestamp of the last meaningful transaction in the database so we're monitoring an internal audit table.  This is the basic query:
SELECT datediff(s, max([timestamp_column]), getdate()) /3600 from [audit_table];
Note: As you can see the query returns hours in decimal form.  Adjust as needed.

Anyway... sometimes the query tries to run when a restore is happening which causes errors.  A fix for this is to connect to master instead of directly to the database then run the query wrapped with an error and timer.  This query will attempt to run 3 times with a 10 second pause between.  The monitoring software is setup with a 120 timeout, so this query will error first.
DECLARE @Tries tinyint
SET @Tries = 1
WHILE @Tries <=3
BEGIN TRY
    SELECT datediff(s, max([timestamp_column]), getdate()) /3600 from [database].[dbo].[audit_table];
    BREAK
END TRY
BEGIN CATCH
    WAITFOR DELAY '00:00:10';
    SET @Tries = @Tries + 1
    CONTINUE
END CATCH

May 24, 2013

SQL Query in Powershell

How to connect to, query, and deal with the results of a SQL server.  Source: systemcentercentral.com

Declare Variables:

$SQLServer = [server\instance]
$SQLDB = [database]
$SQLQuery = "select [columns] from [table]"


Connect using integrated security and run query.  Results stored in $DataSet:

$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server = $SQLServer; Database = $SQLDB; Integrated Security = True"

$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $SqlQuery
$SqlCmd.Connection = $SqlConnection

$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd

$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)

$SqlConnection.Close()

Handle each row of results in $DataSet.  1st Field is [0], 2nd field is [1], etc.  Can specify .ToString(), .Trim(), .DateTime, calculations, etc.:

foreach ($row in $DataSet.Tables[0].Rows)
{
    $Field1 = $row[0].ToString()
    Write-Host $Field1
}

August 29, 2012

Display duplicate records

I don't know where I found this or if I made it up... I've used it for years.  I use this script to find out how many duplicate entries exist for specific columns.  It's especially handy when an application automatically assigns UID's:
 
SELECT  [COLUMN1]
      , [COLUMN2]
      , COUNT([COLUMN1]) AS [COLUMN1]_Count
      , COUNT([COLUMN2]) AS [COLUMN2]_Count
FROM    [TABLE]
GROUP BY [COLUMN1]
       , [COLUMN2]
HAVING  ( COUNT([COLUMN1]) > 1 ) AND
        ( COUNT([COLUMN2) > 1 )

Notify me when InventSumDate has Content

The InventSumDateTable and InventSumDateTrans tables are used for some reports in Dynamics AX (at least in 2009).  When the reports finish they delete the records stored in these tables, however if the report is terminated mid-process these records aren't cleaned out and this can cause substantial performance problems for these reports.

I wanted to setup some sort of notification to tell me when there is data in these tables when it's unlikely that someone would be running a report.  I decided I didn't want to automatically clean it out since it's possible they could actually be running a report and because I'd like to restart the AOS at the same time... don't know if it matters, but don't want anything cached.

Here is a the SQL job that I created which will email me when there are records in the table, but won't email me when there isn't.  I scheduled the job to run nightly after the backup completes.  The database name, database mail profile, and recipient email address need to be configured.


USE [AXDATABASE]
GO
 
SET ANSI_NULLS ON
GO
 
DECLARE @RECORD_CHECK INT
 
SELECT  COUNT(RECID) [Count]
INTO    #tmpCountInventSumDate
FROM    InventSumDateTable
 
INSERT  #tmpCountInventSumDate
        ( [Count]
        )
        SELECT  COUNT(RECID)
        FROM    InventSumDateTrans
 
SET @RECORD_CHECK = ( SELECT    SUM([Count])
                      FROM      #tmpCountInventSumDate
                    )
DROP TABLE #tmpCountInventSumDate
 
WHILE @RECORD_CHECK > 0
      BEGIN
            EXEC msdb.dbo.sp_send_dbmail
                @profile_name = '[Database Mail Profile]'
              , @recipients = '[recipient email address]'
              , @subject = 'InventSumDate Tables'
              , @body = 'InventSumDateTable and InventSumDateTrans temp tables are populated.'
              , @importance = 'high'
              , @query = 'SELECT  ''InventSumDateTable'' [Table]
                                      , COUNT(RECID) [Count]
                                INTO    #tmpCountInventSumDate
                                FROM    AXDATABASE.dbo.InventSumDateTable
                             
                                INSERT  #tmpCountInventSumDate
                                            ( [Table]
                                            , [Count]
                                            )
                                            SELECT  ''InventSumDateTrans''
                                                  , COUNT(RECID)
                                            FROM    AXDATABASE.dbo.InventSumDateTrans
                             
                                SELECT  *
                                FROM    #tmpCountInventSumDate
                             
                                DROP TABLE #tmpCountInventSumDate'
           
            SET @RECORD_CHECK = 0
      END

April 20, 2012

T-SQL divide by zero

I've spent so much time in SharePoint and Reporting Services lately that I had to remind myself the syntax for handling divide by 0 in T-SQL.

Belle's SQL Musings blog (nice title) does a good job explaining some simple options using the NULLIF function.

The tool-tip found in SQL 2008 Management Studio also does a good job of explaining that it "Returns a null value if the two specified expressions are equal."  Format: NULLIF(expression1, expression2).  So basically I did this:

my number / NULLIF(my crazy expression, 0)