Login or Sign Up to become a member!
LessThanDot Sit Logo

LessThanDot

Data Management

Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.

LTD Social Sitings

Lessthandot twitter Lessthandot Linkedin Lessthandot friendfeed Lessthandot facebook Lessthandot rss

Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.

Your profile

    Search

    XML Feeds

    Google Ads

    « SQL Server 2008 R2 August Community Technology Preview (CTP) AnnouncedSQL Server sprawl, heard it twice in one day »
    comments

    As a DBA or DB Developer, it probably seems like a fundamental task to import an excel sheet in order to match some data up to the contents, create a report, import into other tables and such. I was asked yesterday how to do this though by a developer and realize it may not be all that straight forward on the ways to do it. I thought I’d show a few ways just so it’s up there.

    I like to have a scenario with these things so let’s say you just received an email with an Excel attachment and they need additional data on sheet 1 that the application they are using just won’t give them. So there are a few quick ways I would do this.

    1) Import the sheet into your work database (DBA in my case), do your work and get out
    2) A direct insert into the Excel sheet using OPENROWSET, OPENDATASOURCE (this option gets messy on the inserts)

    Option 1 is usually how I do it since I can write and validate the query it seems the quickest.

    First you need the Excel sheet in the DBA database. Either the import wizard or OPENROWSET again. I use the import wizard for these. It’s perfect for it and quick.

    To do that, right click the database, scroll to tasks and select Import Data. Select “Microsoft Excel” in the Data source listing. Note: if you receive an Excel file version 2007+, you need to use Office 12 OLEDB providers. You can read about that here and how to set the properties or if you allow OPENROWSET then you can simply throw this in there and execute it.

    1. SELECT *
    2. INTO EXCELDATA
    3. FROM
    4. OPENROWSET('Microsoft.ACE.OLEDB.12.0','Excel 12.0;Database=C:\ExcelFile.xlsx', 'SELECT * FROM [Sheet1$]')

    Nice thing about this is, it will work with pre-2007 versions so you don’t’ have to alter the statement to import other Excel files older as long as you have Office 12 objects installed on the machine importing. If you don’t you can do the older statement of

    1. SELECT *
    2. INTO EXCELDATA
    3. FROM OPENROWSET('MSDASQL',
    4.     'Driver={Microsoft Excel Driver (*.xls)};DBQ=C:\ExcelFile.xls',
    5.     'SELECT * FROM [sheet1$]')

    Back to the import wizard; now that you have the data source, click browse to locate your Excel file.

    Hit Next and you should be able to hit next again sense you are working in the database to import directly. If they are not, fill in the blanks as needed for your DB and instance. Leave, “copy data from one or more tables or views” select and hit next in the next screen. In the, “select source tables and views screen, tick the first sheet (or the sheet that has the relevant data) and either leave the name for the destination the same or change it to what you want. I like to change it to a meaningful name and one that is easier to type for my query.

    Hit next and then hit finish. That should be it.
    In the Excel sheet I populated Sheet1 with this from AdventureWorks.

    1. Select TOP 10000 OrderDate,SalesOrderNumber from Sales.SalesOrderHeader

    The request at hand is to match up these orders with salesman. Granted this is an odd task and you’re going to get much more complexity in real life, but for the example I like to make it a bit easier so we know you’ll get it working.
    So running this

    1. Select * From BOSSIMPORT

    We can see our data is in there and waiting for us to complete the task. In AdventureWorks the schema for sales is, Sales. This referes the objects of sales and all pertinent data. Just looking at the design of the schema you can see immediately that Sales.SalesPerson is what you’re going to need to fulfill the additional column of sales person to the order numbers. We can then build a query like this

    1. Select
    2.     import.*
    3.     ,salesper.FullName
    4.     ,salesper.SalesPersonID
    5. From
    6. BOSSIMPORT import  
    7. Left Join (
    8.             select
    9.                 names.FirstName + ' ' + names.LastName FullName
    10.                 ,hdr.SalesPersonID
    11.                 ,hdr.SalesOrderNumber
    12.             from
    13.             AdventureWorks.HumanResources.Employee emp
    14.             inner join AdventureWorks.Sales.SalesPerson sls on emp.EmployeeID = sls.SalesPersonID
    15.             inner join AdventureWorks.Person.Contact names on  sls.SalesPersonID = names.ContactID
    16.             Inner Join AdventureWorks.Sales.SalesOrderHeader hdr on sls.SalesPersonID = hdr.SalesPersonID
    17.             ) salesper on import.SalesOrderNumber COLLATE DATABASE_DEFAULT
    18.                                 = salesper.SalesOrderNumber COLLATE DATABASE_DEFAULT

    With that then you just do an alter to add the columns on the import table and then an update for the data

    1. Update import
    2. Set import.FullName = salesper.FullName
    3.     ,import.SalesPersonID = salesper.SalesPersonID
    4. From
    5. BOSSIMPORT import  
    6. Left Join (
    7.             select
    8.                 names.FirstName + ' ' + names.LastName FullName
    9.                 ,hdr.SalesPersonID
    10.                 ,hdr.SalesOrderNumber
    11.             from
    12.             AdventureWorks.HumanResources.Employee emp
    13.             inner join AdventureWorks.Sales.SalesPerson sls on emp.EmployeeID = sls.SalesPersonID
    14.             inner join AdventureWorks.Person.Contact names on  sls.SalesPersonID = names.ContactID
    15.             Inner Join AdventureWorks.Sales.SalesOrderHeader hdr on sls.SalesPersonID = hdr.SalesPersonID
    16.             ) salesper on import.SalesOrderNumber COLLATE DATABASE_DEFAULT
    17.                                 = salesper.SalesOrderNumber COLLATE DATABASE_DEFAULT

    Now selecting all from the BOSSIMPORT will give you everything. I just copy paste the result set into the Excel file they sent and forward it on back.

    The OPENROWSET then can be constructed off the statements above as just

    1. SELECT *
    2. INTO BOSSIMPORT
    3. FROM OPENROWSET('MSDASQL',
    4.     'Driver={Microsoft Excel Driver (*.xls)};DBQ=C:\ExcelFile.xls',
    5.     'SELECT * FROM [sheet1$]')
    6. Go
    7.  
    8. ALTER TABLE BOSSIMPORT
    9. ADD FullName varchar(101)
    10.     ,SalesPersonID INT
    11. Go
    12.  
    13. Update import
    14. Set import.FullName = salesper.FullName
    15.     ,import.SalesPersonID = salesper.SalesPersonID
    16. From
    17. BOSSIMPORT import  
    18. Left Join (
    19.             select
    20.                 names.FirstName + ' ' + names.LastName FullName
    21.                 ,hdr.SalesPersonID
    22.                 ,hdr.SalesOrderNumber
    23.             from
    24.             AdventureWorks.HumanResources.Employee emp
    25.             inner join AdventureWorks.Sales.SalesPerson sls on emp.EmployeeID = sls.SalesPersonID
    26.             inner join AdventureWorks.Person.Contact names on  sls.SalesPersonID = names.ContactID
    27.             Inner Join AdventureWorks.Sales.SalesOrderHeader hdr on sls.SalesPersonID = hdr.SalesPersonID
    28.             ) salesper on import.SalesOrderNumber COLLATE DATABASE_DEFAULT
    29.                                 = salesper.SalesOrderNumber COLLATE DATABASE_DEFAULT
    30. Go
    31.  
    32. select
    33.     names.FirstName + ' ' + names.LastName FullName
    34.     ,hdr.SalesPersonID
    35.     ,hdr.SalesOrderNumber
    36. from
    37. AdventureWorks.HumanResources.Employee emp
    38. inner join AdventureWorks.Sales.SalesPerson sls on emp.EmployeeID = sls.SalesPersonID
    39. inner join AdventureWorks.Person.Contact names on  sls.SalesPersonID = names.ContactID
    40. Inner Join AdventureWorks.Sales.SalesOrderHeader hdr on sls.SalesPersonID = hdr.SalesPersonID
    41. Go

    So you can get it all done in one execute.

    About the Author

    Ted Krueger is a SQL Server MVP and has been working in development and database administration for 13+ years. Specialties range from High Availability and Disaster / Recovery setup and testing methods down to custom assembly development for SQL Server Reporting Services. Ted blogs and is also one of the founders of LessThanDot.com technology community. Some of the articles focused on are Backup / Recovery, Security, SSIS and working on SQL Server and using all of the SQL Server features available to create stable and scalable database services. @onpnt
    Social SitingsTwitterLinkedInLTD RSS Feed
    2551 views
    Instapaper

    3 comments

    Comment from: SQLDenis [Member] Email
    *****
    SQLDenis Nice post, but I still hate excel..especially when you mix numbers and letters in the same column or if you have a null value in the column...that will just hose up the import and skip those rows silently

    I prefer flat files/csv files
    08/05/09 @ 12:58
    Comment from: Ted Krueger (onpnt) [Member]
    Ted Krueger (onpnt) Oh I'm with you. I think the reason I get the data into SQL Server as fast as I do it so there is as little Excel process tasks running in my task manager as possible :-)
    08/05/09 @ 13:01
    Comment from: sqlsister [Member] Email
    sqlsister If at all possible we insist on a text file instead, but some clients can't provide one.

    So when forced to, we always convert the Excel file to a text file first and then import. It avoids most of the silly issues that Excel to SQL Server conversions have. The thing I hate most about Excel imports though is that they never have the same columns from run to run as the clients are using the file for some other purpose and have no problem with changing it and not telling us.

    Unfortunately, we still have some clients we have to export to Excel for, they won't even take csv files. Grr arrrrgh.
    08/05/09 @ 14:36

    Leave a comment


    Your email address will not be revealed on this site.

    Your URL will be displayed.
    (Line breaks become <br />)
    (Name, email & website)
    (Allow users to contact you through a message form (your email will not be revealed.)