September 20, 2004 at 4:43 am
Hi Gurus.
My client drops for me many files like this on a shared drive M: daily
1_Test.csv
2_Test.csv
3_Test.csv
I would like you to advice on how to write a SQL code (that can include DTS if possible) that will take this files, merge them into one (since they have same columns) and send them to another client as one file. But it must only take the files of the same date and must not resend files i have send already. I need this to be an automated process since the files are dumped into M:drive midnite and I need this code so that I can schedule it as a job and run around 4h00am.
September 20, 2004 at 8:19 am
One of the simplest ways to merge files is by DOS copy. If it's desired to run by Transact SQL, it can be done through xp_cmdshell, though this type of task may also be done as a pure *.cmd file.
Combining files with the copy command
If you specify more than one source, separating entries with a plus sign (+), copy combines the files, creating a single file. If you use wildcards in source but specify a single filename in destination, copy combines all files matching the filename in source and creates a single file with the filename specified in destination.
You would also have to define your logic around the filenames, so you know if files have been sent already or not, what to do when something unexpected happens, errorhandling etc. It may very well be scheduled through the SQL Server Agent as well.
Good luck
/Kenneth
September 20, 2004 at 1:41 pm
Create a File called export.csv with the same columns.
Create a DTS Package with a datapump task that will pump the various files from your client into the export.csv file.
Use a union query for your source in the Transform. Example:
SELECT * FROM 1_Test.csv
UNION
SELECT * FROM 2_Test.csv
UNION
SELECT * FROM 3_Test.csv
USE the export.csv as your target.
In a separate step, FTP the export.csv to your other client.
Hope this helps,
PEte
September 21, 2004 at 12:39 am
Hi Pete
Thanks a lot, I also used xp_cmdshell.
Both of us are still using a manual process. I want something that will check if the new files arrived and schedule a job or something to merge this files.
September 21, 2004 at 2:25 am
Check out the following site. This has some nice code examples for doing loops in DTS packages for importing files.
Andrew
September 21, 2004 at 12:22 pm
I have a similar situation I resolved by
1) move the files from download directory to work directory. files are renamed with current datetime extension to avoid overwrite. the files I get have multiple "header" records so I have to split it into pieces as well.
2) do whatever needs to be done
3) archive the files (client is anal retentive - and sometimes I just have to CMB) using the same move process (from / to directories and rename boolean are global
For your needs it should be possible to modify the Active X task script below to only write one file (set the outFileName and simply append to it for all received files).
This is a quick cut 'n paste so there may be some mouse droppings for my logging and error checking routines. Tried to clean it up some and add a message here and there, but am trying to meet a Thurs deadline so it's a quickie.
The basic point is to open a file, read each record to end of line, write the record to the output file, loop for next file.
Need to set YOUR DATABASE string on connection to your database name.
I stumbled through this so can't say it is the best method but it does work. Feel free to contact me directly if you have questions (Frank.Perkins@concerto.com)
'*************************************************************************
' File Move and Split script.
' Used to move files from the downloads directory to
' the workarea directory.
' Server name and directory values are read from DTS global
' variables
' Needs a user id to sign on to db
'***********************************************************************
Option Explicit
Dim oFSO
Dim objCommand
Dim objConnection
Dim objRecordSet
Dim sServerName
Dim sTargetFolder
Dim sErrorFolder
Dim sRootFolder
Dim sSubFolders
Dim sFiles
Dim sExtensionString
Dim sTableName
Dim sSpecName
Dim sFormatId
Dim sSplit
Dim sSplitControl
Dim sErrorFile
Dim bRenameFile
Dim sDay
Dim sMonth
Dim sHour
Dim sMinute
Dim sSecond
Dim sDate
Dim sUserID
Dim sPassword
'*************************************************************************
' Default UserID and Password
'*************************************************************************
sUserId = ""
sPassword = ""
'*************************************************************************
'get today's date
sDate = Now()
' Get Rename parameter from global variable
bRenameFile = DTSGlobalVariables("RenameFile").Value
IF bRenameFile THEN
'Get date and time values to use in rename extension
sDay = Day(Date)
IF Len(sDay) = 1 THEN sDay = "0" & sDay
sMonth = Month(Date)
IF Len(sMonth) = 1 THEN sMonth = "0" & sMonth
sHour = Hour(Time)
IF Len(sHour) = 1 THEN sHour = "0" & sHour
sMinute = Minute(Time)
IF Len(sMinute) = 1 THEN sMinute = "0" & sMinute
sSecond = Second(Time)
IF Len(sSecond) = 1 THEN sSecond = "0" & sSecond
sExtensionString = sMonth & sDay & Year(Date) & sHour & sMinute & sSecond
End If
' current server name
sServerName = DTSGlobalVariables("ServerName").Value
' Create File System Object
Set oFSO = CreateObject("Scripting.FileSystemObject")
' Get the from (download) directory
Set sRootFolder = oFso.GetFolder(DTSGlobalVariables("FromDirectory").Value)
' Then get the list of SubFolders beneath this root folder
Set sSubFolders = sRootFolder.SubFolders
' Get the move to (work) directory
sTargetFolder = DTSGlobalVariables("ToDirectory").Value
If Right(sTargetFolder, 1) <> "\" Then
sTargetFolder = sTargetFolder & "\"
End If
' error directory
sErrorFolder = DTSGlobalVariables("ErrorDirectory").Value
If Right(sErrorFolder, 1) <> "\" Then
sErrorFolder = sErrorFolder & "\"
End If
'connect to the database
Set objConnection = CreateObject("ADODB.Connection")
objConnection.ConnectionString = "Provider=sqloledb;Data Source=" & sServerName & ";Initial Catalog=<YOUR DATABASE>;User Id=" & sUserID & ";Pwd=" & sPassword
objConnection.Open
'build a command object to use for SQL Inserts into task history
Set objCommand = CreateObject("ADODB.Command")
Set objCommand.ActiveConnection = objConnection
Set objRecordSet = CreateObject("ADODB.RecordSet")
'*********************************************************************************************************************************
' Main Function for this script
' Loop through downloads directory, pass each file found in root or any subdirectory of
' the root to a split function which will move the file to the workarea directory and split it if it
' has multiple header rows
'*********************************************************************************************************************************
Function Main()
' ***************************************************************************
' Log process start
' ***************************************************************************
' ******** my requirement included subfolders, yours will probably only have the root **********
' Check for files in root folder -- not supposed to be any at this level, but
' account for error
Set sFiles = sRootFolder.Files
For Each sFiles in sFiles
move sFiles.Path, sFiles.Name
oFSO.DeleteFile(filePath)
Next
' Loop through each subfolder
For Each sSubFolders in sSubFolders
' Get the list of files in this subfolder
Set sFiles = sSubFolders.Files
For Each sFiles in sFiles
move sFiles.Path, sFiles.Name
oFSO.DeleteFile(filePath)
Next
Next
' Clean Up
Set oFSO = Nothing
Main = DTSTaskExecResult_Success
End Function
Function move ( filePath, fileName)
Const ForReading = 1
Const ForWriting = 2
Const Appending = 8
Dim objTextStream
Dim strText
Dim bValidHeader
Dim outFileName
Dim tso
Dim iFileNumber
'***************************************************************************
' FileSystemObject.OpenTextFile(fname,mode,create,format)
'***************************************************************************
'Parameter Description
'fname Required. The name of the file to open
'mode Optional. How to open the file
'1=ForReading - Open a file for reading. You cannot write to this file.
'2=ForWriting - Open a file for writing.
'8=ForAppending - Open a file and write to the end of the file.
'create Optional. Sets whether a new file can be created if the filename does not exist.
'True indicates that a new file can be created, and False indicates that a new file will not be created. False is default
'format Optional. The format of the file
'0=TristateFalse - Open the file as ASCII. This is default.
'-1=TristateTrue - Open the file as Unicode.
'-2=TristateUseDefault - Open the file using the system default.
'***************************************************************************
' Open the passed in file for read
Set objTextStream = oFSO.OpenTextFile(filePath , ForReading)
If not objTextStream.AtEndOfStream Then
'read first line
strText = objTextStream.ReadLine
Else
objTextStream.Close
' ******* I track it as an error if file is empty
sErrorFile = sErrorFolder & fileName & "." & sExtensionString
End If
' ******** you will do this outside the function so it doesn't open another file ***************
'set up the output file name
outFileName = sTargetFolder & fileName & "." & sExtensionString
'and open it for write
Set tso = oFSO.OpenTextFile(outFileName, ForWriting, True)
' ******** you will do this outside the function so it doesn't open another file ***************
'write the first line to the output file
tso.WriteLine(strText)
'read the next line
strText = objTextStream.ReadLine
'if not at end, go into loop and write records until EOF
If NOT objTextStream.AtEndOfStream Then
Do While NOT objTextStream.AtEndOfStream
tso.WriteLine(strText)
strText = objTextStream.ReadLine
Loop
tso.WriteLine(strText)
tso.Close
Else
' this is an error in my case, only one record and it is the header, you may not need
objTextStream.Close
sErrorFile = sErrorFolder & fileName & "." & sExtensionString
oFSO.MoveFile filePath, sErrorFile
tso.Close
Exit Function
End If
objTextStream.Close
Set objTextStream = Nothing
Set tso = Nothing
oFSO.DeleteFile(filePath)
End Function
September 21, 2004 at 12:22 pm
I have a similar situation I resolved by
1) move the files from download directory to work directory. files are renamed with current datetime extension to avoid overwrite. the files I get have multiple "header" records so I have to split it into pieces as well.
2) do whatever needs to be done
3) archive the files (client is anal retentive - and sometimes I just have to CMB) using the same move process (from / to directories and rename boolean are global
For your needs it should be possible to modify the Active X task script below to only write one file (set the outFileName and simply append to it for all received files).
This is a quick cut 'n paste so there may be some mouse droppings for my logging and error checking routines. Tried to clean it up some and add a message here and there, but am trying to meet a Thurs deadline so it's a quickie.
The basic point is to open a file, read each record to end of line, write the record to the output file, loop for next file.
Need to set YOUR DATABASE string on connection to your database name.
I stumbled through this so can't say it is the best method but it does work. Feel free to contact me directly if you have questions (Frank.Perkins@concerto.com)
'*************************************************************************
' File Move and Split script.
' Used to move files from the downloads directory to
' the workarea directory.
' Server name and directory values are read from DTS global
' variables
' Needs a user id to sign on to db
'***********************************************************************
Option Explicit
Dim oFSO
Dim objCommand
Dim objConnection
Dim objRecordSet
Dim sServerName
Dim sTargetFolder
Dim sErrorFolder
Dim sRootFolder
Dim sSubFolders
Dim sFiles
Dim sExtensionString
Dim sTableName
Dim sSpecName
Dim sFormatId
Dim sSplit
Dim sSplitControl
Dim sErrorFile
Dim bRenameFile
Dim sDay
Dim sMonth
Dim sHour
Dim sMinute
Dim sSecond
Dim sDate
Dim sUserID
Dim sPassword
'*************************************************************************
' Default UserID and Password
'*************************************************************************
sUserId = ""
sPassword = ""
'*************************************************************************
'get today's date
sDate = Now()
' Get Rename parameter from global variable
bRenameFile = DTSGlobalVariables("RenameFile").Value
IF bRenameFile THEN
'Get date and time values to use in rename extension
sDay = Day(Date)
IF Len(sDay) = 1 THEN sDay = "0" & sDay
sMonth = Month(Date)
IF Len(sMonth) = 1 THEN sMonth = "0" & sMonth
sHour = Hour(Time)
IF Len(sHour) = 1 THEN sHour = "0" & sHour
sMinute = Minute(Time)
IF Len(sMinute) = 1 THEN sMinute = "0" & sMinute
sSecond = Second(Time)
IF Len(sSecond) = 1 THEN sSecond = "0" & sSecond
sExtensionString = sMonth & sDay & Year(Date) & sHour & sMinute & sSecond
End If
' current server name
sServerName = DTSGlobalVariables("ServerName").Value
' Create File System Object
Set oFSO = CreateObject("Scripting.FileSystemObject")
' Get the from (download) directory
Set sRootFolder = oFso.GetFolder(DTSGlobalVariables("FromDirectory").Value)
' Then get the list of SubFolders beneath this root folder
Set sSubFolders = sRootFolder.SubFolders
' Get the move to (work) directory
sTargetFolder = DTSGlobalVariables("ToDirectory").Value
If Right(sTargetFolder, 1) <> "\" Then
sTargetFolder = sTargetFolder & "\"
End If
' error directory
sErrorFolder = DTSGlobalVariables("ErrorDirectory").Value
If Right(sErrorFolder, 1) <> "\" Then
sErrorFolder = sErrorFolder & "\"
End If
'connect to the database
Set objConnection = CreateObject("ADODB.Connection")
objConnection.ConnectionString = "Provider=sqloledb;Data Source=" & sServerName & ";Initial Catalog=<YOUR DATABASE>;User Id=" & sUserID & ";Pwd=" & sPassword
objConnection.Open
'build a command object to use for SQL Inserts into task history
Set objCommand = CreateObject("ADODB.Command")
Set objCommand.ActiveConnection = objConnection
Set objRecordSet = CreateObject("ADODB.RecordSet")
'*********************************************************************************************************************************
' Main Function for this script
' Loop through downloads directory, pass each file found in root or any subdirectory of
' the root to a split function which will move the file to the workarea directory and split it if it
' has multiple header rows
'*********************************************************************************************************************************
Function Main()
' ***************************************************************************
' Log process start
' ***************************************************************************
' ******** my requirement included subfolders, yours will probably only have the root **********
' Check for files in root folder -- not supposed to be any at this level, but
' account for error
Set sFiles = sRootFolder.Files
For Each sFiles in sFiles
move sFiles.Path, sFiles.Name
oFSO.DeleteFile(filePath)
Next
' Loop through each subfolder
For Each sSubFolders in sSubFolders
' Get the list of files in this subfolder
Set sFiles = sSubFolders.Files
For Each sFiles in sFiles
move sFiles.Path, sFiles.Name
oFSO.DeleteFile(filePath)
Next
Next
' Clean Up
Set oFSO = Nothing
Main = DTSTaskExecResult_Success
End Function
Function move ( filePath, fileName)
Const ForReading = 1
Const ForWriting = 2
Const Appending = 8
Dim objTextStream
Dim strText
Dim bValidHeader
Dim outFileName
Dim tso
Dim iFileNumber
'***************************************************************************
' FileSystemObject.OpenTextFile(fname,mode,create,format)
'***************************************************************************
'Parameter Description
'fname Required. The name of the file to open
'mode Optional. How to open the file
'1=ForReading - Open a file for reading. You cannot write to this file.
'2=ForWriting - Open a file for writing.
'8=ForAppending - Open a file and write to the end of the file.
'create Optional. Sets whether a new file can be created if the filename does not exist.
'True indicates that a new file can be created, and False indicates that a new file will not be created. False is default
'format Optional. The format of the file
'0=TristateFalse - Open the file as ASCII. This is default.
'-1=TristateTrue - Open the file as Unicode.
'-2=TristateUseDefault - Open the file using the system default.
'***************************************************************************
' Open the passed in file for read
Set objTextStream = oFSO.OpenTextFile(filePath , ForReading)
If not objTextStream.AtEndOfStream Then
'read first line
strText = objTextStream.ReadLine
Else
objTextStream.Close
' ******* I track it as an error if file is empty
sErrorFile = sErrorFolder & fileName & "." & sExtensionString
End If
' ******** you will do this outside the function so it doesn't open another file ***************
'set up the output file name
outFileName = sTargetFolder & fileName & "." & sExtensionString
'and open it for write
Set tso = oFSO.OpenTextFile(outFileName, ForWriting, True)
' ******** you will do this outside the function so it doesn't open another file ***************
'write the first line to the output file
tso.WriteLine(strText)
'read the next line
strText = objTextStream.ReadLine
'if not at end, go into loop and write records until EOF
If NOT objTextStream.AtEndOfStream Then
Do While NOT objTextStream.AtEndOfStream
tso.WriteLine(strText)
strText = objTextStream.ReadLine
Loop
tso.WriteLine(strText)
tso.Close
Else
' this is an error in my case, only one record and it is the header, you may not need
objTextStream.Close
sErrorFile = sErrorFolder & fileName & "." & sExtensionString
oFSO.MoveFile filePath, sErrorFile
tso.Close
Exit Function
End If
objTextStream.Close
Set objTextStream = Nothing
Set tso = Nothing
oFSO.DeleteFile(filePath)
End Function
Viewing 7 posts - 1 through 6 (of 6 total)
You must be logged in to reply to this topic. Login to reply