Import Excel Data Into SQL Server

Importing an xls file into a database is as simple as (run from query analyzer):

INSERT INTO Generic_Testing_1.dbo.Table_Name
SELECT * FROM OPENROWSET(’Microsoft.Jet.OLEDB.4.0′,’Excel 8.0;Database=G:\Testing\Excel_File.xls’, [WorkSheet_Name])

The code above inserts the records from WorkSheet_Name worksheet of the Excel_File.xls into Table_Name table of the Generic_Testing_1 database.

NOTE: You must enable “AdHoc Distributed Queries” on your SQL Server in order to run the sql above

sp_configure ’show advanced options’, 1;
GO
RECONFIGURE;
GO
sp_configure ‘Ad Hoc Distributed Queries’, 1;
GO
RECONFIGURE;
GO

Import Data from a source file using OPENROWSET

Here is a query that imports data from a source file using OPENROWSET

 DECLARE @sqlScript1 VARCHAR(8000)

 -- Import records fron source file (OPENROWSET)

SET @sqlScript1 =

‘SELECT * INTO ##tmpOrders FROM OPENROWSET(”Microsoft.Jet.OLEDB.4.0” ,

”Excel 8.0;Database=’

 

+ @fileName +

”’, ”SELECT [Sale Time] AS SaleTime, Ref, [Item Title] AS ItemTitle, [Item Type] AS ItemType, [Item Id] AS ItemId,

Quantity AS Qty, Amount, [Buyer Id] AS BuyerId, [Email Address] AS EmailAddress, [Day Phone] AS DayPhone, [Evening Phone] AS EveningPhone, [Preferred Contact Time] AS PreferredContactTime,

[First Name] AS FirstName, [Last Name] AS LastName, [Address Line 1] AS AddressLine1, [Address Line 2] AS AddressLine2, [Shipping Locality] AS ShippingLocality, [Postal Code] AS PostalCode,

Country, [Order Id] AS OrderId, [Order Amount] AS OrderAmount, [Delivery First Name] AS DeliveryFirstName, [Delivery Last Name] AS DeliveryLastName, [Delivery Address Line 1] AS DeliveryAddressLine1,

[Delivery Address Line 2] AS DeliveryAddressLine2, [Delivery Location] AS DeliveryLocation, [Delivery Postal Code] AS DeliveryPostalCode, [Delivery Country] AS DeliveryCountry, [Delivery Telephone 1] AS DeliveryTelephone1,

[Delivery Telephone 2] AS DeliveryTelephone2, [Online Payment Status] AS OnlinePaymentStatus, [You Rating Buyer] AS YouRatingBuyer, [Buyer Rating You] AS BuyerRatingYou, [SNC Status] AS SNCStatus, [View Item] AS ViewItem,

[View Buyer] AS ViewBuyer, [Email Buyer] AS EmailBuyer, [View Order] AS ViewOrder, [Accept or Reject Credit Card Payments] AS CreditCardPayments, [Rate Buyer] AS RateBuyer, [Reply to Buyer Rating] AS ReplyToBuyerRating,

SNC, [Buyers Note] AS BuyersNote FROM BoBExport$”)’

 

EXEC (@sqlScript1

) 

SELECT * FROM ##tmpOrders

Example of the queries you can write with OpenDataSource

Here is an example of a quite complex query joining the data from both database and excel spreadsheet that is using OpenDataSource:

Insert into OpenDataSource(
‘Microsoft.Jet.OLEDB.4.0′,
‘Data Source=”H:\Imran\Capacity Planning 0708\UHL Spells Apr 05 to Sept 07 TEST.xls”;
Extended properties=Excel 5.0′)…[PivotSh$]
(Provider_Code, Commissioner_Code, LSS_Flag, Financial_Year, Financial_Month, Qtr,
Description_Contract, Activity_Type_Grouped, Sum_of_Spells)

Select Provider_Code, Commissioner_Code, LSS_Flag, Financial_Year, Financial_Month,
Case When Financial_Month between ‘1′ and ‘3′ Then ‘Qtr 1′
When Financial_Month between ‘4′ and ‘6′ Then ‘Qtr 2′
When Financial_Month between ‘7′ and ‘9′ Then ‘Qtr 3′
When Financial_Month between ‘10′ and ‘12′ Then ‘Qtr 4′ Else ” End as Qtr,
Description_Contract,
Case When Activity_Type in (’Emergency’,'Non-elective’) Then ‘Non-Elective’
Else Activity_Type End as Activity_Type_Grouped,
SUM(Total_Spells) as Sum_of_Spells

From [Busobjects].Capacity_Planning.dbo.tbl_BaseLine_UHL_Spells_Tre nd_0708 a

Inner Join OpenDataSource( ‘Microsoft.Jet.OLEDB.4.0′,
‘Data Source=”H:\Imran\Capacity Planning 0708\UHL Spells Apr 05 to Sept 07 TEST.xls”;
Extended properties=Excel 5.0′)…[SPECIALTY TREND by Month$] as PR
On PR.P1 = Commissioner_Code
AND PR.P2 = LSS_Flag
AND PR.P3 = Description_Contract
AND PR.P4 = (Case When Activity_Type in (’Emergency’,'Non-elective’) Then ‘Non-Elective’
Else Activity_Type END)

Left Outer Join [Busobjects].Capacity_Planning.dbo.tbl_Refs_Specialty_UHL b
on a.Specialty_Code = b.Code

Left Outer Join [Busobjects].Capacity_Planning.dbo.tbl_Refs_IP_SpecServ_0708 c
on a.Specialised_Services_Code = c.SpecServ

Left Outer Join [Busobjects].Capacity_Planning.dbo.tbl_Refs_IP_HRG_Tariff_0708 d
on a.HRG_Code = d.HRGCode

Group by Provider_Code, Commissioner_Code, LSS_Flag, Financial_Year, Financial_Month,
Case When Financial_Month between ‘1′ and ‘3′ Then ‘Qtr 1′
When Financial_Month between ‘4′ and ‘6′ Then ‘Qtr 2′
When Financial_Month between ‘7′ and ‘9′ Then ‘Qtr 3′
When Financial_Month between ‘10′ and ‘12′ Then ‘Qtr 4′ Else ” End,
/*Specialty_Code,*/ Description_Contract, –Activity_Type,
Case When Activity_Type in (’Emergency’,'Non-elective’) Then ‘Non-Elective’
Else Activity_Type End–, HRG_Code + ‘: ‘+ d.HRGDesc,
–Specialised_Services_Code + ‘: ‘+c.Description

Importing and Exporting SQL Server Data from the Command Line with bcp

The bulk copy (bcp) command of Microsoft SQL Server provides you with the ability to insert large numbers of records directly from the command line. In addition to being a great tool for command-line aficionados, bcp is a powerful tool for those seeking to insert data into a SQL Server database from within a batch file or other programmatic method.

In order to run T-SQL Queries outside of the SQL Query Analyzer window is SQL Server “AdHoc Distributed Queries” option should be turned on @ SQL Server

sp_configure ’show advanced options’, 1;
GO
RECONFIGURE;
GO
sp_configure ‘Ad Hoc Distributed Queries’, 1;
GO
RECONFIGURE;
GO

bcp Syntax

The basic syntax for using bcp is:

bcp <table_name> <direction> <file_name> <options>

Where the arguments take the following values:

table_name is the fully qualified name of the table. For example, you might use inventory.dbo.fruits to insert records into the fruits table, owned by the database owner, in the inventory database.
direction indicates whether you want to import (“in” direction) or export (“out” direction) data.
file_name is the full path to the file. For example, you could import the file C:\fruit\inventory.txt.
options allow you to specify parameters for the bulk operation. For example, you can specify the maximum number of errors allowed with the –m option. You may also use the –x option to specify an XML file format. Consult Microsoft’s bcp documentation for a full list.

bcp Import Example

Let’s put it all together. Imagine that you have a fruits table in your inventory database and that you want to programmatically import all of the records from a text file stored on your hard drive into that database. You would use the following bcp command syntax:

bcp inventory.dbo.fruits in “C:\fruit\inventory.txt” -c -T

This would produce the following output:

C:\>bcp inventory.dbo.fruits in “C:\fruit\inventory.txt” -c -T

Starting copy…

36 rows copied.
Network packet size (bytes): 4096
Clock Time (ms.) Total : 16 Average : (2250.00 rows per sec.)
C:\>

If you’re sharp-eyed, you might have noticed that I slipped in two new options on that command line. The –c option specifies that the file format of the import file will be tab-delimited text with each record on a new line. The –T option specifies that bcp should use Windows authentication to connect to the database.

bcp Export Example

As I mentioned earlier, you can export data from your database with bcp by changing the direction of the operation from “in” to “out”. For example, we could dump the contents of the fruit table to a text file with the following command:

bcp inventory.dbo.fruits out “C:\fruit\inventory.txt” -c -T

Here’s how that looks on the command line:

C:\>bcp inventory.dbo.fruits out “C:\fruit\inventory.txt” -c -T

Starting copy…

42 rows copied.
Network packet size (bytes): 4096
Clock Time (ms.) Total : 1 Average : (42000.00 rows per sec.)
C:\>

That’s all there is to the bcp command. You may use this command from within batch files or other programs with access to the DOS command line to automate the import and export of data from your SQL Server database.

Different Options for Importing Data into SQL Server

Problem
Moving data into SQL Server is something that most DBAs or Developers are faced with probably on a daily basis. One simple way of doing this is by using the Import / Export wizard, but along with this option there are several other ways of loading data into SQL Server tables. Another common technique would be to use either DTS (SQL 2000) or SSIS (SQL 2005). In this tip we take a look at some of these other options for importing data into SQL Server.

Solution
In addition to using the Import / Export wizards and/or DTS or SSIS to move data into SQL Server there are also a few other options for doing this that are built into SQL Server. Some these other options include bcp, BULK INSERT, OPENROWSET as well as others. The following examples show you some of these different options for importing data and how you can use some of these inline with your T-SQL code as well as others that can be run from the command line.

BCP
This is one of the options that is mostly widely used. One reason for this is that it has been around for awhile, so DBAs have come quite familiar with this command. This command allows you to both import and export data, but is primarily used for text data formats. In addition, this command is generally run from a Windows command prompt, but could also be called from a stored procedure by using xp_cmdshell or called from a DTS or SSIS package.

Here is a simple command for importing data from file C:\ImportData.txt into table dbo.ImportTest.

bcp dbo.ImportTest in ‘C:\ImportData.txt’ -T -SserverName\instanceName

BULK INSERT
This command is a T-SQL command that allows you to import data directly from within SQL Server by using T-SQL. This command imports data from file C:\ImportData.txt into table dbo.ImportTest.

BULK INSERT dbo.ImportTest
FROM ‘C:\ImportData.txt’
WITH ( FIELDTERMINATOR =’,', FIRSTROW = 2 )

OPENROWSET
This command is a T-SQL command that allows you to query data from other data sources directly from within SQL Server. By using this command along with an INSERT INTO command we can load data from the specified data source into a SQL Server table.

This command will pull in all data from worksheet [Sheet1$]. By using the INSERT INTO command you can insert the query results into table dbo.ImportTest.

INSERT INTO dbo.ImportTest
SELECT * FROM OPENROWSET(’Microsoft.Jet.OLEDB.4.0′,
‘Excel 8.0;Database=C:\ImportData.xls’, [Sheet1$])

Two things to remember while running the script above:

1) The script below works fine when you are logged in with username ’sa’ and psswrd ’sa’ but when you log in with another user name and password I get the following error:
2) In order to run T-SQL Queries outside of the SQL Query Analyzer window is SQL Server “AdHoc Distributed Queries” option should be turned on @ SQL Server. Run the sql script below to enable “AdHoc Distributed Queries”sp_configure ’show advanced options’, 1;
GO
RECONFIGURE;
GO
sp_configure ‘Ad Hoc Distributed Queries’, 1;
GO
RECONFIGURE;
GO

 

Here is another example where data is pulled from worksheet [Sheet1$] by using a SELECT * FROM command. Again, by using the INSERT INTO command you can insert the query results into table dbo.ImportTest. The query can be any valid SQL query, so you can filter the columns and rows by using this option.

INSERT INTO dbo.ImportTest
SELECT * FROM OPENROWSET(’Microsoft.Jet.OLEDB.4.0′,
‘Excel 8.0;Database=C:\ImportData.xls’, ‘SELECT * FROM [Sheet1$]‘)

OPENDATASOURCE
This command is a T-SQL command that allows you to query data from other data sources directly from within SQL Server. This is similar to the OPENROWSET command.

INSERT INTO dbo.ImportTest
SELECT * FROM OPENDATASOURCE(’Microsoft.Jet.OLEDB.4.0′,
‘Data Source=C:\ImportData.xls;Extended Properties=Excel 8.0′)…[Sheet1$]

Here is an example of importing data from a Text file using OpenDataSource:

insert into tbltst (field1, field2) SELECT field1, field2 FROM OpenDataSource(’Microsoft.Jet.OLEDB.4.0′,’Data Source=c:\temp;Extended properties=Text’)…tstfile#txt

OPENQUERY
Another option is OPENQUERY. This is another command that allows you to issue a T-SQL command to select data and again with the INSERT INTO option we can load data into our table. There are two steps with this process, first a linked server is setup and then second the query is issued using the OPENQUERY command. This option allow you to filter the columns and rows by the query that is issued against your linked data source.

EXEC sp_addlinkedserver ‘ImportData’,
‘Jet 4.0′, ‘Microsoft.Jet.OLEDB.4.0′,
‘C:\ImportData.xls’,
NULL,
‘Excel 8.0′
GO

INSERT INTO dbo.ImportTest
SELECT *
FROM OPENQUERY(ImportData, ‘SELECT * FROM [Sheet1$]‘)

Linked Servers
Here is yet another option with setting up a linked server and then issuing a straight SQL statement against the linked server. This again has two steps, first the linked server is setup and secondly a SQL command is issued against the linked data source.

EXEC sp_addlinkedserver ‘ImportData’,
‘Jet 4.0′, ‘Microsoft.Jet.OLEDB.4.0′,
‘C:\ImportData.xls’,
NULL,
‘Excel 8.0′
GO

INSERT INTO dbo.ImportTest
SELECT * FROM ImportData…Sheet1$

Which Port SQL Server is Using (listening)

SQL Server is a Winsock application that communicates over TCP/IP using the sockets network library. The SQL Server listens for incoming connections on a particular port; the default port for SQL Server is 1433. The port doesn’t need to be 1433, but 1433 is the official Internet Assigned Number Authority (IANA) socket number for SQL Server.

There is no way to limit the number of source TCP ports used for a SQL Server client to connect; this would defeat the purpose of having the client allocate a new, unused dynamic port. This is a TCP/IP standard that is defined for Winsock applications; this is not a limitation of SQL Server client communication.
In addition, a named instance of SQL Server 2000 will use a dynamic destination port by default. This port should be changed to a fixed port prior to configuring the firewall. The SQL Server Network Utility should be used to configure the destination port. See SQL Server Books Online for information on how to use the SQL Server Network Utility.

When a SQL Server instance supports the TCP/IP protocol, it listens for incoming connections on particular TCP ports. By default, a default instance is configured to use a fixed port 1433, and a named instance is configured to use dynamic ports. However, you can change the fixed port of a default instance, or make the named instance use a fixed port with Configuration Manager.

You cannot connect to a SQL Server instance using TCP/IP protocol without knowing the port number it is listening on. Although SQL Server Browser service introduced in SQL Server 2005 can help translate an instance name to its associated port number, it is not guaranteed SQL Server Browser service is always running. Windows Firewall may block the UDP port 1434 that SQL Server Browser service uses as well. You can find the port number of a SQL Server instance using Configuration Manager. However, Configuration Manager is GUI-based and only works locally. In this article, we will show a script that returns the TCP port used by an instance on a SQL Server host. This script can run locally on the SQL Server host or remotely. In an Enterprise environment, this script can be used to collect an inventory of all SQL Server instances and their port numbers from a central admin server.

In our script, we assume the ListenAll option is enabled on SQL Server 2005 (or later) servers so all the network cards listen on the same port. This is usually the case unless special security concerns and NUMA are taken into consideration. Like SQL Server Browser, our script reads the registry on SQL Server host. TCP port number is stored in a value called TCPPort under the TCP/IP registry key for a SQL Server instance. For different SQL Server products, the location of the TCP/IP registry key is different. Here we list the location for each product.
SQL Server 2000

Default instance

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\SuperSocketNetLib\TCP

Named instance

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\(InstanceName)\MSSQLServer\SuperSocketNetLib\TCP

SQL Server 2005

There is no distinction between default and named instances. An instance is assigned a number based on the order it was installed. We first need to locate the registry key for the instance, which looks like

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL.#

# is the number assigned to the instance. The instance name is stored as the default value for this registry key. For a default instance, it is MSSQLSERVER.

Once the registry key for the instance is found, we know the TCP/IP registry key is

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL.#\MSSQLServer\SuperSocketNetLib\TCP\IPAll

SQL Server 2008

Default instance

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQLServer\SuperSocketNetLib\TCP\IPAll

Named instance

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10.(InstanceName)\MSSQLServer\SuperSocketNetLib\TCP\IPAll

However, if two SQL Server products exist on one host, then the location of the registry key could differ from above. For example, if SQL Server 2005 or 2008 are installed on the same host after SQL Server 2000, then the TCP/IP registry key of SQL Server 2005 or 2008 will follow the SQL Server 2000 format. Say, if a SQL Server 2000 instance INST2000 and a SQL Server 2005 instance INST2005 are installed on a host sequentially, then the registry key for the TCP/IP protocol of the SQL Server 2005 instance would reside at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\INST2005\MSSQLServer\SuperSocketNetLib\TCP, not HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL.1\MSSQLServer\SuperSocketNetLib\TCP\IPAll.

Script Get-TCPPort.ps1 accepts two arguments, a host name and an instance name. Of course, to run this script, you need the permission to query the registry on the host. By default, only members of the Administrators group can access the registry remotely.

CONVERT statement should be placed OUTSIDE of SUM

Lets say you want to convert your SUM to 12 decmal places.

In this case put CONVERT statement outside of SUM, i.e.

CONVERT(DECIMAL(18,8),sum(FieldName))
 

  

Sending Automated Job Email Notifications in SQL Server with SMTP

What is required for sending mail through SQL Server:

1) install IIS

2) install SMTP Server

3) “OLE Automation” feature in Surface Area Configuration features must be turned on

When you have automated backup jobs running on your database server, sometimes you forget that they are even running. Then you forget to check to see if they are running successfully, and don’t realize until your database crashes and you can’t restore it since you don’t have a current backup.

That’s where email notifications come in, so you can see the job status every morning when you are sipping your coffee and pretending you are working.

SQL Server provides a built-in method of sending emails, but unfortunately it requires you to have Outlook and a profile installed on the server, which isn’t necessarily the ideal way to send an email. Thankfully there is another method, that involves installing a stored procedure on your server that will allow you to send email via SMTP.

 

SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

CREATE PROCEDURE [dbo].[sp_SQLNotify]
   @From varchar(100) ,
   @To varchar(100) ,
   @Subject varchar(100)=” “,
   @Body varchar(4000) = “Motley Fool Inc.”
/*********************************************************************

This stored procedure takes the above parameters and sends an e-mail.
All of the mail configurations are hard-coded in the stored procedure.
Comments are added to the stored procedure where necessary.
Reference to the CDOSYS objects are at the following MSDN Web site:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cdosys/html/_cdosys_messaging.asp

***********************************************************************/
   AS
   Declare @iMsg int
   Declare @hr int
   Declare @source varchar(255)
   Declare @description varchar(500)
   Declare @output varchar(1000)

–************* Create the CDO.Message Object ************************
   EXEC @hr = sp_OACreate ‘CDO.Message’, @iMsg OUT

–***************Configuring the Message Object ******************
– This is to configure a remote SMTP server.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cdosys/html/_cdosys_schema_configuration_sendusing.asp
   EXEC @hr = sp_OASetProperty @iMsg, ‘Configuration.fields(”http://schemas.microsoft.com/cdo/configuration/sendusing”).Value’,'2′
– This is to configure the Server Name or IP address.
– Replace MailServerName by the name or IP of your SMTP Server.
   EXEC @hr = sp_OASetProperty @iMsg, ‘Configuration.fields(”
http://schemas.microsoft.com/cdo/configuration/smtpserver”).Value’, ‘10.1.1.10′

– Save the configurations to the message object.
   EXEC @hr = sp_OAMethod @iMsg, ‘Configuration.Fields.Update’, null

– Set the e-mail parameters.
   EXEC @hr = sp_OASetProperty @iMsg, ‘To’, @To
   EXEC @hr = sp_OASetProperty @iMsg, ‘From’, @From
   EXEC @hr = sp_OASetProperty @iMsg, ‘Subject’, @Subject

– If you are using HTML e-mail, use ‘HTMLBody’ instead of ‘TextBody’.
   EXEC @hr = sp_OASetProperty @iMsg, ‘TextBody’, @Body
   EXEC @hr = sp_OAMethod @iMsg, ‘Send’, NULL

– Sample error handling.
   IF @hr <>0
     select @hr
     BEGIN
       EXEC @hr = sp_OAGetErrorInfo NULL, @source OUT, @description OUT
       IF @hr = 0
         BEGIN
           SELECT @output = ‘  Source: ‘ + @source
           PRINT  @output
           SELECT @output = ‘  Description: ‘ + @description
           PRINT  @output
         END
       ELSE
         BEGIN
           PRINT ‘  sp_OAGetErrorInfo failed.’
           RETURN
         END
     END

– Do some error handling after each step if you need to.
– Clean up the objects created.
   EXEC @hr = sp_OADestroy @iMsg

   PRINT ‘Mail Sent!’

GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

You will want to edit one line in the stored procedure to put the IP address of your SMTP server:
EXEC @hr = sp_OASetProperty @iMsg, ‘Configuration.fields(”http://schemas.microsoft.com/cdo/configuration/smtpserver”).Value’, ‘10.1.1.10′
Install the stored procedure into the master database, so it can be easily used from wherever needed.
Open up the SQL Server Agent \ Jobs list, and select the properties for the job you are trying to create a notification for:

jobslist1

Click on the Steps tab, and you should see a screen that looks like this:

 

jobsteps1

 

newstep1

 

Click the New button to create a new job step. We will use this step to send the email notification on success.
Step Name: Email Notification Success
Enter this SQL into the Command window as seen below. You will want to customize the email addresses and message subject to match your environment:
 
exec master.dbo.sp_SQLNotify ’server@localserver.com’,'admin@localserver.com’,'Backup Job Success’,'The Backup Job completed successfully’
 
Click OK and then click the New button again to create another step. This will be the failure notification step.
Step Name: Email Notification Failure
SQL:
exec master.dbo.sp_SQLNotify ’server@localserver.com’,'admin@localserver.com’,'Backup Job Failure,’The Backup Job failed’
Now the idea is to make the items follow a specific workflow. First click Edit on step 1, and set the properties as shown here:


step1flow1

What we are saying is that on success, go to the success step, and on failure, go to the failure step. Pretty simple stuff.

Now edit the second step, the one labled “Email Notification Success”, and set the properties as seen here:
step2flow1
 

We are saying that if the notification job is successful, then just quit the job without running step 3. If we don’t specify this, then we will end up getting two emails, one with success and one with failure.

Now edit the third step, the one labled “Email notification failure”, and set the properties as seen here:
 
step3flow1

Now your job steps should look like this:

finalsteps1 

 

Attach Date/Time Stamp To A File - Can Be Used For Automated Backups

Here is an interesting one. I found a way to take the %date% environment variable, and turn it into a valid string for a filename - without any extra programs or scripts.

For the longest time I used a little utility I created to do this. The problem with that is the utility needs to be around if you want to send the batch file to someone.

What I didn’t know that was that you can use this character combination ‘:~’ to pull a substring out of an environment variable. That is when I realized you could use this to pull out parts of the current date (or time).

Here is how it works. Lets take the %date% variable and print it out

echo %date%

It comes back …At least today ;) .. with

Thu 02/15/2007

Not sure if the length of the day changes. It may be always the same. To be safe we can pull the year, month and day starting from the right.

The :~ substring command works like this:

:~[START POS],[LENGTH]

If [START_POS] is positive or zero the substring will start from the left. If the number [START_POS] is negative it will start from the right. And [LENGTH] is the number of characters in the opposite direction of the starting point.

I know this might be confusing at first, but you will see what I am talking about.

If we wanted to get the current year we could start 4 from the end, and 4 in length. Like this:

echo %date:~-4,4%

For the month we start 7 from the right (Length of Year + Length of Month + 1 Slash)

echo %date:~-7,2%

For the day we start 10 from the right (Length of Year + Length of Month + Length Of Day + 2 Slashes)

echo %date:~-10,2%

Bringing it all together. Lets say I zipped up a folder every night for archival purposes, and wanted a different filename for each day (Not sure if this pkzip syntax is correct, but that is not important for our discussion here)

pkzip c:\ImportantFolder\*.* c:\TempZip.zip
ren C:\TempZip.Zip c:\TempZip_%date:~-4,4%%date:~-7,2%%date:~-10,2%.zip

Which renames our C:\TempZip.Zip to C:\TempZip_20070215.zip

Perfect.  I get a date stamped file, and no special vbscript, or command line program is needed.

The same method could be used for the current time

I am still amazed this little trick works.

Running batch file using T-SQL

Example of running batch file using T-SQL
i) Running standalone batch file (without passed parameters)
EXEC master..xp_CMDShell ‘c:restore_from_backup.bat’

ii) Running parameterized batch file

DECLARE @PassedVariable VARCHAR(100)
DECLARE @CMDSQL VARCHAR(1000)
SET @PassedVariable = ‘SomeVariable’
SET @CMDSQL = ‘c:restore_from_backup.bat’ + @PassedVariable
EXEC master..xp_CMDShell @CMDSQL