Copyright (c)  2007  Mike Chirico (mchirico@gmail.com)

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2 or
any later version published by the Free Software Foundation.

Last Updated: Fri Dec 21 12:37:14 EST 2007


TIP 1:

 Need to know how much fragmentation?

      DBCC SHOWCONTIG (tbl_transaction)

 There is also a more advanced option

      DBCC SHOWCONTIG (tbl_transaction) WITH TABLERESULTS, ALL_LEVELS

 There is also a defrag command

      DBCC INDEXDEFRAG(Northwind,Customers,1)



TIP 2:


 This is a cool feature:

     IF object_id('OutputTest') IS NOT NULL
     BEGIN
        drop table OutputTest
     END
     
     
     CREATE TABLE OutputTest
         (
             ID int NOT NULL,
             Description varchar(max) NOT NULL,
         )
     
         INSERT INTO OutputTest (ID, Description) VALUES (1, 'row 1')
         INSERT INTO OutputTest (ID, Description) VALUES (2, 'row 2')
         INSERT INTO OutputTest (ID, Description) VALUES (3, 'row 3')
     
     DECLARE @DeleteLog AS TABLE (LogID INT, LogEntry VARCHAR(MAX))
     
         DELETE OutputTest
         OUTPUT DELETED.ID, DELETED.Description INTO @DeleteLog
         WHERE ID = 1
     
         SELECT *into DeleteLog FROM @DeleteLog
     
     
     select * from DeleteLog



TIP 3:

     Standard table create statement, with getdate() for automatically
     recording the time when a record was added.

       CREATE TABLE [junk23](
        [JunkID] [smallint] IDENTITY(1,1) NOT NULL,
        [Name] varchar(20) NOT NULL,
        [ModifiedDate] [datetime] NOT NULL   DEFAULT (getdate()))

     
     
TIP 4:

     create PROCEDURE Insert_Top as
     
     /*
     
     CREATE TABLE [dbo].[top](
        [SPID] [float] NULL,
        [Status] [nvarchar](255) NULL,
        [Login] [nvarchar](255) NULL,
        [HostName] [nvarchar](255) NULL,
        [BlkBy] [nvarchar](255) NULL,
        [DBName] [nvarchar](255) NULL,
        [Command] [nvarchar](255) NULL,
        [CPUTime] [float] NULL,
        [DiskIO] [float] NULL,
        [LastBatch] [nvarchar](255) NULL,
        [ProgramName] [nvarchar](255) NULL,
        [SPID1] [float] NULL,
        [REQUESTID] [float] NULL,
        [ModifiedDate] [datetime] NULL CONSTRAINT [DF_top_ModifiedDate]  DEFAULT (getdate())
     ) ON [PRIMARY]
     
     */
     
     
     INSERT INTO [DPart_P008_Dev].[dbo].[top]
               (
        [SPID],
        [Status],
        [Login],
        [HostName],
        [BlkBy],
        [DBName],
        [Command],
        [CPUTime],
        [DiskIO],
        [LastBatch],
        [ProgramName],
        [SPID1],
        [REQUESTID])
      EXEC sp_who2

  Now, create the loop procedure:

      create PROCEDURE Loop_Insert_Top as
      WHILE (1=1) BEGIN
          EXEC insert_top
          WAITFOR DELAY '00:01:00';
      END

  To view the records:

     select * from [top]




TIP 5:

   sp_help
   sp_helptext Insert_Page7_into_Combined_sproc


   "All that really happens when you create a procedure is that its
    syntax is checked and its source code is inserted into the
    syscomments system table"




TIP 6:

    Getting a directory listing of the c:\ drive.


        -- To allow advanced options to be changed.
        EXEC sp_configure 'show advanced options', 1
        GO
        -- To update the currently configured value for advanced options.
        RECONFIGURE
        GO
        -- To enable the feature.
        EXEC sp_configure 'xp_cmdshell', 1
        GO
        -- To update the currently configured value for this feature.
        RECONFIGURE
        GO

        EXEC master..xp_cmdshell "dir c:\*"



TIP  7:

        select  
            'Name'          = o.name,  
            'Owner'         = user_name(ObjectProperty( object_id, 'ownerid')),  
            'Object_type'   = substring(v.name,5,31) 

        --into t_sp_help
        from sys.all_objects o, master.dbo.spt_values v  
        where o.type = substring(v.name,1,2) collate database_default and v.type = 'O9T'  
        and substring(v.name,5,31) ='stored procedure'
        and user_name(ObjectProperty( object_id, 'ownerid'))='dbo'
        order by [Owner] asc, Object_type desc, Name asc  



TIP 8:

   You may need indexes. Try running the following query to see if the
   value is above 5000.


        SELECT *
        FROM
        (SELECT user_seeks * avg_total_user_cost * (avg_user_impact * 0.01) AS index_advantage,
        migs.* FROM sys.dm_db_missing_index_group_stats migs) AS migs_adv
          INNER JOIN sys.dm_db_missing_index_groups AS mig ON migs_adv.group_handle =
           mig.index_group_handle
          INNER JOIN sys.dm_db_missing_index_details AS mid ON mig.index_handle = mid.index_handle
        ORDER BY migs_adv.index_advantage




TIP 9:

    Need to see what users are doing?

         select * from sys.dm_exec_sessions




TIP 10:

    Need the last day of the month?


         Select 
             dateadd(mm,1,convert(datetime,convert(char(10),getdate(),110)) - 
                day(getdate())+1)-1




TIP 11:

    Put last day of month into a user defined function.


        create FUNCTION dbo.GetLastDayOfMonth()
        RETURNS datetime
        AS
        BEGIN
          DECLARE  @OutDate datetime
            set @OutDate = (Select dateadd(mm,1,convert(datetime,convert(char(10),getdate(),110)) 
               - day(getdate())+1)-1)
        RETURN(@OutDate)
        END

    Now call it:

        select dbo.GetLastDayOfMonth()




TIP 12:

    Need a function that gets the date a year ago at the beginning of
    the month?


        create FUNCTION dbo.Get1YearAgo()
        RETURNS datetime
        AS
        BEGIN
          DECLARE  @OutDate datetime
          set @OutDate = (Select dateadd(mm,-12,convert(datetime,convert(char(10),
                     getdate(),110)) - day(getdate())+1)
        )
          RETURN(@OutDate)
        END

        select dbo.Get1YearAgo()




TIP 13:

    Need to get a list of all stored procedures?

        SELECT name
        FROM dbo.sysobjects
        WHERE type = 'P' AND category = 0




TIP 14:

     Need to get the median?  Also see TIP 15 below and TIP 19.

        
         SELECT Median=AVG(c1) FROM (
           SELECT MIN(c1) AS c1 FROM (
           SELECT TOP 50 PERCENT col AS c1 FROM table
          ORDER BY c1 DESC) t
            UNION ALL
          SELECT MAX(c1) FROM (
          SELECT TOP 50 PERCENT col AS c1 FROM table
          ORDER BY c1) t
          ) M


    (Also reference: http://www.sqlmag.com/Article/ArticleID/49827/49827.html)
     But note, you can probably use the sp_executesql statement as well.


     Here's a way to get the 75%.



        WITH T AS
        (
          SELECT [Sls Rep],[Prod No],[UOM],[Unit Sales $],
              ROW_NUMBER() OVER(PARTITION BY [Sls Rep],[Prod No],[UOM] 
                 ORDER BY [Unit Sales $]) AS RowNum,
                  COUNT(*) OVER(PARTITION BY [Sls Rep],[Prod No],[UOM]) AS Cnt
                    FROM Pg7_all_trans
                    )
                    SELECT [Sls Rep],[Prod No],[UOM],Avg([Unit Sales $]) [Median Unit Sales $], 
                    Max(RowNum) [RowNum], Max(Cnt) [Cnt] into Pg7_75
                    FROM T
                    WHERE RowNum >= 0.75*(Cnt+1) and RowNum <= 0.75*(Cnt+2) 
                    GROUP BY [Sls Rep],[Prod No],[UOM]



TIP 15:

    sp_executesql -- Executing the contents of a string as a SQL statement.

         Declare @S nvarchar(500);
         set @S = 'select * from' + ' junk'
         execute sp_executesql @S

    But wait! You can do this in a sproc:

        
         create proc select_table(@a as nvarchar(50))
         as
         Declare @t as nvarchar(500);
         set @t = 'select * from ' + @a;
         execute sp_executesql @t

    Now just run this as follows:

         select_table 'junk';


    Here's another example with parameters:

        EXECUTE sp_executesql 
          N'SELECT * FROM AdventureWorks.HumanResources.Employee 
          WHERE ManagerID = @level',
          N'@level tinyint',
          @level = 109;

    Here's an example with quotes:

        Declare @S nvarchar(max);
        set @S = '
        IF object_id(''junk'') IS NOT NULL
        BEGIN
           DROP TABLE junk
        END
        
        create table
        junk (a int,
        b varchar(20));
        insert into junk (a,b) values (1,''one'');
        insert into junk (a,b) values (2,''two'');
        select * from junk;
        '
        -- print @S
        execute sp_executesql @S


     (Also reference: http://msdn2.microsoft.com/en-us/library/ms188001.aspx)



TIP 16:

    More sp_executesql -- 
     
        DECLARE @sql AS NVARCHAR(MAX), @i AS INT;
        SET @sql = N'';
        SET @i = 1;
        WHILE @i <= 100
        BEGIN
          SET @sql = @sql + N'PRINT ' + CAST(@i AS NVARCHAR(10))
           + NCHAR(13) + NCHAR(10);
          SET @i = @i + 1;
        END
        EXEC sp_executesql @sql;



TIP 17:

    Simple example of a union statement:

        select  *  into t1_t2_combined from 
        (select * from t1
             union
          select * from t2) as a



TIP 18:

    Need to find SQL version?

        SELECT @@VERSION

    or

        
        SELECT  SERVERPROPERTY('productversion'), SERVERPROPERTY ('productlevel'), 
              SERVERPROPERTY ('edition')
    

    Reference: 
         http://support.microsoft.com/kb/321185



TIP 19:

    Example calculating Median on the table Median_table

                
                GO
                SET ANSI_NULLS ON
                GO
                SET QUOTED_IDENTIFIER ON
                GO
                
                alter FUNCTION [dbo].[calc_median_product_uom] (@product as nvarchar(30),
                @uom as nvarchar(4)
                )
                -- Created:  Mike Chirico <mchirico@gmail.com>
                -- Updated: Thu Sep 27 16:30:20 EDT 2007
                --
                -- Example Usage:
                --
                -- select product,uom,DPart_P008.dbo.calc_median_product_uom(product,uom) Median from Median_table
                -- 
                -- 
                
                
                RETURNS money
                AS
                BEGIN
                
                DECLARE  @Median as money
                
                SELECT @Median=AVG(c1) FROM (
                  SELECT MIN(c1) AS c1 
                   FROM (SELECT TOP 50 PERCENT AvqPrice AS c1 FROM Median_table 
                     where product=@product and uom=@uom ORDER BY c1 DESC
                ) as t
                UNION ALL
                select max(c1) as c1 from (
                  SELECT TOP 50 PERCENT AvqPrice AS c1 FROM 
                    Median_table where product=@product and uom=@uom ORDER BY c1
                ) as t
                ) M
                
                
                  RETURN(@Median)
                END




TIP 20:

    Example listing all the indexes on table mytable.

           select a.name table_name,
                  b.name index_name,
                  d.name column_name,
                  c.index_column_id
             from sys.tables a,
                  sys.indexes b,
                  sys.index_columns c,
                  sys.columns d
           where a.object_id = b.object_id
            and b.object_id = c.object_id
            and b.index_id  = c.index_id
            and c.object_id = d.object_id
            and c.column_id = d.column_id
            and a.name      = 'mytable'



TIP 21:

    Need a comparison between Oracle 10g and SQL 2005? Take a look at
    the following:

        http://www.wisdomforce.com/dweb/resources/docs/MSSQL2005_ORACLE10g_compare.pdf



TIP 22:

    Need to free up space?  The following query shows how much space
    can be freed.


           SELECT name ,size/128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS int)/128.0 AS AvailableSpaceInMB
           FROM sys.database_files;

    To free up space from the database 'mydatabase' use the following
    command:

           DBCC SHRINKDATABASE('mydatabase',0);

    To free up sapce from the logfile 'mylogfile' use the following command:

           DBCC SHRINKFILE('mylogfile',0);


  
TIP 23:

    Getting the Sum, Max across rows in a table.

       Assume a simple table defined as follows:

       create table junk
       (a int,
        b int,
        c int);

       insert into junk (a,b,c) values (1,4,3);
       insert into junk (a,b,c) values (2,5,9);
       insert into junk (a,b,c) values (3,8,2);


        select *, (select sum(my_columns)
        from (select a as my_columns
           union all
              select b 
           union all
             select c) as t) as sum_column
       from junk



Tip 24:

    Delete all tables with the name delete in them.    

        SET ANSI_NULLS ON
        GO
        SET QUOTED_IDENTIFIER ON
        GO
        -- =============================================
        -- Author:              <Mike Chirico mchirico@gmail.com>
        -- Create date: <Thu Nov  1 08:34:41 EDT 2007>
        -- Description: <This proc will go through and delete
        --              all tables with the name delete in them.>
        -- =============================================
        alter PROCEDURE free_space 

        AS
        BEGIN
                -- SET NOCOUNT ON added to prevent extra result sets from
                -- interfering with SELECT statements.
                SET NOCOUNT ON;

                DECLARE cursor_value CURSOR
                FOR 
                                select name from sys.tables where name like '%delete%'
                FOR READ ONLY

                DECLARE @cursor_row_value varchar(120)
                DECLARE @S nvarchar(500);
                OPEN cursor_value
                FETCH cursor_value INTO @cursor_row_value
                WHILE (@@FETCH_STATUS=0) BEGIN
                           set @S = 'drop table ['+@cursor_row_value+']'
                           execute sp_executesql @S
                           FETCH cursor_value INTO @cursor_row_value
                END
                CLOSE cursor_value
                DEALLOCATE cursor_value

       END
       GO




TIP 25:

    What is the difference between UNION and UNION ALL?  UNION only returns the distinct
    number of rows and is slower than UNION ALL.




TIP 26:

    What is the difference between NVARCHAR, VARCHAR and CHAR?
    NVARCHAR takes two bytes, VARCHAR takes 1 byte, and CHAR is fixed
    length.


TIP 27:

    Order can make a difference when doing updates

       
       IF object_id('tempdb..#t1') IS NOT NULL
       BEGIN
          DROP TABLE #t1
       END
       IF object_id('tempdb..#t2') IS NOT NULL
       BEGIN
          DROP TABLE #t2
       END
       IF object_id('tempdb..#t3') IS NOT NULL
       BEGIN
          DROP TABLE #t3
       END
       
       
       
       create table #t1 (a int, b int);
       insert into #t1 (a,b) values (1,2);
       insert into #t1 (a,b) values (1,5);
       
       create table #t2 (a int ,b int, c int, d int, [order] int);
       insert into #t2 (a,b,c,d,[order]) values (1,2,10,10,0);
       insert into #t2 (a,b,c,d,[order]) values (1,2,50,60,1);

       -- Change order here:
       --select * into #t3 from #t2 order by [order] desc
       select * into #t3 from #t2 order by [order] asc
       
       update #t1 
       set #t1.a=#t3.c, #t1.b=#t3.d
       from #t1 ,#t3
       where #t1.a=#t3.a and #t1.b=#t3.b 
       
       
       select * from #t1
       
       

TIP 28:

    Need a listing of all stored procedures on the system that you
    created?


       SELECT * -- Stored Procs
       FROM sys.objects
       WHERE objectproperty( object_id, N'IsMSShipped' ) = 0
       AND objectproperty( object_id, N'IsProcedure' ) = 1

    Below are some other common methods. But take a look at the
    following below and note the condition where N'IsMSShipped' is
    false, or equal to zero.

       SELECT * -- Functions
       FROM sys.objects
       WHERE objectproperty( object_id, N'IsMSShipped' ) = 0
       AND ( objectproperty( object_id, N'IsTableFunction' ) = 1
       OR objectproperty( object_id, N'IsScalarFunction' ) = 1 )

       SELECT * -- User tables
       FROM sys.objects
       WHERE objectproperty( object_id, N'IsMSShipped' ) = 0
       AND objectproperty( object_id, N'IsTable' ) = 1

       SELECT * -- Views
       FROM sys.objects
       WHERE objectproperty( object_id, N'IsMSShipped' ) = 0
       AND objectproperty( object_id, N'IsView' ) = 1


     Reference:
         http://msdn2.microsoft.com/en-us/library/ms176105.aspx
         http://sqlblogcasts.com/blogs/tonyrogerson/archive/2006/06/29/850.aspx



TIP 29:

    Combining two tables into 1 pivot table

       
       create table p1 (a int, b int)
       create table p2 (a int, b int)
       
       
       delete from p1;
       delete from p2;
       insert into p1 (a,b) values (1,34);
       insert into p1 (a,b) values (2,12);
       insert into p1 (a,b) values (3,22);
       
       insert into p2 (a,b) values (1,500);
       insert into p2 (a,b) values (2,512);
       insert into p2 (a,b) values (4,600);
       
       
       
       select g.a,g.b,g.c 
       from
       (
       	select p1.a, p1.b,p2.b as c from p1, p2
       	where p1.a=p2.a
       union all
             select p1.a,p1.b,null as c from p1 left outer join
              p2 on p1.a=p2.a
              where p2.a is null
       union all
             select p2.a,null as b,p2.b as c from p2 left outer join 
              p1 on p2.a=p1.a
              where p1.a is null
       ) as g
       
       /* Results:
       a  b	c

       1  34	500
       2  12	512
       3  22	NULL
       4  NULL	600

       */



ADDITIONAL TUTORIALS

Linux Quota Tutorial This tutorial walks you through implementing disk quotas for both users and groups on Linux, using a virtual filesystem, which is a filesystem created from a disk file. Since quotas work on a per-filesystem basis, this is a way to implement quotas on a sub-section, or even multiple subsections of your drive, without reformatting. This tutorial also covers quotactl, or quota's C interface, by way of an example program that can store disk usage in a SQLite database for monitoring data usage over time.

Gmail on Home Linux Box using Postfix and Fetchmail If you have a Google Gmail account, you can relay mail from your home linux system. It's a good exercise in configuring Postfix with TLS and SASL. Plus, you will learn how to bring down the mail safely, using fetchmail with the "sslcertck" option.

Breaking Firewalls with OpenSSH and PuTTY If the system administrator deliberately filters out all traffic except port 22 (ssh), to a single server, it is very likely that you can still gain access other computers behind the firewall. This article shows how remote Linux and Windows users can gain access to firewalled samba, mail, and http servers. In essence, it shows how openSSH and Putty can be used as a VPN solution for your home or workplace.

Create your own custom Live Linux CD These steps will show you how to create a functioning Linux system, with the latest 2.6 kernel compiled from source, and how to integrate the BusyBox utilities including the installation of DHCP. Plus, how to compile in the OpenSSH package on this CD based system. On system boot-up a filesystem will be created and the contents from the CD will be uncompressed and completely loaded into RAM -- the CD could be removed at this point for boot-up on a second computer. The remaining functioning system will have full ssh capabilities. You can take over any PC assuming, of course, you have configured the kernel with the appropriate drivers and the PC can boot from a CD.

SQLite Tutorial This article explores the power and simplicity of sqlite3, first by starting with common commands and triggers, then the attach statement with the union operation is introduced in a way that allows multiple tables, in separate databases, to be combined as one virtual table, without the overhead of copying or moving data. Next, the simple sign function and the amazingly powerful trick of using this function in SQL select statements to solve complex queries with a single pass through the data is demonstrated, after making a brief mathematical case for how the sign function defines the absolute value and IF conditions.

Lemon Parser Tutorial Lemon is a compact, thread safe, well-tested parser generator written by D. Richard Hipp. Using a parser generator, along with a scanner like flex, can be advantageous because there is less code to write. You just write the grammar for the parser. This article is an introduction to the Lemon Parser, complete with examples.



Chirico img Mike Chirico, a father of triplets (all girls) lives outside of Philadelphia, PA, USA. He has worked with Linux since 1996, has a Masters in Computer Science and Mathematics from Villanova University, and has worked in computer-related jobs from Wall Street to the University of Pennsylvania. His hero is Paul Erdos, a brilliant number theorist who was known for his open collaboration with others.


Mike's notes page is souptonuts. For open source consulting needs, please send an email to mchirico@gmail.com. All consulting work must include a donation to SourceForge.net.


SourceForge.net Logo