Click here to Skip to main content
15,885,004 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hello,

I use the following code to stream filedata into a database:

C#
private static bool WriteFileDataToDb(Guid fileid, string filename, System.IO.Stream stream, long length)
        {
            bool success = true;               

            using (System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection(Config.ConnectionString))
            {
                SqlCommand command = null;

                try
                {                    
                    connection.Open();                    

                    command = connection.CreateCommand();
                    command.CommandTimeout = Config.SQLTimeout;
                    command.CommandText = "UPDATE [File] SET FileData.WRITE(@Bytes,@Index,@Length) WHERE FileId = @Id";

                    SqlParameter param_bytes = command.CreateParameter();
                    SqlParameter param_index = command.CreateParameter();
                    SqlParameter param_length = command.CreateParameter();
                    SqlParameter param_id = command.CreateParameter();
                    
                    param_bytes.DbType = DbType.Binary;
                    param_bytes.ParameterName = "@Bytes";
                    param_index.ParameterName = "@Index";
                    param_length.ParameterName = "@Length";
                    param_id.ParameterName = "@Id";                    

                    command.Parameters.Add(param_bytes);
                    command.Parameters.Add(param_index);
                    command.Parameters.Add(param_length);
                    command.Parameters.Add(param_id);
                    
                    int bufflength = 1024;
                    int index = 0;                    
                    byte[] buff = new byte[bufflength];
                                        
                    using (System.IO.BinaryReader br = new System.IO.BinaryReader(stream, Encoding.GetEncoding(Config.Encode)))
                    {
                        param_id.Value = fileid;

                        int offset = 0;

                        while ((buff = br.ReadBytes(buff.Length)).Length > 0)
                        {
                            offset = index * bufflength;

                            param_bytes.Value = buff;
                            param_index.Value = index * bufflength;
                            param_length.Value = buff.Length;

                            try
                            {                             command.ExecuteNonQuery();                                
                            }                            
                            catch (Exception ex)
                            {
                                var msg = ex.Message;
                                var stack = ex.StackTrace;
                                success = false;
                                break;
                            }
                            index++;
                        }
                    }                    
                }
                catch (Exception ex)
                {                   
                    success = false;
                }
                finally
                {
                    if (command != null)
                        command.Dispose();
                    if (connection.State == ConnectionState.Open)
                        connection.Close();
                    if (connection != null)
                        connection.Dispose();
                }
            }
            return success;            
        }


The problem is I get a timeout either on the first ExecuteNonQuery or on the last one (end of file).
I have no idea where this error could come from.
Does anyone have an idea?

Kind regards.
Posted
Comments
ZurdoDev 11-Nov-14 10:59am    
I'm not sure if changing the stand alone parameter after you've already added it to the sqlCommand object will work.

You may want to change param_bytes.Value = buff; to command.Parameters[x].Value = buff
Richard Deeming 11-Nov-14 11:03am    
I don't think that's the problem - I've changed the value of parameter objects after adding them to the command, and it always works.
ZurdoDev 11-Nov-14 11:04am    
Interesting.
Member 10945064 11-Nov-14 13:06pm    
When setting the timeout to 0 or very large (5 minutes) the command gets executed.
But that takes very long (> 3 minutes).
In most cases the problem occurs for the last few bytes (in my test case 102).
It can't take over 3 minutes to append 102 bytes, so there has to be another reason for this.
Sometimes the first 1024 bytes take a long time, but then the rest executes very fast.
Sometimes (really not often) the error does not occur, then the streaming is done in 10 seconds, otherwise it takes over 3 minutes.
I don't know if this information is helpful, but I wanted to mention it.
Corporal Agarn 11-Nov-14 15:01pm    
is FieldID indexed?

1 solution

The root of this behavior seems to be a bug in the auto_update_statistics option (https://connect.microsoft.com/SQLServer/feedback/details/174619/update-statistics-holding-exclusive-lock-and-blocking).
After disabling the option for this table I could not reproduce the error.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900