Monday, July 7, 2014

T-SQL: MDF files in use

List the MDF file for every database in SQL Instance

declare @files table (
    db_name sysname,
    physical_name nvarchar(260)
)

insert into @files
    exec sp_MSforeachdb 'select "?", physical_name from ?.sys.database_files'

select db_name, physical_name 
    from @files

Wednesday, July 2, 2014

T-SQL: Get a list of dates

Returns a list of dates from first of year to end of year
DECLARE @startofyear DATETIME, @endofyear DATETIME
SET @startofyear =   DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)
SET @endofyear = DATEADD(yy, DATEDIFF(yy,0,getdate()) + 1, -1);

WITH sample AS (
  SELECT @startofyear  AS [Date]  
  UNION ALL
  SELECT DATEADD(dd, 1, [Date])
    FROM sample s
   WHERE DATEADD(dd, 1, [Date]) <=  @endofyear) 
SELECT * 
  FROM sample
  option (maxrecursion 370) –loop not more than 370, change to zero to infinite

Tuesday, June 24, 2014

T-SQL: Search text inside tables

Script to search inside tables
 
DECLARE @SearchStr nvarchar(100)
 
SET @SearchStr = 'STRING TO SEARCH'
 
CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))
 
SET NOCOUNT ON
 
DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110)
SET  @TableName = ''
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''')
 
WHILE @TableName IS NOT NULL
BEGIN
    SET @ColumnName = ''
    SET @TableName = 
    (
        SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
        FROM     INFORMATION_SCHEMA.TABLES
        WHERE         TABLE_TYPE = 'BASE TABLE'
            AND    QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
            AND    OBJECTPROPERTY(
                    OBJECT_ID(
                        QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
                         ), 'IsMSShipped'
                           ) = 0
    )
 
    WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)
    BEGIN
        SET @ColumnName =
        (
            SELECT MIN(QUOTENAME(COLUMN_NAME))
            FROM     INFORMATION_SCHEMA.COLUMNS
            WHERE         TABLE_SCHEMA    = PARSENAME(@TableName, 2)
                AND    TABLE_NAME    = PARSENAME(@TableName, 1)
                AND    DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar')
                AND    QUOTENAME(COLUMN_NAME) > @ColumnName
        )
 
        IF @ColumnName IS NOT NULL
        BEGIN
            INSERT INTO #Results
            EXEC
            (
                'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) 
                FROM ' + @TableName + ' (NOLOCK) ' +
                ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
            )
        END
    END    
END
 
SELECT ColumnName, ColumnValue FROM #Results

Link to source

Monday, May 5, 2014

T-SQL: Remove duplicate rows

The following example partitions the query by columns foo and bar and generates a number for each sequence containing the same 'foo' and 'bar'. Then using common table expressions 'WITH cte', which stores temporary the result set in a table named 'cte' (or whatever you choose) and then uses the script 'DELETE cte where [RN] > 1' to remove and duplicate entries having more than one result set with the same 'foo' and 'bar' combination.

Be extra careful before using DELETE ;) I usually do a select query instead of a delete to see what I am about to delete and when i'm certain that the query is correct, I change it to a delete.


WITH cte AS (
  SELECT[foo], [bar], 
     row_number() OVER(PARTITION BY foo, bar ORDER BY baz) AS [rn]
  FROM TABLE
)

DELETE cte WHERE [rn] > 1

Source
http://stackoverflow.com/questions/6025367/t-sql-deleting-all-duplicate-rows-but-keeping-one

Friday, January 10, 2014

T-SQL: Return nth delimited element from a string


CREATE FUNCTION [dbo].[fn_String_SplitByDelimiter]
(
   @List       VARCHAR(MAX),
   @Delimiter  VARCHAR(255),
   @ElementNumber int
)
RETURNS VARCHAR(4000)
AS
BEGIN

   DECLARE @result varchar(4000)    
   DECLARE @Items TABLE ( position int IDENTITY PRIMARY KEY,
                          Item VARCHAR(4000)
                         )  

   DECLARE @ll INT , @ld INT;  
   set @ll =  LEN(@List) + 1
   set @ld = LEN(@Delimiter);

   WITH a AS
   (
       SELECT
           [start] = 1,
           [end]   = COALESCE(NULLIF(CHARINDEX(@Delimiter, 
                       @List, @ld), 0), @ll),
           [value] = SUBSTRING(@List, 1, 
                     COALESCE(NULLIF(CHARINDEX(@Delimiter, 
                       @List, @ld), 0), @ll) - 1)
       UNION ALL
       SELECT
           [start] = CONVERT(INT, [end]) + @ld,
           [end]   = COALESCE(NULLIF(CHARINDEX(@Delimiter, 
                       @List, [end] + @ld), 0), @ll),
           [value] = SUBSTRING(@List, [end] + @ld, 
                     COALESCE(NULLIF(CHARINDEX(@Delimiter, 
                       @List, [end] + @ld), 0), @ll)-[end]-@ld)
       FROM a
       WHERE [end] < @ll
   )
   INSERT @Items SELECT [value]
   FROM a
   WHERE LEN([value]) > 0
   OPTION (MAXRECURSION 0);

   SELECT @result=Item
   FROM @Items
   WHERE position=@ElementNumber

   RETURN @result;
END

Example
SELECT [dbo].fn_String_SplitByDelimiter (
   '1ST\2ND\3RD\4TH'
  ,'\'
  ,3)

Will output
3RD

taken from the below url, just updated it to work on SQL2005
http://stackoverflow.com/questions/19449492/using-t-sql-return-nth-delimited-element-from-a-string

Monday, January 6, 2014

T-SQL: Which table taking most space

This query will list all tables of the selected database, sorted by the table which is taking up most data space in MB from the database.  I used it on a database which had a huge MDF file and found out that the Audit table had grown too much.

SELECT 
 t.NAME AS TableName,
 i.name AS indexName,
 SUM(p.rows) AS RowCounts,
 SUM(a.total_pages) AS TotalPages, 
 SUM(a.used_pages) AS UsedPages, 
 SUM(a.data_pages) AS DataPages,
 (SUM(a.total_pages) * 8) / 1024 AS TotalSpaceMB, 
 (SUM(a.used_pages) * 8) / 1024 AS UsedSpaceMB, 
 (SUM(a.data_pages) * 8) / 1024 AS DataSpaceMB
FROM 
 sys.tables t
INNER JOIN  
 sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN 
 sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN 
 sys.allocation_units a ON p.partition_id = a.container_id
WHERE 
 t.NAME NOT LIKE 'dt%' AND
 i.OBJECT_ID > 255 AND  
 i.index_id <= 1
GROUP BY 
 t.NAME, i.object_id, i.index_id, i.name 
ORDER BY 
TotalSpaceMB desc
 --OBJECT_NAME(i.object_id) 


Source: http://stackoverflow.com/questions/3927231/how-can-you-tell-what-tables-are-taking-up-the-most-space-in-a-sql-server-2005-d