Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsVB SyntaxEnterprise DevelopmentDatabase AccessControlsCOMWin APICrystal ReportDeploymentGeneralGeneral 2
Related Topics
VB.NET / ASP.NETMS SQL ServerMS AccessOther Database ProductsMore Topics ...

VB Forum / Database Access / June 2007



Tip: Looking for answers? Try searching our database.

AppendChunk method resulting in wrong data

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
everymn@yahoo.com - 21 Jun 2007 01:16 GMT
Hi,
Having a bit of trouble with the Parameter.AppendChunk method.  The
test output from the below code is as follows:

Trace: param first byte: 0
Trace: param second byte: 255
Trace: Source first byte: 255
Trace: Original file length: 711
Trace: total bytes appended to param: 711
Trace: final param length: 712
Trace: param last byte: 217
Trace: Source last byte: 217

For some reason it appears that the first time I'm call the method,
it's putting a 0 in the first byte of the Parameter value.  It's my
understanding that the first time the method is called it's supposed
to replace the current contents of the value, and when I've done these
tests against field objects using that that object's version of the
same method it works fine.

In this case however, after I've stored the data to the parameter's
value field it is always 1 byte longer than the original data and when
I call Command.Execute, that same data with the extra 0 byte is stored
to the data source.

Unless I've done something specifically wrong here, it appears that
this might be an ADO bug because I've tried it against two different
data source providers and have the same results.

Thanks
Eric

' get  a reference an empty byte array
' to read byte arrays from test file
binArr = TestFunctions.GetByteArr()
   
Set param1 = command1.CreateParameter( _
            "@binValue", adLongVarBinary, _
                                       adParamInput,_
                                       fileSize+1, binArr)

Set param2 = command1.CreateParameter( _
            "@Key", adInteger, _
                                       adParamInput, 0, 0)   

command1.Parameters.Append param1
command1.Parameters.Append param2
command1.Parameters("@Key") = 1

For each col_name in testArr
   strSQL = "UPDATE ado_test SET " & _
                col_name & " = ? WHERE " & key_column & " = ?"
   command1.CommandText = strSQL

   blockSize = 100

  While bytesTotalWritten <> fileSize
       If fileSize - bytesTotalWritten < blockSize Then
            blockSize = fileSize - bytesTotalWritten
       End If
                   
      ' Reads  binary file on block at a time
       iReturn = TestFunctions.GetBytesFromFile( _
                  binArr, bytesTotalWritten, _
                 blockSize, FILE )

     ' write the bytes to the field
     command1.Parameters("@binValue").AppendChunk (binArr)
                   
'DEBUG
If bFirst Then
Assert.Trace "param first char: " & Int(ascB(MidB
(command1.Parameters("@binValue"), 1,1)))
Assert.Trace "param second char: " & Int(ascB(MidB
(command1.Parameters("@binValue"), 2,1)))
Assert.Trace "Source first char: " & Int(ascB(MidB (binArr,1,1)))
End If

     bytesTotalWritten = bytesTotalWritten + blockSize
     bFirst = cBool(false)
  Wend
               
' DEBUG
Assert.Trace "Original file length: " & fileSize
Assert.Trace "total bytes appended to param: " & bytesTotalWritten
Assert.Trace "final param length: " &
lenB(command1.Parameters("@binValue"))

Assert.Trace "param last char: " & Int(ascB(MidB
(command1.Parameters("@binValue"), 712,1)))
Assert.Trace "Source last char: " & Int(ascB(MidB (binArr,11,1)))

   command1.execute
Next
everymn@yahoo.com - 21 Jun 2007 03:14 GMT
I should add that when creating the first parameter to store the
binary data, I was forced to declare the size so..

Set param1 = command1.CreateParameter( _
                         "@binValue", adLongVarBinary,_
                          adParamInput, fileSize+1, binArr)

If I stated the size of the field as fileSize which is the exact size
of the date, I get this error when I perform command.Execute

Probably this is because the extra 0 as the first byte is causing an
overflow if I don't create the param with an extra byte in it

Error: Source: ADODB.Command  Line 202  Column 2
Application uses a value of the wrong type for the current operation.
everymn@yahoo.com - 22 Jun 2007 05:09 GMT
I've determined where the extra byte is coming from but I'm not sure
what to do about it.  I'm doing this in VBs, and since byte() are not
supported there I'm calling a DLL I made in VB6 to create and modify
them for me.  When I do this...

>' get  a reference an empty byte array
>' to read byte arrays from test file
>binArr = TestFunctions.GetByteArr()

I'm calling...

Public Function GetByteArr() As Byte()
   Dim arr(0) As Byte
   GetByteArr = arr
End Function

If I change the dimension to arr(10), then the length of my final
parameter value goes up by 10.  What I'm unlear about is that
supposedly the first time you call appendChunk, it's supposed to
initialize the variable.  I've tried to dimension it as arr() as Byte,
but then when I do this it tells me I'm trying to use the wrong data
type.  

>Set param1 = command1.CreateParameter( _
>            "@binValue", adLongVarBinary, _
>                                        adParamInput,_
>                                        fileSize+1, binArr)

Is there a more appropriate way to initialize the array that I haven't
tried?

Thanks
Eric
Mark J. McGinty - 25 Jun 2007 11:37 GMT
> I've determined where the extra byte is coming from but I'm not sure
> what to do about it.  I'm doing this in VBs, and since byte() are not
[quoted text clipped - 26 lines]
> Is there a more appropriate way to initialize the array that I haven't
> tried?

Have you tried omitting the value arg when you create the parameter object?
Perhaps CreateParameter internally calls AppendChunk if/when a value is
explicitly passed?

Also, there is another way to transfer blob values that works with recordset
fields, so should work with Parameter values as well:

Dim s As ADODB.Stream
Set s = New ADODB.Stream
s.Mode = adModeReadWrite
s.Type = adTypeBinary
s.Open

' load binary contents of into stream
' assumes FileName is the name of an existing file
s.LoadFromFile FileName
' set position to beginning of stream
s.Position = 0

' insert a row (or otherwise position record pointer)
rs.AddNew
' assign other fields as required
' ...
' assumes image field name is 'blob'
rs.Fields("blob").value = s.Read()

rs.Update
s.Close

-Mark

> Thanks
> Eric
everymn@yahoo.com - 25 Jun 2007 19:42 GMT
Mark,

Yes, good call, that's exactly what it was doing.  
Thanks

Just out of curiousity, is there a direct way to read data a block at
a time from a Stream?  Here I've been using the Get method as follows
   Open FilePath For Binary Access Read As #fileIndex
   Get #fileIndex, offset, arrBin2
   Close

Thanks
Eric

>Have you tried omitting the value arg when you create the parameter object?
>Perhaps CreateParameter internally calls AppendChunk if/when a value is
[quoted text clipped - 29 lines]
>> Thanks
>> Eric
Mark J. McGinty - 30 Jun 2007 08:49 GMT
> Mark,
>
[quoted text clipped - 6 lines]
>    Get #fileIndex, offset, arrBin2
>    Close

The Stream's Read method accepts an optional NumBytes parameter, but I'm not
sure how it could be used to chunk-up a blob parameter -- I take it you're
working with large files and need to show progress?  If that's the case, the
stream may not offer you any advantages.

As I was drafting this, and experimenting a little in an unsaved project, I
noticed that Open accepts adOpenStreamAsync as an option, but apparently
that only applies to certain types of sources.  I also saw that loading a
multi-hundred MB file into a stream blocks for longer than most users like
to see a frozen UI...

But my experiment ended when I was left once again to lament that VB6's
debugger somehow parents the debug target, such that msgbox blocks access to
the debugger IDE -- gah what a horrible design flaw!  You'd think they'd
have provided some way to kill the debug target without killing the IDE, no
matter what the target was doing, ala VS[every version I've used] C++ apps,
but oh no...

Anyway, good luck with your project.

-Mark

> Thanks
> Eric
[quoted text clipped - 34 lines]
>>> Thanks
>>> Eric
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.