Wednesday, June 18, 2014

List SQL table hierarchically based on Foreign Key and Primary Key Relationship

WITH Fkeys AS (
    SELECT DISTINCT
         OnTable       = OnTable.name
        ,AgainstTable  = AgainstTable.name 
    FROM 
        SYSFOREIGNKEYS fk
        INNER JOIN SYSOBJECTS onTable 
            ON fk.fkeyid = onTable.id
        INNER JOIN SYSOBJECTS againstTable  
            ON fk.rkeyid = againstTable.id
    WHERE 1=1
        AND AgainstTable.TYPE = 'U'
        AND OnTable.TYPE = 'U'
        -- ignore self joins; they cause an infinite recursion
        AND OnTable.Name <> AgainstTable.Name
    )
,MyData AS (
    SELECT 
         OnTable = o.name
        ,AgainstTable = FKeys.againstTable
    FROM 
        SYS.OBJECTS O
        LEFT JOIN FKeys
            ON  o.name = FKeys.onTable
    WHERE 1=1
        AND o.type = 'U'
        AND o.name NOT LIKE 'sys%'
    )
,MyRecursion AS (
    -- base case
    SELECT 
         TableName    = OnTable
        ,Lvl    = 1
    FROM
        MyData
    WHERE 1=1
        AND AgainstTable IS NULL
    -- recursive case
    UNION ALL SELECT
         TableName    = OnTable
        ,Lvl          = r.Lvl + 1
    FROM 
        MyData d
        INNER JOIN MyRecursion r
            ON d.AgainstTable = r.TableName
)
SELECT 
     ROW_NUMBER() OVER (ORDER BY MAX(lvl) ASC) AS SNO
     ,Lvl = MAX(Lvl)
    ,TableName
 FROM 
    MyRecursion
GROUP BY
    TableName
ORDER BY 
     1 DESC
    ,2 DESC

T-SQL Query to get the SQL Agent job exectuted date time and duration

Select job_name, run_datetime, run_duration
From
(
    select job_name, run_datetime,
        SUBSTRING(run_duration, 1, 2) + ':' + SUBSTRING(run_duration, 3, 2) + ':' +
        SUBSTRING(run_duration, 5, 2) AS run_duration
    from
    (
        select DISTINCT
            j.name as job_name, 
            run_datetime = CONVERT(DATETIME, RTRIM(run_date)) +  
                (run_time * 9 + run_time % 10000 * 6 + run_time % 100 * 10) / 216e4,
            run_duration = RIGHT('000000' + CONVERT(varchar(6), run_duration), 6)
        from msdb..sysjobhistory h
        inner join msdb..sysjobs j
        on h.job_id = j.job_id
    ) t
) t
order by job_name, run_datetime

To drop all tables

SQL server is providing a nice option to drop all the tables at a stretch. Below is the query to achieve the same
EXEC sp_MSforeachtable @command1 = "DROP TABLE ?"

To drop single table:
EXEC sp_MSforeachtable @command1 = "DROP TABLE <TableName>"

To find the log size of all database

DBCC SQLPERF ( LOGSPACE )