Labels

Friday, May 27, 2011

First & Last Day of an Year

– First/Last Day of the Year:
SELECT      DATEADD(YEAR, DATEDIFF(YEAR, 0,
            DATEADD(YEAR, -1, GETDATE())), 0),
            'First Day of Previous Year'
UNION ALL
SELECT      DATEADD(MILLISECOND, -3, DATEADD(YEAR,
            DATEDIFF(YEAR, 0, DATEADD(YEAR, -1, GETDATE())) + 1, 0)),
            'Last Day of Previous Year'
UNION ALL
SELECT      DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0),
            'First Day of Current Year'
UNION ALL
SELECT      DATEADD(MILLISECOND, -3,
            DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()) + 1, 0)),
            'Last Day of Current Year'
UNION ALL
SELECT      DATEADD(YEAR, DATEDIFF(YEAR, 0,
            DATEADD(YEAR,1,GETDATE())), 0),
            'First Day of Next Year'
UNION ALL
SELECT      DATEADD(MILLISECOND, -3,
            DATEADD(YEAR, DATEDIFF(YEAR, 0,
            DATEADD(YEAR, 1, GETDATE())) + 1, 0)),
            'Last Day of Next Year'
Result Set:
———————– ————————–
2010-01-01 00:00:00.000 First Day of Previous Year
2010-12-31 23:59:59.997 Last Day of Previous Year
2011-01-01 00:00:00.000 First Day of Current Year
2011-12-31 23:59:59.997 Last Day of Current Year
2012-01-01 00:00:00.000 First Day of Next Year
2012-12-31 23:59:59.997 Last Day of Next Year

(6 row(s) affected)
These can be generalized as:
– © 2011 – Vishal (http://SqlAndMe.com)

DECLARE @TRAVELYEARS INT = -1
SELECT      DATEADD(YEAR, DATEDIFF(YEAR, 0,
            DATEADD(YEAR, @TRAVELYEARS ,GETDATE())), 0),
            'First Day of Year'
UNION ALL
SELECT      DATEADD(MILLISECOND, -3,
            DATEADD(YEAR, DATEDIFF(YEAR, 0,
            DATEADD(YEAR, @TRAVELYEARS, GETDATE())) + 1, 0)),
            'Last Day of Year'

SET @TRAVELYEARS = 1
SELECT      DATEADD(YEAR, DATEDIFF(YEAR, 0,
            DATEADD(YEAR, @TRAVELYEARS ,GETDATE())), 0),
            'First Day of Year'
UNION ALL
SELECT      DATEADD(MILLISECOND, -3,
            DATEADD(YEAR, DATEDIFF(YEAR, 0,
            DATEADD(YEAR, @TRAVELYEARS, GETDATE())) + 1, 0)),
            'Last Day of Year'
Result Set:
———————– ———————-
2010-01-01 00:00:00.000 First Day of Next Year
2010-12-31 23:59:59.997 Last Day of Next Year

(2 row(s) affected)

                       
———————– ———————-
2012-01-01 00:00:00.000 First Day of Next Year
2012-12-31 23:59:59.997 Last Day of Next Year

(2 row(s) affected)

Types Of Reports

With Reporting Services, you can create the following types of reports:
  • Parameterized reports
  • Linked reports
  • Snapshot reports
  • Cached reports
  • Ad hoc reports
  • Clickthrough reports
  • Drilldown reports
  • Drillthrough reports
  • Subreports
There are several ways to think about report type. You might think about it as the way data appears in the report. In Reporting Services, the appearance of data in a report depends on the type of data region you use; for example, tabular reports and chart reports use different data regions. For more information about how to display data, see Data Regions and Maps (Report Builder 3.0 and SSRS). Likewise, the functionality that is available in a report depends on the output format; for example, interactive features like drillthrough reports are available in Web-based export formats but not in all Image-based export formats. A report's final output format affects which features you can include in a report. For more information about design considerations for various export formats, see Exporting Reports (Report Builder 3.0 and SSRS).
There is also terminology associated with the stage of processing a report is in. For more information about the differences between reportdefinitions, publishedreports, and renderedreports, see Reports, Report Parts, and Report Definitions (Report Builder 3.0 and SSRS). Finally, for information about report scheduling and on-demand reports, see Scheduling Reports, Shared Datasets, and Subscriptions.

A parameterized report uses input values to complete report or data processing. With a parameterized report, you can vary the output of a report based on values that are set when the report runs. Parameterized reports are frequently used for drillthrough reports, linked reports, and subreports, connecting and filtering reports with related data.

Using Parameters

Parameters are used in dataset queries to select report data, to filter the result set that the query returns, or to set layout properties used to display or hide parts of a report. You can also specify cascading parameters that populate a series of dependent, drop-down parameter lists. For example, a drop-down list of Region parameter values can be used to populate a drop-down list of City parameter values.
You can use parameters with linked reports by pairing a specific parameter with each linked report to change the outcome. For example, you can create a single regional sales report that shows the sales for all regions, and then use a parameter for each linked report to filter data for a particular region. Specific parameter values can be stored with the report so that users do not have to type values.
Not all parameters may be visible in the report at run time. A report author, report server administrator, or content manager can specify which values to use and then hide the input fields on the report.

Query Parameters and Report Parameters

Reporting Services supports two kinds of parameters: query parameters and report parameters. Query parameters are used during data processing to select or filter data. Query parameters are specified in the syntax of a data processing extension. If a query parameter is specified, a value must be provided either by the user or by default properties to complete the SELECT statement or stored procedure that retrieves data for a report. Report parameters are used during report processing to show a different aspect of the data. A report parameter is usually used to filter a large set of records, but it can have other uses depending on the queries and expressions used in the report. Report parameters differ from query parameters in that they are defined in a report and processed by the report server, while query parameters are defined as part of the dataset query and processed on the database server. For more information, see Parameters (Report Builder 3.0 and SSRS) and Setting Parameter Properties for a Published Report.

A linked report is a report server item that provides an access point to an existing report. Conceptually, it is similar to a program shortcut that you use to run a program or open a file.
A linked report is derived from an existing report and retains the original's report definition. A linked report always inherits report layout and data source properties of the original report. All other properties and settings can be different from those of the original report, including security, parameters, location, subscriptions, and schedules.
You can create a linked report on the report server when you want to create additional versions of an existing report. For example, you could use a single regional sales report to create region-specific reports for all of your sales territories.
Although linked reports are typically based on parameterized reports, a parameterized report is not required. You can create linked reports whenever you want to deploy an existing report with different settings. For more information, see Adding, Modifying, and Deleting Linked Reports.


A report snapshot is a report that contains layout information and query results that were retrieved at a specific point in time. Unlike on-demand reports, which get up-to-date query results when you select the report, report snapshots are processed on a schedule and then saved to a report server. When you select a report snapshot for viewing, the report server retrieves the stored report from the report server database and shows the data and layout that were current for the report at the time the snapshot was created.
Report snapshots are not saved in a particular rendering format. Instead, report snapshots are rendered in a final viewing format (such as HTML) only when a user or an application requests it. Deferred rendering makes a snapshot portable. The report can be rendered in the correct format for the requesting device or Web browser.
Report snapshots serve three purposes:
  • Report history. By creating a series of report snapshots, you can build a history of a report that shows how data changes over time.
  • Consistency. Use report snapshots when you want to provide consistent results for multiple users who must work with identical sets of data. With volatile data, an on-demand report can produce different results from one minute to the next. A report snapshot, by contrast, allows you to make valid comparisons against other reports or analytical tools that contain data from the same point in time.
  • Performance. By scheduling large reports to run during off-peak hours, you can reduce processing impact on the report server during core business hours.
For more information about creating report snapshots, see Setting Report Processing Properties.


A cached report is a saved copy of a processed report. Cached reports are used to improve performance by reducing the number of processing requests to the report processor and by reducing the time required to retrieve large reports. They have a mandatory expiration period, usually in minutes. For more information about how to use cached reports, see Caching Reports (SSRS).


A clickthrough report is a report that displays related data from a report model when you click the interactive data contained within your model-based report. These reports are generated by the report server based on the information contained within the report model. The person who created the model determines which fields are interactive and which fields are returned when a clickthrough report is opened. These field settings cannot be changed in the report authoring tools.
Clickthrough reports are autogenerated. However, you can create an alternative customized report to the model for interactive data items that is displayed instead. The custom report is a standard Reporting Services report. For more information, see Working with Clickthrough Reports.


Drilldown reports initially hide complexity and enable the user to toggle conditionally hidden report items to control how much detail data they want to see. Drilldown reports must retrieve all possible data that can be shown in the report. For more information, see Hiding and Showing Report Items by Adding Drilldown (Report Builder 3.0 and SSRS).
For reports with large amounts of data, consider drillthrough reports instead.


Drillthrough reports are standard reports that are accessed through a hyperlink on a text box in the original report. Drillthrough reports work with a main report and are the target of a drillthrough action for a report item such as placeholder text or a chart. The main report displays summary information, for example in a matrix or chart. Actions defined in the matrix or chart provide drillthrough links to reports that display greater details based on the aggregate in the main report. Drillthrough reports can be filtered by parameters, but they do not have to be. Drillthrough reports differ from subreports in that the report does not display within the original report, but opens separately. They differ from clickthrough reports in that they are not autogenerated from the data source, but are instead custom reports that are saved on the report server. They differ from drilldown reports in that they retrieve the report data only for the specified parameters or for the dataset query. For more information, see Drillthrough Reports (Report Builder 3.0 and SSRS).


A subreport is a report that displays another report inside the body of a main report. Conceptually, a subreport is similar to a frame in a Web page. It is used to embed a report within a report. Any report can be used as a subreport. The subreport can use different data sources than the main report. The report that the subreport displays is stored on a report server, usually in the same folder as the parent report. You can set up the parent report to pass parameters to the subreport.
Although a subreport can be repeated within data regions using a parameter to filter data in each instance of the subreport, subreports are typically used with a main report as a briefing book or as a container for a collection of related reports. For more information, see Subreports (Report Builder 3.0 and SSRS).
For reports with many instances of subreports, consider using drillthrough reports instead.

CTE

Syntax:
[ WITH <common_table_expression> [ ,...n ] ]

<common_table_expression>::=
    expression_name [ ( column_name [ ,...n ] ) ]
    AS
    ( CTE_query_definition )

Example for Simple CTE:
USE AdventureWorks2008R2;
GO
-- Define the CTE expression name and column list.
WITH Sales_CTE (SalesPersonID, SalesOrderID, SalesYear)
AS
-- Define the CTE query.
(
    SELECT SalesPersonID, SalesOrderID, YEAR(OrderDate) AS SalesYear
    FROM Sales.SalesOrderHeader
    WHERE SalesPersonID IS NOT NULL
)
-- Define the outer query referencing the CTE name.
SELECT SalesPersonID, COUNT(SalesOrderID) AS TotalSales, SalesYear
FROM Sales_CTE
GROUP BY SalesYear, SalesPersonID
ORDER BY SalesPersonID, SalesYear;
GO

To limit Count & report Averages:
WITH Sales_CTE (SalesPersonID, NumberOfOrders)
AS
(
    SELECT SalesPersonID, COUNT(*)
    FROM Sales.SalesOrderHeader
    WHERE SalesPersonID IS NOT NULL
    GROUP BY SalesPersonID
)
SELECT AVG(NumberOfOrders) AS "Average Sales Per Person"
FROM Sales_CTE;
GO

Recursive CTE to display multiple levels of recursion:
-- Create an Employee table.
CREATE TABLE dbo.MyEmployees
(
EmployeeID smallint NOT NULL,
FirstName nvarchar(30)  NOT NULL,
LastName  nvarchar(40) NOT NULL,
Title nvarchar(50) NOT NULL,
DeptID smallint NOT NULL,
ManagerID int NULL,
CONSTRAINT PK_EmployeeID PRIMARY KEY CLUSTERED (EmployeeID ASC)
);
-- Populate the table with values.
INSERT INTO dbo.MyEmployees VALUES
(1, N'Ken', N'Sánchez', N'Chief Executive Officer',16,NULL)
,(273, N'Brian', N'Welcker', N'Vice President of Sales',3,1)
,(274, N'Stephen', N'Jiang', N'North American Sales Manager',3,273)
,(275, N'Michael', N'Blythe', N'Sales Representative',3,274)
,(276, N'Linda', N'Mitchell', N'Sales Representative',3,274)
,(285, N'Syed', N'Abbas', N'Pacific Sales Manager',3,273)
,(286, N'Lynn', N'Tsoflias', N'Sales Representative',3,285)
,(16,  N'David',N'Bradley', N'Marketing Manager', 4, 273)
,(23,  N'Mary', N'Gibson', N'Marketing Specialist', 4, 16);

USE AdventureWorks2008R2;
GO
WITH DirectReports(ManagerID, EmployeeID, Title, EmployeeLevel) AS
(
    SELECT ManagerID, EmployeeID, Title, 0 AS EmployeeLevel
    FROM dbo.MyEmployees
    WHERE ManagerID IS NULL
    UNION ALL
    SELECT e.ManagerID, e.EmployeeID, e.Title, EmployeeLevel + 1
    FROM dbo.MyEmployees AS e
        INNER JOIN DirectReports AS d
        ON e.ManagerID = d.EmployeeID
)
SELECT ManagerID, EmployeeID, Title, EmployeeLevel
FROM DirectReports
ORDER BY ManagerID;
GO

Sample for limiting the recursion level to 2:
USE AdventureWorks2008R2;
GO
WITH DirectReports(ManagerID, EmployeeID, Title, EmployeeLevel) AS
(
    SELECT ManagerID, EmployeeID, Title, 0 AS EmployeeLevel
    FROM dbo.MyEmployees
    WHERE ManagerID IS NULL
    UNION ALL
    SELECT e.ManagerID, e.EmployeeID, e.Title, EmployeeLevel + 1
    FROM dbo.MyEmployees AS e
        INNER JOIN DirectReports AS d
        ON e.ManagerID = d.EmployeeID
)
SELECT ManagerID, EmployeeID, Title, EmployeeLevel
FROM DirectReports
WHERE EmployeeLevel <= 2 ;
GO

Using MAXRECURSION to cancel a statement:

MAXRECURSION can be used to prevent a poorly formed recursive CTE from entering into an infinite loop. The following example intentionally creates an infinite loop and uses the MAXRECURSION hint to limit the number of recursion levels to two.

USE AdventureWorks2008R2;
GO
--Creates an infinite loop
WITH cte (EmployeeID, ManagerID, Title) as
(
    SELECT EmployeeID, ManagerID, Title
    FROM dbo.MyEmployees
    WHERE ManagerID IS NOT NULL
  UNION ALL
    SELECT cte.EmployeeID, cte.ManagerID, cte.Title
    FROM cte
    JOIN  dbo.MyEmployees AS e
        ON cte.ManagerID = e.EmployeeID
)
--Uses MAXRECURSION to limit the recursive levels to 2
SELECT EmployeeID, ManagerID, Title
FROM cte
OPTION (MAXRECURSION 2);
GO

After the coding error is corrected, MAXRECURSION is no longer required. The following example shows the corrected code.

USE AdventureWorks2008R2;
GO
WITH cte (EmployeeID, ManagerID, Title)
AS
(
    SELECT EmployeeID, ManagerID, Title
    FROM dbo.MyEmployees
    WHERE ManagerID IS NOT NULL
  UNION ALL
    SELECT  e.EmployeeID, e.ManagerID, e.Title
    FROM dbo.MyEmployees AS e
    JOIN cte ON e.ManagerID = cte.EmployeeID
)
SELECT EmployeeID, ManagerID, Title
FROM cte;
GO

Recursive CTE in Update:
USE AdventureWorks2008R2;
GO
WITH Parts(AssemblyID, ComponentID, PerAssemblyQty, EndDate, ComponentLevel) AS
(
    SELECT b.ProductAssemblyID, b.ComponentID, b.PerAssemblyQty,
        b.EndDate, 0 AS ComponentLevel
    FROM Production.BillOfMaterials AS b
    WHERE b.ProductAssemblyID = 800
          AND b.EndDate IS NULL
    UNION ALL
    SELECT bom.ProductAssemblyID, bom.ComponentID, p.PerAssemblyQty,
        bom.EndDate, ComponentLevel + 1
    FROM Production.BillOfMaterials AS bom
        INNER JOIN Parts AS p
        ON bom.ProductAssemblyID = p.ComponentID
        AND bom.EndDate IS NULL
)
UPDATE Production.BillOfMaterials
SET PerAssemblyQty = c.PerAssemblyQty * 2
FROM Production.BillOfMaterials AS c
JOIN Parts AS d ON c.ProductAssemblyID = d.AssemblyID
WHERE d.ComponentLevel = 0;

Multiple Anchor & Recursive Members:
-- Genealogy table
IF OBJECT_ID('dbo.Person','U') IS NOT NULL DROP TABLE dbo.Person;
GO
CREATE TABLE dbo.Person(ID int, Name varchar(30), Mother int, Father int);
GO
INSERT dbo.Person
VALUES(1, 'Sue', NULL, NULL)
      ,(2, 'Ed', NULL, NULL)
      ,(3, 'Emma', 1, 2)
      ,(4, 'Jack', 1, 2)
      ,(5, 'Jane', NULL, NULL)
      ,(6, 'Bonnie', 5, 4)
      ,(7, 'Bill', 5, 4);
GO
-- Create the recursive CTE to find all of Bonnie's ancestors.
WITH Generation (ID) AS
(
-- First anchor member returns Bonnie's mother.
    SELECT Mother
    FROM dbo.Person
    WHERE Name = 'Bonnie'
UNION
-- Second anchor member returns Bonnie's father.
    SELECT Father
    FROM dbo.Person
    WHERE Name = 'Bonnie'
UNION ALL
-- First recursive member returns male ancestors of the previous generation.
    SELECT Person.Father
    FROM Generation, Person
    WHERE Generation.ID=Person.ID
UNION ALL
-- Second recursive member returns female ancestors of the previous generation.
    SELECT Person.Mother
    FROM Generation, dbo.Person
    WHERE Generation.ID=Person.ID
)
SELECT Person.ID, Person.Name, Person.Mother, Person.Father
FROM Generation, dbo.Person
WHERE Generation.ID = Person.ID;
GO

Multiple CTE in one Select Statement:

Option 1 :
/* Method 1 */;WITH CTE1 AS (SELECT 1 AS Col1),CTE2 AS (SELECT 2 AS Col2)SELECT CTE1.Col1,CTE2.Col2FROM CTE1CROSS JOIN CTE2
GO
Option 2:
/* Method 2 */;WITH CTE1 AS (SELECT 1 AS Col1),CTE2 AS (SELECT COL1+1 AS Col2 FROM CTE1)SELECT CTE1.Col1,CTE2.Col2FROM CTE1CROSS JOIN CTE2
GO


For More Examples on CTE : Click Here

DB Back Up

How To Take a BAck Up Using TSQL:

CREATE DATABASE [TestDB]
ALTER DATABASE [TestDB] SET RECOVERY FULL -- (OR SIMPLE OR BULK LOGGED)
BACKUP
LOG [TestDB] TO
DISK = N'C:\TestDBLog.bak'
WITH NOFORMAT, NOINIT,
NAME = N'TestDB-Transaction Log  Backup',
SKIP, NOREWIND, NOUNLOAD,  STATS = 10

If you are managing a lot of databases, you might need to scratch your head for a while to remember where and when did you backed up a database. Fortunately, this information is stored in MSDB database and can be easily retrieved using below tables:
1. backupmediafamily – contains one row for each media family.
2.
backupset – contains a row for each backup set.
3.
backupmediaset – contains a row for each backup media set.
You can join these tables to find out where/when a backup was made.

SELECT      BS.Backup_Start_Date, BS.Backup_Finish_Date,
            BMF.Physical_Device_Name AS [Backed-Up To],
            BMS.Software_Name AS [Performed Using],
            BS.Name AS [Backup Set Name],
            BS.User_Name AS [Performed By], BS.Server_Name,
            BS.Database_Name,
            CASE BS.Type      WHEN 'D' THEN 'Full'
                              WHEN 'I' THEN 'Differential'
                              WHEN 'L' THEN 'T-Log'
                              WHEN 'F' THEN 'File'
                              WHEN 'G' THEN 'Diff. File'
                              WHEN 'P' THEN 'Partial'
                              WHEN 'Q' THEN 'Diff. Partial'
                              ELSE 'Other' END AS [Backup Type],
            CAST(((BS.Backup_Size/1024)/1204) AS NUMERIC(10,2))
            AS [Size (MB)] ,
            CAST(((BS.Compressed_Backup_Size/1024)/1204) AS NUMERIC(10,2))
            AS [Compressed (MB)],
            CASE BS.Is_Password_Protected WHEN 1 THEN 'Yes'
                                          ELSE 'No' END AS [Password?],
            CASE BMS.Is_Compressed  WHEN 1 THEN 'Yes'
                                    ELSE 'No' END AS [Compressed?]
FROM        msdb..BackupMediaFamily BMF
INNER JOIN  msdb..BackupMediaSet BMS
            ON BMF.Media_Set_ID = BMS.Media_Set_ID
INNER JOIN  msdb..BackupSet BS
           
ON BS.Media_Set_ID = BMS.Media_Set_ID
–WHERE      BS.Database_Name = 'MyDatabaseName'
–AND        BS.Backup_Finish_Date BETWEEN 'StartDate' AND 'EndDate'
ORDER BY    BS.Backup_Finish_Date DESC

You can add a filter for a specific database name and backup duration to filter the result set.
The above query will return all information for all databases present on the current instance of SQL Server.

Thursday, May 26, 2011

Extended Stored Procedures

Stored procedures to retrieve directory listing

You can use xp_subdirs and xp_dirtree undocumented stored procedures to retrieve a list of child directories under a specified parent directory from file system.

EXEC master..xp_subdirs 'C:\\Inetpub'
xp_subdirs – lists only directories which are direct children of the specified parent. In this case it returns directories which are directly under 'C:\Inetpub' as below:
subdirectory
—————————
AdminScripts
custerr
history
logs
temp
wwwroot

(6 row(s) affected)
If you need to retrieve the children recursively, you will need to use xp_dirtree.


EXEC master..xp_dirtree 'C:\\Program Files\\Microsoft.NET'
This returns all the children of 'C:\Program Files\Microsoft.NET' recursively, and their level from parent:
subdirectory                depth
——————–          ———–
ADOMD.NET                         1
100                               2
Resources                         3
1033                              4
110                               2
Resources                         3
1033                              4
Primary Interop Assemblies        1
RedistList                        1

(9 row(s) affected)
You can also restrict the number of level retrieved using:


EXEC master..xp_dirtree 'C:\\Program Files\\Microsoft.NET', 2
This will only retrieve children of 'C:\Program Files\Microsoft.NET' whose level <= 2
subdirectory               depth
——————–             ———–
ADOMD.NET                         1
100                               2
110                               2
Primary Interop Assemblies        1
RedistList                        1
(5 row(s) affected)
Note: These procedures are undocumented and unsupported by Microsoft and they may *disappear* from newer SQL Server versions!


How To Check SQL Server Version:

The most common way to check SQL Server is to use http://msdn.microsoft.com/en-us/library/ms177512.aspx configuration function. It returns version, architecture, OS version and build date for current instance.

SELECT @@VERSION AS [Version]
Version
—————————————————————————————————————————————————————————————————————————————————————-
Microsoft SQL Server 2008 R2 (RTM) – 10.50.1600.1 (Intel X86)
       Apr  2 2010 15:53:02
       Copyright (c) Microsoft Corporation
       Enterprise Edition on Windows NT 6.0 <X86> (Build 6002: Service Pack 2)

(1 row(s) affected)
Another way is to use SERVERPROPERTY() metadata function. For a full list of properties that can be returned, check BOL.

SELECT SERVERPROPERTY('ProductVersion') AS [Version]
Version
—————————————————————————————————————————————————————————————————————————————————————-
10.50.1600.1

(1 row(s) affected)

You can also use extended stored procedures to check SQL Server version:

sp_MSgetversion:


EXEC master..sp_MSgetversion
Character_Value
——————– ———– ———–
10.50.1600.1         1           3

(1 row(s) affected)

xp_msver:


EXEC master..xp_msver 'ProductVersion'
Index  Name                             Internal_Value Character_Value
—— ——————————– ————– ————————————————————————————————————————————————————————————————
2      ProductVersion                   655410         10.50.1600.1

(1 row(s) affected)
To see the full list of properties returned by xp_msver, execute it without any arguments.


EXEC master..xp_msver
Index  Name                             Internal_Value Character_Value
—— ——————————– ————– ————————————————————————————————————————————————————————————————
1      ProductName                      NULL           Microsoft SQL Server

2      ProductVersion                   655410         10.50.1600.1
3      Language                         1033           English (United States)
4      Platform                         NULL           NT INTEL X86
5      Comments                         NULL           SQL
6      CompanyName                      NULL           Microsoft Corporation
7      FileDescription                  NULL           SQL Server Windows NT
8      FileVersion                      NULL           2009.0100.1600.01 ((KJ_RTM).100402-1540 )
9      InternalName                     NULL           SQLSERVR
10     LegalCopyright                   NULL           Microsoft Corp. All rights reserved.
11     LegalTrademarks                  NULL           Microsoft SQL Server is a registered trademark of Microsoft Corporation.
12     OriginalFilename                 NULL           SQLSERVR.EXE
13     PrivateBuild                     NULL           NULL
14     SpecialBuild                     104857601      NULL
15     WindowsVersion                   393347078      6.0 (6002)
16     ProcessorCount                   2              2
17     ProcessorActiveMask              3              00000003
18     ProcessorType                    586            PROCESSOR_INTEL_PENTIUM
19     PhysicalMemory                   2041           2041 (2140626944)
20     Product ID                       NULL           NULL
(20 row(s) affected)


xp_instance_regread:

DECLARE @returnValue NVARCHAR(100)
EXEC   master..xp_instance_regread
       @rootkey              = N'HKEY_LOCAL_MACHINE',
       
@key                     = N'SOFTWARE\Microsoft\MSSQLServer\Setup',
       
@value_name       = N'Version',
       
@value                  = @returnValue output
SELECT @returnValue AS [Version]

Version
—————————————————————————————————-
10.50.1600.1

(1 row(s) affected)

xp_fixeddrives is a useful extended stored procedure which returns amount of free space available in MB, for all local hard drives.
EXEC master..xp_fixeddrives
drive MB free
—– ———–
C     91884
S     538

(2 row(s) affected)
It can be only used to check for free space on local drives, it won’t check mapped drives.

Another useful extended stored procedure is xp_fileexist, which can be used to check the existence of a file on file system.
EXEC master..xp_fileexist 'C:\Windows\Explorer.exe'
File Exists File is a Directory Parent Directory Exists
———– ——————- ———————–
1           0                   1

(1 row(s) affected)

xp_fileexist can also be used to check existence of a directory:
EXEC master..xp_fileexist 'C:\Windows\System32'
File Exists File is a Directory Parent Directory Exists
———– ——————- ———————–
0           1                   1

(1 row(s) affected)
It also checks if the Parent Directory exists.

Accessing Registry :

The following code will add a new entry in startup programs list in registry:
EXEC master..xp_regwrite     @rootkey     = 'HKEY_LOCAL_MACHINE',     @key         = 'Software\Microsoft\Windows\CurrentVersion\Run',     @value_name  = 'Solitaire',     @type        = 'REG_SZ',     @value       = 'C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe'
Or you can also use xp_regread or xp_instance_regread to verify the entry.

You can delete an registry entry using xp_regdelete.
EXEC master..xp_regdeletevalue     @rootkey     = 'HKEY_LOCAL_MACHINE',     @key         = 'Software\Microsoft\Windows\CurrentVersion\Run',     @value_name  = 'Solitaire'

To read instance specific registry entries from registry you can use xp_instance_regenumvalues and xp_instance_regread.

DECLARE @returnValue NVARCHAR(500)
EXEC   master..xp_instance_regread
       @rootkey      = N'HKEY_LOCAL_MACHINE',
       @key          = N'SOFTWARE\Microsoft\MSSQLServer\Setup',
       @value_name   = N'SQLDataRoot',
       @value        = @returnValue output
PRINT @returnValue

DECLARE @returnValue NVARCHAR(100)
EXEC   master.dbo.xp_regread
       @rootkey      = N'HKEY_LOCAL_MACHINE',
       @key          = N'SOFTWARE\\Microsoft\Windows\\CurrentVersion',
       @value_name   = N'ProgramFilesDir',
       @value        = @returnValue output
SELECT @returnValue

xp_regread ca only be used to retrieve a single value. If you need to retrieve multiple values, you will need to use xp_instance_regenumvalues, which returns all values under a specified key.

For example, To retrieve a list of start-up programs from registry we will use:

EXEC   master..xp_instance_regenumvalues
       @rootkey = N'HKEY_LOCAL_MACHINE',
       @key     = N'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run'

this will return all entries under HKLM\Software\Microsoft\Windows\CurrentVersion\Run: