Overall Description
I have a web service that:
Retrieves a dataset from our
database
Uses JsonConvert.SerializeObject() to serialize the
object and returns that data to a user's local application as a string
then my client's local application:
Uses JsonConvert.DeserializeObject<DataSet>() to convert the object back into a System.Data.DataSet
My problem
I have a Data Column that holds Varbinary data (Byte[]). This serialize/deserialize process ends up causing that column data type to be a String (I'm guessing base64).
Is there a way that when I deserialize the JSON object that it treats this column as a varbinary?
EDIT: In response to comments
My issue is that I generate a CREATE TABLE scripts based on the columns of my DataSet. When I iterate through the columns I need to specify what datatype each column will be in this new table I generate with SQL. For the columns that should be varbinary my DataColumn data type is String and is indistinguishable from actual string columns like 'Username'
As #eulerfx mentioned you can leave it that way. But if you absolutely need an array use a int[] instead of byte[]. I needed to present the array of numbers as an array of numbers in other contexts (UI) and this worked for me.
Related
Is there a way to get the actual encoded string saved in the Database of column with DataType Bytea. Because when the record is fetched in C# it returns as System.Byte[] which I don't want. I want the data which is saved in that column
E'\\\142\\\247\\\ and so on till the data ends.
I will appreciate your support
When I am querying the data through
SELECT tpl::TEXT from Cards where ecode="xyz";
I get the following error
Error: Cannot cast type bytea to text
Line1: Select tpl::TEXT from cards
Thank you
Like this
As you see that the Bytea column is showing System.Byte[] which was overwritten by my application because the code in C# stores the data in the DataTable column as System.Byte[] while updating the data I didn't decode it and update it .
I am using Navicat premium when I query data it shows me the result when I right click on the grid result and copy as insert statement it shows me two result for different rows
like this
INSERT INTO "public"."cards" ("ecode", "tpl") VALUES ('4210149888659', E'System.Byte[]');
INSERT INTO "public"."cards" ("ecode", "tpl") VALUES('3650257637661',E '\\247\\377\\001\\021\\340\\000\\230\\000\\002U\\000e\\000\\362\\000\\002-\\000\\253\\000p\\000\\002\\207\\000~\\000g\\000\\002\\215\\000{\\000\\317\\000\\002\\334\\000h\\000\\222\\000\\001|\\000\\004\\001U\\000\\002\\202\\000K\\000\\201\\000\\001\\000\\000\\204\\000\\241\\000\\001w\\000\\213\\000\\305\\000\\002\\021\\000V\\000\\237\\000\\002L\\001=\\001\\364\\000\\001X\\001"\\001\\313\\000\\002J\\000\\010\\001\\324\\000\\001\\370\\000\\037\\001J\\000\\002;\\0017\\000\\202\\000\\002\\300\\000\\317\\0007\\000\\002\\215\\000[\\000\\004\\011\\017\\007\\012\\005\\015\\014\\006\\016\\012\\007\\010\\005\\005\\007\\011\\010\\001\\004\\012\\017\\002\\003\\010\\012\\004\\010\\005\\003\\013\\014\\005\\017\\007\\003\\010\\003\\001\\011\\004\\012\\006\\020\\011\\005\\013\\015\\010\\002\\004\\005\\010\\007\\011\\012\\000\\002\\002\\020\\012\\003\\015\\000\\005\\002\\017\\003\\000\\006\\016\\020\\010\\017\\014\\000\\001\\012\\001\\010\\011\\002\\004\\007\\010\\000\\002\\006\\011\\007\\003\\020\\011\\003\\001\\005\\011\\000\\007\\002\\012\\002\\000\\020\\000\\016\\004\\017\\004\\003\\011\\017\\000\\003\\004\\000\\001\\007\\017\\002\\001\\017\\014\\006\\002\\016\\015\\011\\015\\006\\014\\016\\010\\020\\013\\000\\003\\006\\015\\002\\005\\020\\015\\016\\015\\004\\001\\003\\015\\010\\010\\006\\014\\002\\007\\020\\014\\011\\001\\000\\014\\010\\003\\016\\001\\015\\017\\020\\013\\006\\013\\016\\013\\011\\001\\014\\013\\004\\013\\002\\013\\001\\000'
);
You can't just convert it because PostgreSQL can't guarantee it can be converted safely. The best you can do is to convert the escaped form into a string and that's not what you probably want. Keep in mind that since bytea is binary data there is no way that PostgreSQL can be sure that the string that comes out will be legit. You could have embedded nulls in a UTF-8 string, for example, which could cause some fun with buffer overruns if you aren't careful.
This is the sort of thing that should be done in the client-side and you should assume that the data is binary, and not necessarily a valid string. If you want to store strings, store text fields, not bytea.
I have one web application, having one table in oracle10g having following structure:
Column Name DataType
UserImage long
My problem is that how should I display the IMAGE on my aspx page which is stored in long format?
If data type is BLOB or CLOB then it could be easier one, but it's stored in long.
I could not change the datatype since this is third party DB.
Please suggest me how could I achieve this. The solution could be either using Oracle or C#, I'm fine with both.
Thanks in advance.
You can't store an image in a 'long' datatype.
Instead - hold a static list of key-value pairs, each pair defines an index (say, from 1 to n) of an image
and the value holds the Image's file name.
For instance, the following pseudo code demonstrates a similar approach (should be implemented on the client/server side of your application, not in the DB
SWITCH (USERIMAGE)
CASE 1:
SETIMAGE("IMAGES/IMAGE_NUMBER_ONE.JPG");
BREAK:
CASE 2:
SETIMAGE("IMAGES/IMAGE_NUMBER_TWO.JPG");
BREAK:
and so on.
Another solution:
Assume your 1st table is called "Table1". create a new table in your database called my_images
Column name Column type Comments
UserImage LONG Foreign key to Table1.UserImage
ImageData BLOB
And,
SELECT t1.ImageData FROM Table1 t1, my_images mi
WHERE t1.UserImage == mi.UserImage;
The "chunk" characters you have posted seem to be a TIFF image. That gives an idea how the images are stored. In fact, the binary image data seems to be stored as character data. That's certainly completely unsupported and very fragile. I'd recommend converting it as soon as possible.
In the mean time, I can propose two ways of retrieving the data so I cannot guarantee that either one works.
But approaches are susceptible to characters sets: If two or more character sets are involved, your data will be converted and thereby destroyed. And both are susceptible to the maximum length of certain data types.
Approach 1:
Try to go via the RAW data type and retrieve it as a byte array. It's certainly limited to 32'000 characters, maybe even less.
SELECT UTL_RAW.CAST_TO_RAW(UserImage) FROM UNNAMED_TABLE WHERE ...
On the C# side, you should get an OracleBinary or byte[] instance.
Approach 2:
Try to retrieve it as a string. Then convert the string into a byte array using the original encoding (Encoding.GetBytes. With enough luck, the original data can be restored.
I'm using a query in C#. I'm printing out data from a database.
Its number of columns is about 200 and the first column's type is TIMESTAMP.
Other types don't have a problem being printed out. Only TIMESTAMP does.
Someone said I can use TIMESTAMP to get TO_CHAR(COLUMN_NAME, 'YYYYHHDD')
I want to show all of database. But if I want, I should type all of column.
This way newly created columns aren't shown.
I want to use query like this, but it doesn`t work:
SELECT TO_CHAR(TIME, 'HHMMSS'), * FROM DATAS
Please help me with this query.
The following works for me:
SELECT CONVERT(numeric(20,0), stamp + 0) FROM ...
This is where "stamp" is timestamp column.
Assuming you are using SQL Server, you have to read the timestamp value as a byte array and convert it to string. The SQL Server Data Type Mappings on MSDN show that Timestamp maps to Byte[] and can be accessed by the GetSqlBinary or GetBytes methods.
The mapping also shows that timestamp is actually a row version number that changes automatically each time a row is modified. It has nothing to do with time. It's just an incrementing 8 byte number. This number has no meaning for end-users and there is probably no point in showing it anywhere.
If you still want to display it, you can convert the timestamp bytes to an Int64 type using the BitConverter.ToInt64 method.
This might seem an easy question for some, but I am struggling with it.
I am trying to use SQLDataReader.GetFieldType to check if a certain field is an Image field. Lets assume the first field of the result set is an Image field, if I do:
reader.GetFieldType(0).ToString;
I get System.Byte[] But is this the correct way to check for it? I really don't like:
if (reader.GetFieldType(0).ToString="System.Byte[]")
Is there a better way?
Thanks,
AJ
You could always shorten it a bit:
if(reader.GetFieldType(0) == typeof(byte[]));
Unfortunately there's no direct mapping from an image field in SQL Server to a .NET CLR type...which is why you get a byte array.
You might want to add further checking to make sure that the byte array being returned is actually an image (byte arrays are used for image, binary, varbinary, and rowversion columns as well).
You can check the type mappings at:
MSDN - Mapping CLR Parameter Data
It's preferable to use the Type.IsAssignableFrom method instead of looking at the type name itself.
Type fieldType = reader.GetFieldType(0);
bool isImageField = typeof(byte[]).IsAssignableFrom(fieldType);
This gives you some measure of compile-time safety.
Note: This doesn't actually guarantee that the field will contain images - any form of binary data can be stored in image/binary/varbinary fields, so the only way to see if it is truly an image is to read the value and try loading it as one. But you can use this to check if the field is a binary field.
An alternative way could be to use the SqlDataReader.GetSchemaTable method. This will return a datatable containing the schema of the resultset, and makes available the actual datatype from the db - e.g. the DataTypeName column of the schema table returned will be the actual SQL Server datatype like varchar, and the ProviderSpecificDataType column will be a System.Data.SqlType
e.g.
DataTable dataSchema = reader.GetSchemaTable();
// dataSchema.Rows[0]["DataTypeName"] would return the sql server
// data type name for the first column in the resultset.
You might have to check for the first bytes to see if they make an image header. Otherwise, you might deal with an audio file, for instance. So a byte array doesn't necessarily represent an image.
I am using C# & MYSQL to develop a desktop application.
In one of my form I have a DataGridView (dgvBookings) and in my database table I have a table tblBookings which contains a field specialization of type BLOB.
I am selecting data with following query,
SELECT * FROM tblBookings WHERE IsActive=1;
and then binding the data with DataGridView as,
dgvBookings.DataSource = ds.Tables["allbookings"];
BUT after binding the data in gridview it shows Byte[] Array value for all rows of column specialization which is of BLOB type.
How yo solve this problem, I want the data in String format, whatever is written in that column should be show as it is there in the grid.
You'll have to convert the byte array to a string before using the DataSet:
DataTable allBookings = ds.Tables["allbookings"];
DataColumn column = allBookings.Columns.Add("NotABlobAnyMore", typeof(string));
foreach (DataRow row in allBookings.Rows) {
row[column] = Encoding.Unicode.GetString((byte[])row["specialization"]);
}
dgvBookings.DataSource = allBookings ;
In the sample I'm using Unicode, but you should use whatever encoding was used to generate the byte array (blob).
If you are going to allow updates on the new column, you'll have to convert the string back to an array of bytes (in the old column) before sending the data back to the database.
Sink the CellFormatting event and cast the byte array to a String, or cast the BLOB to a character type in your SQL query.
Well, the inherent problem with a BLOB is that it... isn't text. It is binary. It could be an image (jpg etc), an exe, or it could be text... but in which encoding? UTF8? Not simple. If it was a CLOB I'd hope it works OK - but otherwise I would fully anticipate that you'd have to parse the BLOB manually, otherwise how would it be interpreted?
For an arbitrary BLOB, the closest I can think of is to just show something like the hex... but with DataTable even that is a challenge. You could do it for a class via a TypeConverter...