From: Christopher W. <chr...@ad...> - 2003-05-29 14:30:25
|
Hello, I am attempting to use the Firebird Net-Provider to store binary data that can be included in a where clause. I am modifying code that works on MS SQL Server where the column is varbinary with a length of 4096. If I use a blob subtype binary, NetProvider works fine on the insert, but I also want to be able to delete rows based on the value contained in the binary data. Someone please correct me if I am wrong, but the firebird blob seems only for storage and retrieval and it does not appear you can use it as a column in the where clause... I researched it a bit on the web and I have seen the recommendation to store binary data by using char(size) character set octets. Apparently, firebird won't perform any transliteration on the data and stores it in its native binary format. I have tried this solution using the Net-Provider two different ways and in both cases it throws an Invalid Cast exception. I tried setting the FbType of the parameter to Char and also setting it to Binary... I was also wondering if I should use C# to somehow transform the byte[] into a string representing the binary information... Any suggestions on how to solve this problem would be greatly appreciated. Regards, Chris Whelan |
From: Christopher W. <chr...@ad...> - 2003-05-29 14:35:03
|
Hi- I also tried FbType of LongVarBinary which I had used successfully for the blob insertion and I still receive a Invalid Cast exception... Regards, Chris Whelan |
From: Christopher W. <chr...@ad...> - 2003-05-29 17:25:57
|
Hi- FYI to anyone interested: It doesn't seem that efficient, but I solved the problem by iterating over the byte[] contents in a loop and appending the result of (char)byte[i] to a StringBuilder instance. I set the FBType of the parameter to Char and write the string to the database without a problem. I also write the actual length of the data to another column because it represents a serialized object and must be deserialized into an instance. The column that is defined as char(x) character set octets does allow the delete statement that uses it in the where clause to work properly. When I get the results of the select, I need to transform the string representing the binary data into the datatable column format of Base64Binary. That rules out dataAdapter.Fill( dateSet ). Instead I used the following code to load the data from the database table into the dataset: FbDataReader reader = m_daSinks.SelectCommand.ExecuteReader(); byte[] buff1, buff2; while( reader.Read() ) { buff1 = ASCIIEncoding.Default.GetBytes( reader.GetString( 0 ) ); // Binary data is in first column buff2 = new byte[ reader.GetInt16( 1 )]; // Actual Length of the binary data Array.Copy( buff1, 0, buff2, 0, buff2.Length ); object[] vals = new Object[]{ reader.GetInt64(2), buff2, DateTime.Now, EventName }; ds.Tables["tb_sinks"].LoadDataRow( vals, true ); } reader.Close(); Any suggestions for improving this approach would be greatly appreciated. Regards, Chris Whelan |
From: Carlos G. A. <car...@te...> - 2003-05-29 17:37:29
|
Hello: > It doesn't seem that efficient, but I solved the problem by iterating > over the byte[] contents in a loop and appending the result of > (char)byte[i] to a StringBuilder instance. Why do not try using Encoding.Default.GetString(...) ??? > > FbDataReader reader = > m_daSinks.SelectCommand.ExecuteReader(); > > byte[] buff1, buff2; > while( reader.Read() ) > { > > buff1 = ASCIIEncoding.Default.GetBytes( > reader.GetString( 0 ) ); // Binary data is in first column > > buff2 = new byte[ reader.GetInt16( 1 )]; // > Actual Length of the binary data > > Array.Copy( buff1, 0, buff2, 0, buff2.Length ); > > object[] vals = new Object[]{ reader.GetInt64(2), > buff2, DateTime.Now, EventName }; > ds.Tables["tb_sinks"].LoadDataRow( vals, true ); > } > > reader.Close(); Huummmm ... anything like this int bufLen = 0; byte[] buff1, buff2; while( reader.Read() ) { buff1 = new byte[reader.GetInt16( 1 )] // Use here the encoding you need Endcoding.Default.GetBytes( reader.GetString( 0 ), 0, buff1.Length, buff1, 0 ); object[] vals = new Object[]{ reader.GetInt64(2), buff2, DateTime.Now, EventName }; ds.Tables["tb_sinks"].LoadDataRow( vals, true ); } -- Best regards Carlos Guzmán Álvarez Vigo-Spain "No tengo dones especiales.Sólo soy apasionadamente curioso" Albert Einstein, científico. |
From: Christopher W. <chr...@ad...> - 2003-05-29 17:52:20
|
I'll try that...Thanks! On Thu, 2003-05-29 at 13:47, Carlos Guzman Alvarez wrote: > Hello: > > > It doesn't seem that efficient, but I solved the problem by iterating > > over the byte[] contents in a loop and appending the result of > > (char)byte[i] to a StringBuilder instance. > > > Why do not try using Encoding.Default.GetString(...) ??? > > > > > FbDataReader reader = > > m_daSinks.SelectCommand.ExecuteReader(); > > > > byte[] buff1, buff2; > > while( reader.Read() ) > > { > > > > buff1 = ASCIIEncoding.Default.GetBytes( > > reader.GetString( 0 ) ); // Binary data is in first column > > > > buff2 = new byte[ reader.GetInt16( 1 )]; // > > Actual Length of the binary data > > > > Array.Copy( buff1, 0, buff2, 0, buff2.Length ); > > > > object[] vals = new Object[]{ reader.GetInt64(2), > > buff2, DateTime.Now, EventName }; > > ds.Tables["tb_sinks"].LoadDataRow( vals, true ); > > } > > > > reader.Close(); > > > Huummmm ... anything like this > > > int bufLen = 0; > byte[] buff1, buff2; > while( reader.Read() ) > { > buff1 = new byte[reader.GetInt16( 1 )] > // Use here the encoding you need > Endcoding.Default.GetBytes( > reader.GetString( 0 ), 0, buff1.Length, buff1, 0 ); > > object[] vals = new Object[]{ reader.GetInt64(2), > buff2, DateTime.Now, EventName }; > ds.Tables["tb_sinks"].LoadDataRow( vals, true ); > } > > > > |