A safe array of bytes is expected as an argument

D

Dooza

Hi there,
I am using the ASP to PDF component from www.asppdf.com and have an
unusual problem when displaying a blob from the database.

When there is an image stored in my SQL2000 field of type image, and I
use this:

Params = "x=337; y=408; scalex=.33; scaley=.33"
Set SigImage = Doc.OpenImageBinary(rsMotor("Photo").Value)
Page.Canvas.DrawImage SigImage, Params

The image gets drawn in the PDF and everything is fine.

If I try to create a PDF using the same record, but where the image
filed is NULL, I get this error:

Persits.PdfManager.1 error '800a002f'

A safe array of bytes is expected as an argument.

So I thought I need to check if the field isn't null before attempting
to draw it onto the canvas, so I tried this:

If LEN(rsMotor("Photo").Value) > 0 Then
'Insert Photo
Params = "x=337; y=408; scalex=.33; scaley=.33"
Set SigImage = Doc.OpenImageBinary(rsMotor("Photo").Value)
Page.Canvas.DrawImage SigImage, Params
End if

Using this with an image stored in the field gives me the same error
message, its only when the field is empty that the above code works and
doesn't draw the image on the PDF.

I also tried this:

If NOT(ISNULL(rsMotor("Photo").Value)) Then
'Insert Photo
Params = "x=337; y=408; scalex=.33; scaley=.33"
Set SigImage = Doc.OpenImageBinary(rsMotor("Photo").Value)
Page.Canvas.DrawImage SigImage, Params
End if

But still got the same error.

If I don't use any checking code, and have NULL in the image field, I
get the same error. This must be something to do with the binary
content, how can I detect if there is binary content?

Steve
 
D

Dooza

Dooza said:
Hi Jon,
Thanks for the pointers, I like the idea of doing it in SQL, as I am
already using a view to get the data to the page.

I am still open to other ideas.

Cheers,

Steve

I have gone for a temporary solution, as it seems that as soon as you do
a length check or isnull check on the binary field it becomes unusable.

I have used this in my SQL view:

CASE WHEN (MC.mct_photo IS NULL)
THEN '0' ELSE '1' END AS PhotoCheck

And this on my page:

If rsMotor("PhotoCheck") = 1 Then
'Insert Photo
Params = "x=337; y=408; scalex=.33; scaley=.33"
Set SigImage = Doc.OpenImageBinary(rsMotor("Photo").Value)
Page.Canvas.DrawImage SigImage, Params
End if

Does anyone have any experience with using binary data in asp? Am I
right in thinking that the starting position has changed due to the
length check? Is there a way to reset the starting position?

Cheers,

Steve
 
D

Dave Anderson

Dooza said:
I have gone for a temporary solution, as it seems that as soon as you
do a length check or isnull check on the binary field it becomes
unusable.
I have used this in my SQL view:

CASE WHEN (MC.mct_photo IS NULL)
THEN '0' ELSE '1' END AS PhotoCheck

And this on my page:

If rsMotor("PhotoCheck") = 1 Then
'Insert Photo
Params = "x=337; y=408; scalex=.33; scaley=.33"
Set SigImage = Doc.OpenImageBinary(rsMotor("Photo").Value)
Page.Canvas.DrawImage SigImage, Params
End if

Does anyone have any experience with using binary data in asp? Am I
right in thinking that the starting position has changed due to the
length check? Is there a way to reset the starting position?

Rather than checking for NULL, use DATALENGTH:
http://msdn2.microsoft.com/en-us/library/ms173486.aspx
 
D

Dave Anderson

Dooza said:
Hi Dave, thats a new one on me, is it SQL only, or can I use
it in ASP/VBScript?

It's only VBScript if you can find it here:
http://msdn2.microsoft.com/en-us/library/d1wf56tt.aspx

The link I provided is Transact-SQL. I meant for you to understand that you
can use it in this manner:

SELECT
MC.mct_photo,
DATALENGTH(MC.mct_photo) AS Bytes,
...
FROM [Your Table]

This does not require a conditional evaluation in the database. You will be
using one, regardless, in your web script, so why add another?
 
A

Anthony Jones

Dooza said:
I have gone for a temporary solution, as it seems that as soon as you do
a length check or isnull check on the binary field it becomes unusable.

I have used this in my SQL view:

CASE WHEN (MC.mct_photo IS NULL)
THEN '0' ELSE '1' END AS PhotoCheck

And this on my page:

If rsMotor("PhotoCheck") = 1 Then
'Insert Photo
Params = "x=337; y=408; scalex=.33; scaley=.33"
Set SigImage = Doc.OpenImageBinary(rsMotor("Photo").Value)
Page.Canvas.DrawImage SigImage, Params
End if

Does anyone have any experience with using binary data in asp?
Yes

Am I right in thinking that the starting position has changed due to the
length check?
Yes

Is there a way to reset the starting position?

No

When using a foward only recordset once you have consumed a BLOB you can't
consume it again. Additional you can't access standard fields once you've
started reading a BLOB.

Therefore you should use DATALENGTH as Dave suggests but you should move it
and any other fields you need to the beginning of the set of fields and
leave the photo data field as the last field. Do not attempt to use any of
the fields after consuming the photo.

Note also that DATALENGTH returns null if the field passed to it as a
parameter is null so you'll need to test that field with IsNull in VBScript
code.
 
D

Dooza

Dave said:
The link I provided is Transact-SQL. I meant for you to understand that you
can use it in this manner:

SELECT
MC.mct_photo,
DATALENGTH(MC.mct_photo) AS Bytes,
...
FROM [Your Table]

This does not require a conditional evaluation in the database. You will be
using one, regardless, in your web script, so why add another?

That makes perfect sense and works perfectly too. It will also allow me
to keep an eye on the size of images in the table.

Thanks again!

Steve
 
D

Dooza

Anthony said:
Dooza said:
Dooza said:
Jon Paal [MSMD] wrote: http://databases.aspfaq.com/databas...s-in-my-database-from-mucking-up-my-html.html

http://databases.aspfaq.com/database/coalesce-vs-isnull-sql.html
Hi Jon,
Thanks for the pointers, I like the idea of doing it in SQL, as I am
already using a view to get the data to the page.

I am still open to other ideas.

Cheers,

Steve
I have gone for a temporary solution, as it seems that as soon as you do
a length check or isnull check on the binary field it becomes unusable.

I have used this in my SQL view:

CASE WHEN (MC.mct_photo IS NULL)
THEN '0' ELSE '1' END AS PhotoCheck

And this on my page:

If rsMotor("PhotoCheck") = 1 Then
'Insert Photo
Params = "x=337; y=408; scalex=.33; scaley=.33"
Set SigImage = Doc.OpenImageBinary(rsMotor("Photo").Value)
Page.Canvas.DrawImage SigImage, Params
End if

Does anyone have any experience with using binary data in asp?
Yes

Am I right in thinking that the starting position has changed due to the
length check?
Yes

Is there a way to reset the starting position?

No

When using a foward only recordset once you have consumed a BLOB you can't
consume it again. Additional you can't access standard fields once you've
started reading a BLOB.

Therefore you should use DATALENGTH as Dave suggests but you should move it
and any other fields you need to the beginning of the set of fields and
leave the photo data field as the last field. Do not attempt to use any of
the fields after consuming the photo.

Putting the Blob field at the end of the table and the end of my view
was the one thing I did know about Blobs, which is why I guessed that it
was the starting position that was my problem.

I have put the Datalength field just before the Blob.
Note also that DATALENGTH returns null if the field passed to it as a
parameter is null so you'll need to test that field with IsNull in VBScript
code.

Perfect, I have used a NOT ISNULL to display the blob.

Thanks again!

Steve
 
B

Bob Barrows [MVP]

Anthony said:
Note also that DATALENGTH returns null if the field passed to it as a
parameter is null so you'll need to test that field with IsNull in
VBScript
code.

....or use " ... COALESCE(DATALENGTH(field),0) as fieldlength, ... " in the
sql statement.
 
D

Dooza

Bob said:
...or use " ... COALESCE(DATALENGTH(field),0) as fieldlength, ... " in the
sql statement.

So this basically checks if the datalength is null, and if it is, uses 0
instead, if its not it uses the datalength... I am starting to like
Coalesce more and more. In my ASP I would then check for 0 instead of NULL.

I am currently testing for null, is there any performance benefits to
using the above, or should I stick with what I have working at the moment?

Steve
 
B

Bob Barrows [MVP]

Dooza said:
So this basically checks if the datalength is null, and if it is,
uses 0 instead, if its not it uses the datalength... I am starting to
like Coalesce more and more. In my ASP I would then check for 0
instead of NULL.

?
You should still check for 0 after checking for Null. The field could
contain a zero-length string ...
I am currently testing for null, is there any performance benefits to
using the above, or should I stick with what I have working at the
moment?
It avoids having to do two checks in the vbscript code. Now all you have to
check for is 0.
 
D

Dooza

Bob said:
?
You should still check for 0 after checking for Null. The field could
contain a zero-length string ...

It avoids having to do two checks in the vbscript code. Now all you have to
check for is 0.

Of course, I should have been checking for empty but not null as well.
Your solution is working nicely.

Thank you Bob!

Steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top