Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 Import/Export (DTS) and Replication (2000)
 OPENDATASOURCE fun

Author  Topic 

Wanderer
Master Smack Fu Yak Hacker

1168 Posts

Posted - 2004-06-17 : 08:11:20
Hi all,

I've got a request to insert data from 4 different spreadsheets, as part of an automated process. Currently, I'm trying to look at using OPENDATASOURCE, and have managed to "open" the spreadsheets. I have some specific issues I am hoping someone can help me with

1> If the sheet is named with numbers first, or if it has spaces in the name, it seems to fail.

2> I can get it working locally, but when I try and run against a mapped network drive that I have read and write access to. it fails with the following message:
quote:
Server: Msg 7399, Level 16, State 1, Line 1
OLE DB provider 'Microsoft.Jet.OLEDB.4.0' reported an error. The provider did not give any information about the error.
OLE DB error trace [OLE/DB Provider 'Microsoft.Jet.OLEDB.4.0' IDBInitialize::Initialize returned 0x80004005: The provider did not give any information about the error.].

... I think I can get around that - seems to require SQL to be running with a domain user



*##* *##* *##* *##*

Chaos, Disorder and Panic ... my work is done here!

ditch
Master Smack Fu Yak Hacker

1466 Posts

Posted - 2004-06-17 : 08:25:38
Hi Wanderer,

silly question but,
why not change the worksheets name?

If you're too lazy to do that - use VBA

--**********************************************
Private Sub Workbook_Open()
Dim Inx As Integer

For Inx = 1 To ActiveWorkbook.Sheets.Count
Sheets(Inx).Name = "A" & Replace(Sheets(Inx).Name, " ", "")
Next Inx

End Sub
--*******************************************************


Duane.
Go to Top of Page

Wanderer
Master Smack Fu Yak Hacker

1168 Posts

Posted - 2004-06-17 : 08:40:59
Thanks Duane :-)

The customer intelligence guys have acceeded to my request to change the sheet names - I was trying to find out with there was a better way/ some way to handle the sheets. Another problem was that the names of the sheets were going to be different every day (date named), but it seems like they will accept changing that.

Has anyone done this with varying filenames incoming? Basically, we will want to pick up the specific days files. Currently, what I've got is:

set nocount on
go

create table #test_file
(filee int,
filed int,
pd int)
go

insert into #test_file
exec xp_fileexist 'R:\Contact centre ICM reports\t16062004peragt04.xls'

if not exists (select 1 from #test_file where filee = 1)
begin
print 'no file'
end
else
begin
print 'file found'
SELECT * FROM OpenDataSource( 'Microsoft.Jet.OLEDB.4.0',
'Data Source="R:\Contact centre ICM reports\t16062004peragt04.xls";Extended properties=Excel 8.0')...[Agent_call_stats_14_June_2004$]
end


I see that if the file doesn't exist then the script "bombs" - I had hoped to get around that, but to no avail, as yet. I am thinking that I will have to dynamically create the file name if it is going to be different each day - has anyone done anything like this, or can anyone offer to smack me upside the head, and show me the simple way?

Ta

*##* *##* *##* *##*

Chaos, Disorder and Panic ... my work is done here!
Go to Top of Page

ditch
Master Smack Fu Yak Hacker

1466 Posts

Posted - 2004-06-17 : 08:45:44
Perhaps an activex task that uses the filesystemobject
and runs prior to the load,
that first checks file existence
then renames the file to a known file name which can be used in the opendatasource?




Duane.
Go to Top of Page

Wanderer
Master Smack Fu Yak Hacker

1168 Posts

Posted - 2004-06-17 : 08:55:02
Hmm - sounds interesting ... I admit I haven't used this ... have you got a pointer to an article or example of changing file names? The BOL example seems pretty far from checking fileexistance and renaming.

*##* *##* *##* *##*

Chaos, Disorder and Panic ... my work is done here!
Go to Top of Page

ditch
Master Smack Fu Yak Hacker

1466 Posts

Posted - 2004-06-17 : 09:04:39
We use this stuff often.

Here is the first one I found.
This one just checks file age:

For renaming methods etc you can look on msdn or google filesystemobject:

'**********************************************************************
' Visual Basic ActiveX Script
'************************************************************************

Function Main()

'File in the LoadFile directory to check for age:
FilePath = "flash_sales.txt"

MaxDiff = 0

Set fso = CreateObject("Scripting.FileSystemObject")
Set Flash = fso.GetFile(FilePath)
FileDatetime = Flash.DateLastModified

TimeDiff = DateDiff("d", Flash.DateLastModified, Now)

'Clear memory space the objects occupy:
Set fso = Nothing
Set Flash = Nothing

If TimeDiff > MaxDiff Then
DTSGlobalVariables("ErrorMessage").Value = "LOAD STOPPED! FlashSales file too old: It arrived at " & FileDatetime
Main = DTSTaskExecResult_Failure
Else
Main = DTSTaskExecResult_Success
End If

End Function


EDIT:
This will have to run in a DTS Package - in case u r wondering Wanderer
Duane.
Go to Top of Page

Wanderer
Master Smack Fu Yak Hacker

1168 Posts

Posted - 2004-06-17 : 09:39:00
Got that, Duane.

I will carry on playing with this, but they are pushing to have this done in T-SQL, because they want to get is callable from a reporting from end. Still, I can abuse xp_cmdshell and dtsrun, perhaps, although I would rather not. Off I go ...

*##* *##* *##* *##*

Chaos, Disorder and Panic ... my work is done here!
Go to Top of Page

The Enigma
Posting Yak Master

179 Posts

Posted - 2004-06-17 : 15:22:11


CREATE Procedure usp_UploadExcelFile
@Folder_Name varchar(256)
,@File_Name varchar(256)
,@SessionId int
,@Worksheet varchar(20)
as
begin
if exists (select * from sysobjects where name = 'Temp_Upload_table' and type = 'U' )
begin
drop table Temp_Upload_table
end
DECLARE
@Query varchar(800)
,@Error_Msg varchar(200)
select @query ='create procedure usp_excel_upload as select
IDENTITY(INT,1,1) AS RowId
,*
into
Temp_Upload_Table
from OpenDataSource( '+''''+'Microsoft.Jet.OLEDB.4.0'+''''+','+''''+'Data Source="'
+@Folder_Name
+@File_Name
+'";User ID=;Password=;Extended properties="Excel 8.0;IMEX=1"'+'''' + ')...'+@Worksheet+'$'
exec (@query)
exec usp_excel_upload

end


This is something I have been using. This uploads the file into a physical temp table which you can test for errors in code before transferring into table. If you have a standard format in which worksheets will be named ... u can pass the same to this proc ....
















GO
Go to Top of Page

kselvia
Aged Yak Warrior

526 Posts

Posted - 2004-06-18 : 01:05:34
FYI, you can select from a sheet name that starts with a number. Put '[]' around it.

SELECT * FROM OPENDATASOURCE('Microsoft.Jet.OLEDB.4.0', 'Data Source=c:\temp\book1;Extended Properties=Excel 8.0')...['1$']

works for me. The worksheet is named 1

Also, if sheet names change, you can create a linked server to the worksheet and run sp_tables_ex to find out what sheets exist

EXEC sp_addlinkedserver 'TestExcel', 'Excel', 'Microsoft.Jet.OLEDB.4.0', 'c:\temp\book1.xls', '', 'Excel 8.0', ''

EXECUTE SP_TABLES_EX 'TestExcel'

Returns

TABLE_CAT TABLE_SCHEM TABLE_NAME TABLE_TYPE REMARKS
----------------------------- ------------------------------ ---------------- -------------- -------------
NULL NULL '1$' TABLE NULL

You can create a temp table and insert the results from SP_TABLES_EX into it to find worksheet names.

Also, the error you are getting is the same error you would get if the path was invalid, suggesting the account SQL Server is running as does not have R: mapped (which is probably true) If SQL runs as a domain account that does have rights to the file, use a UNC \\server\share\....) instead.
Go to Top of Page

Wanderer
Master Smack Fu Yak Hacker

1168 Posts

Posted - 2004-06-18 : 01:50:17
Enigma,

Thanks for the response. Working on my own, I am fairly close to what you have, at the moment :-)

I see you have an @errormsg field, but I didn't see you use it?

I hadn't gotten as far as allowing @foldername, but that is a nice improvement

Your procedure check to see if the table exists, then drops it.
Then you build up a string that will create a stored procedure to runs the opendatasource.
Then you exec the producedure created.

The second time you try this, it will fall over because the stored procedure usp_excel_upload already exists, surely?

Also, do you need to create a secondary stored procedure? Surely you could just build the string in the stored proceudre, and exec it there, then you wouldn't have to cleanup the stored procedure creation.

Look forward to your response

*##* *##* *##* *##*

Chaos, Disorder and Panic ... my work is done here!
Go to Top of Page

Wanderer
Master Smack Fu Yak Hacker

1168 Posts

Posted - 2004-06-18 : 02:00:06
Kselvia,

Thanks for the tip on the numbered worksheets. With a little playing, I got that working.

I sorted out the access to R:\ ... I was testing on my local machine (used only for testing), where I have SQL running off of a local account becuase of the irritation on having SQL bomb when you domain account password fails :-)

I also have seen that I will have to have MSDTS running to get this working.

I thinking I am nearing on a solution - will post it when I get there ... although more comment widely sought after to imrpove !

CiaO

*##* *##* *##* *##*

Chaos, Disorder and Panic ... my work is done here!
Go to Top of Page

The Enigma
Posting Yak Master

179 Posts

Posted - 2004-06-18 : 03:41:17
Wanderer .. here's the complete stored procedure .. with some important bits removed i.e.

ALTER Procedure usp_UploadExcelFile
@Folder_Name varchar(256)
,@File_Name varchar(256)
,@SessionId int
,@Worksheet varchar(20)
as
begin
if exists (select * from sysobjects where name = 'Temp_Upload_table' and type = 'U' )
begin
drop table Temp_Upload_table
end
DECLARE
@Query varchar(800)
,@Error_Msg varchar(200)
select @query ='create procedure usp_excel_upload as select
IDENTITY(INT,1,1) AS RowId
,*
into
Temp_Upload_Table
from OpenDataSource( '+''''+'Microsoft.Jet.OLEDB.4.0'+''''+','+''''+'Data Source="'
+@Folder_Name
+@File_Name
+'";User ID=;Password=;Extended properties="Excel 8.0;IMEX=1"'+'''' + ')...'+@Worksheet+'$'
exec (@query)
exec usp_excel_upload

if (@@error <> 0)
Begin

select
@Error_Msg = 'An unhandled error occured during upload of file "'
+@File_Name
+'". Kindly validate the file and try again.'
insert into
Error_log
select
@SessionId
,'2'
,@Error_Msg
,@File_Name
,getdate()
End
Drop Procedure usp_excel_upload

end


The error log table is as below

CREATE TABLE [Error_Log] (
[Session_id] [char] (10) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[Error_Code] [int] NULL ,
[Error_Desc] [varchar] (396) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[File_Name] [varchar] (256) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[Date] [datetime] NULL
) ON [PRIMARY]
GO



Go to Top of Page

Wanderer
Master Smack Fu Yak Hacker

1168 Posts

Posted - 2004-06-18 : 06:13:06
Hi Enigma,

thanks for the followup.

Looks like I spoke to soon about right's .. we have mutiple domains, and some of the dev SQL boxes don't run on domain accounts, so this is getting a little ugly.

I see you have IMEX=1 ... is that a code page type thing? I can't find any reference to it anywhere.

Also, I couldn't get the opendatasource working until I removed the "User ID=;Password=" ... which I assumed then allowed it to use integrated security, based on the account running SQL.

I'm guessing that you've (quite sensibly) removed the userid and password you had there, but can you just confirm for me - did you have a domain user there, with rights to the location where the file resides ?

Cheers

*##* *##* *##* *##*

Chaos, Disorder and Panic ... my work is done here!
Go to Top of Page

Wanderer
Master Smack Fu Yak Hacker

1168 Posts

Posted - 2004-06-18 : 06:29:01
hmm - with all the problem I'm having, I looked to use yours - I am likely calling it incorrectly, since I get
quote:

Server: Msg 170, Level 15, State 1, Procedure usp_excel_upload, Line 6
Line 6: Incorrect syntax near '.17062004'.
Server: Msg 2812, Level 16, State 62, Line 25
Could not find stored procedure 'usp_excel_upload'.



when I use the following:

exec usp_UploadExcelFile '\\reports\reports\test_e\','17062004pergat04.xls',1,'17062004pergat04'


can't see any obvious problems, given the length of char's, etc, that should lead to it refering to only '.17062004' -- can you?

cheers

*##* *##* *##* *##*

Chaos, Disorder and Panic ... my work is done here!
Go to Top of Page

Wanderer
Master Smack Fu Yak Hacker

1168 Posts

Posted - 2004-06-18 : 08:23:58
The frustration is mounting...

Can anyone see what I am doing wrong here - it must be something obvious, but I've been trying and trying for the last hour or so, with no joy...

If you look at the string I am build for @dir, you will see it is exactly the same as the literal used in the first exec xp_cmdshell, and yet the literal works, and the @dir does not. More frustrating is that it was working a while ago!!


set nocount on
go
declare @filename varchar(250)
declare @sheetname varchar(100)
--declare @dateformat varchar(8)
declare @dir varchar(1250)
--select @dateformat = cast((datepart(day,getdate()) -1) as char(2))
-- +substring(cast((datepart(month,getdate()) +100) as char(3)),2,2)
-- +cast(datepart(year,getdate()) as char(4))
set @filename = '\\reports\reports\test_e\a'+cast((datepart(day,getdate()) -1) as char(2))
+substring(cast((datepart(month,getdate()) +100) as char(3)),2,2)
+cast(datepart(year,getdate()) as char(4))+'peragt04.xls'
--set @filename = 'c:\2020 data\test16062004peragt04.xls'
--set @sheetname = 'sheet1$'
--select @filename
--select @sheetname
set @dir= 'dir \\reports\reports\test_e\a'+cast((datepart(day,getdate()) -1) as char(2))
+substring(cast((datepart(month,getdate()) +100) as char(3)),2,2)
+cast(datepart(year,getdate()) as char(4))+'peragt04.xls'
select @dir
select 'dir \\reports\reports\test_e\a17062004pergat04.xls'
exec master..xp_cmdshell 'dir \\reports\reports\test_e\a17062004pergat04.xls'
--this works
exec master..xp_cmdshell @dir
--this does not

the return the following:

dir \\reports\reports\test_e\a17062004peragt04.xls

--------------------------------------------------
dir \\reports\reports\test_e\a17062004pergat04.xls

output Volume in drive \\reports\reports has no label.
Volume Serial Number is 0E2F-CEB4
NULL
Directory of \\reports\reports\test_e
NULL
2004/06/18 12:44p 23,552 a17062004pergat04.xls
1 File(s) 23,552 bytes
0 Dir(s) 6,030,200,832 bytes free
NULL

output Volume in drive \\reports\reports has no label.
Volume Serial Number is 0E2F-CEB4
NULL
Directory of \\reports\reports\test_e
NULL
File Not Found
NULL



Notice that the dir command fired by the @dir version seems to have stopped at the end of the \test_e , even though the @dir string is complete.

What am I missing?

*##* *##* *##* *##*

Chaos, Disorder and Panic ... my work is done here!
Go to Top of Page

ditch
Master Smack Fu Yak Hacker

1466 Posts

Posted - 2004-06-18 : 09:45:55
Hi Wanderer,
It is not working because of a typo.
in 1 place you have called the file peragt.xls and in the other place you have called it pergat.xls



Duane.
Go to Top of Page

Wanderer
Master Smack Fu Yak Hacker

1168 Posts

Posted - 2004-06-18 : 10:56:44
Duane, you have just saved my friday night :-)

It would be funny if it wasn't so embarrassing - I've been copying and pasting the wrong "gat" version into the spreadsheet names, worksheet names, and bleeding everywhere *sighs* I even told myself to start from scratch, and write everything again ... guess which bit was to only bit I copied :-)

Thanks again...

*##* *##* *##* *##*

Chaos, Disorder and Panic ... my work is done here!
Go to Top of Page

ditch
Master Smack Fu Yak Hacker

1466 Posts

Posted - 2004-06-20 : 09:24:05
Thats no problem buddy.

I've found many times that an extra pair of eyes are always quite helpfull. :)



Duane.
Go to Top of Page

Wanderer
Master Smack Fu Yak Hacker

1168 Posts

Posted - 2004-06-23 : 10:15:30
Newest version - this pretty much works, but could be "nicened"...

this is reasonably customized around my requirements. This are several changes that could be made, I am sure - would love some feedback..


if exists (select 1 from sysobjects where name = 'usp_Import_ExcelFile_TempTable' and xtype = 'p')
drop procedure usp_Import_ExcelFile_TempTable

set nocount on

go

create procedure usp_Import_ExcelFile_TempTable
@filename varchar(250),
@sheetname varchar(100) = 'Sheet1$',
@succeed int OUTPUT
as
begin
set @succeed = -1 --failure
set nocount on
if exists (select 1 from sysobjects where name = 'excel_data_inserted' and xtype = 'u')
drop table dbo.excel_data_inserted
declare @sql varchar(500)
declare @filexists int

set @sql = 'SELECT * INTO dbo.excel_data_inserted FROM OpenDataSource( ''Microsoft.Jet.OLEDB.4.0'',
''Data Source="'+@filename+'";Extended properties=Excel 8.0'')...['+@sheetname+']'
exec master..xp_fileexist @filename, @filexists OUT
if (@filexists <> 1)
print 'No file'
else
begin
set @succeed = 0 --success
-- print @succeed
-- print @sql
exec (@sql)
end
end

set nocount on
go
declare @filename varchar(250)
declare @fullname varchar(250)
declare @dateformat char(8)
declare @dir varchar(250)
declare @suc int

select @dateformat = convert(char(2),(datepart(day,getdate()) -2))
+substring(convert(char(3),(datepart(month,getdate()) +100) ),2,2)
+convert(char(4),datepart(year,getdate()))
--CHANGE the SECTION before @dateformat to the relevant spreadsheet, eg PERAGT04 or PERAGT05 or PERAGT06
select @fullname = 'peragt06'+@dateformat
print @fullname
select @filename = '\\reports\reports\Contact centre ICM reports\'+@fullname+'.xls'
select @filename
select @fullname = ''+@fullname+'$'
select @fullname


--change the SHEET1 to the specific sheet name for the
--per files. eg PERAGT0421062004.
--I am working on a dynamic version of that - shouldn't be hard
exec usp_Import_ExcelFile_TempTable @filename,@fullname,@suc output
--select @suc
if @suc = 0
select * from dbo.excel_data_inserted



*##* *##* *##* *##*

Chaos, Disorder and Panic ... my work is done here!
Go to Top of Page

tengo1
Starting Member

2 Posts

Posted - 2006-11-01 : 11:29:44
Being that the original thread is over 2 years old, I don't know if all of the players are still in touch with this website, but I'm going to give it a try.

I've been searching the net with little luck except for this thread. I'm trying to import an excel spreadsheet using OPENDATASOURCE in a SQL Server Stored Procedure. The example from "The Enigma" on 6/18/2004 03:41:17 works great except the vender that is providing me with the spreadsheet is putting a space in the Worksheet name. I found that if I hard code the name and use [''] around the worksheet name it works good, but if I pass it in as a variable it doesn't. Then I found "Wanderer's" example which looks as though it should solve the issue, because it uses the [''] but when I plugged in this change I get an error.

Here is my stripped down sample code used for development purposes only. You can set up any excel spreadsheet using a worksheet name with the space.

What am I missing?

declare @spreadsheetfile nvarchar(4000), @p_Worksheet nvarchar(4000)
select @spreadsheetfile = 'C:\test\XXX.xls',
@p_Worksheet = 'TRANS_REPORT'

declare @sql varchar(500)

set @sql = 'SELECT * INTO dbo.excel_data_inserted FROM OpenDataSource( ''Microsoft.Jet.OLEDB.4.0'',
''Data Source="'+@spreadsheetfile+'";Extended properties=Excel 8.0'')...['+@p_Worksheet+']'
exec(@sql)
Go to Top of Page

rockmoose
SQL Natt Alfen

3279 Posts

Posted - 2006-11-01 : 14:22:10
Does anything in this thread apply to your problem?

http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=49926

rockmoose
Go to Top of Page
    Next Page

- Advertisement -