Showing posts with label systemio. Show all posts
Showing posts with label systemio. Show all posts

Friday, February 24, 2012

Capture System.IO rows from incoming file and insert into table

Ok, I'm not quite sure how to approach this one. This is a VB.NET console app in which I want to capture each row and throw it into a table. The reason being, they want a report on what was processed...which I'll be able to do easily in Reporting Services 2005 once this crap is in a table where it should be.

1) What should I use to do this, dataset? I want to use stored procedures also, not inline SQL

Function here takes an incoming file, and splits it up into separate files. I want to insert each row that is succesfully split

Public Sub ProcessFiles(ByVal sIncomingfile As String, ByVal sOutputDirectory As String)

If sIncomingfile <> "" And sOutputDirectory <> "" Then

Dim f As New Security.Permissions.FileIOPermission(Security.Permissions.PermissionState.None)
f.AllLocalFiles = Security.Permissions.FileIOPermissionAccess.Read

Dim file As New IO.FileInfo(sIncomingfile)
Dim filefs As IO.FileStream = Nothing
If file.Exists Then
Try
filefs = New IO.FileStream(file.FullName, IO.FileMode.Open) 'Place: 1
Catch ex As Exception
SendEmail("Incoming .mnt or .naf Filename Invalid or not found", "Place: 1")
Application.Exit()
End Try
End If

Dim reader As New IO.StreamReader(filefs)
Dim counter As Integer = 0

Dim CurrentFS As IO.FileStream
Dim CurrentWriter As IO.StreamWriter
Dim extension As String = IO.Path.GetExtension(file.FullName)


If extension = ".mnt" Then
While Not reader.Peek < 0
Dim Line As String = reader.ReadLine
If IsNumeric(Line.Substring(0, 1)) Then
Dim Parts() As String = Line.Split(" "c) ' split row into parts
If Parts(0).Length = 8 Then ' if first part is 8 then know we hit another header so cut and then write to file
counter += 1
If Not CurrentWriter Is Nothing Then CurrentWriter.Flush() : CurrentWriter.Close()
CurrentFS = New IO.FileStream(IO.Path.Combine(IO.Path.GetDirectoryName(sOutputDirectory), Line.Substring(59, 4) & "[" & counter.ToString & "]" & Now.ToString("MM-dd-yyyy") & IO.Path.GetExtension(file.FullName)), IO.FileMode.Create)
CurrentWriter = New IO.StreamWriter(CurrentFS)
End If

If Not CurrentWriter Is Nothing Then
CurrentWriter.WriteLine(Line)
End If

End If
End While

If Not CurrentWriter Is Nothing Then CurrentWriter.Flush() : CurrentWriter.Close()

MoveFilesFTP(sOutputDirectory, "mnt")

ElseIf extension = ".naf" Then
While Not reader.Peek < 0
Dim Line As String = reader.ReadLine
If Not IsNumeric(Line.Substring(0, 1)) Then ' if first part is not a number, then we know it's a header so split the file
counter += 1
If Not CurrentWriter Is Nothing Then CurrentWriter.Flush() : CurrentWriter.Close()
CurrentFS = New IO.FileStream(IO.Path.Combine(IO.Path.GetDirectoryName(sOutputDirectory), Line.Substring(6, 4) & "[" & counter.ToString & "]" & Now.ToString("MM-dd-yyyy") & IO.Path.GetExtension(file.FullName)), IO.FileMode.Create)
CurrentWriter = New IO.StreamWriter(CurrentFS)
End If

If Not CurrentWriter Is Nothing Then
CurrentWriter.WriteLine(Line)
End If

End While

If Not CurrentWriter Is Nothing Then CurrentWriter.Flush() : CurrentWriter.Close()

MoveFilesFTP(sOutputDirectory, "naf")
End If
Else
'input file not valid
SendEmail("Incoming .mnt or .naf Filename Invalid", "Place: 1")
End If
End Sub

You don't need a console application to import the data into SQL Server if you are in SQL Server 2000 you need a DTS package and in SQL Server 2005 you need an Integration services package. The only important thing to note is SQL Server being a RDBMS(relational database management systems) sees a text file as having Null values so you import your data into a Temp table then do INSERT INTO your destination table. Try the link below for sample DTS and Integration services code. Hope this helps.

http://www.sqlis.com/

|||

Put this somewhere at the top:

Dim conn as new sqlconnection("Your connect string")
conn.open
Dim cmd1 as new sqlcommand("INSERT INTO ProcessedFiles(Filename) VALUES (@.Filename) SELECT SCOPE_@.IDENTITY()")

cmd1.parameters.add("@.Filename",sqldbtype.varchar)

dim cmd2 as new sqlcommand("INSERT INTO ProcessedLines(FileID,LineNum,LineData) VALUES (@.FileID,@.LineNum,@.LineData)",conn)

cmd2.parameters.add("@.FileID",sqldbtype.int32)

cmd2.parameters.add("@.LineNum",sqldbtype.int32)

cmd2.parameters.add("@.LineData",sqldbtype.varchar)

Then after you get the filename in your code:

cmd1.parameters("@.Filename").value={Your filename variable}

cmd2.parameters("@.FileID").value = cmd1.executescaler

Then after you read a line of data from the file:

cmd2.parameters.add("@.LineNum").value=counter

cmd2.parameters.add("@.LineData").value=line

cmd2.executenonquery

And at the end of your program:

conn.close

of course, this assumes you have a table named processedfiles that has a Filename column, as well as an identity field. I would put a ProcessedDate field in there too, that defaults to GetUTCDate(). And a table named ProcessedLines that has three columns (FileID,LineNum,LineData).

Is that what you were looking for?