Интерпретация байта [] в хранимой процедуре

#c# #.net #sql-server #stored-procedures #entity-framework-4

#c# #.net #sql-сервер #хранимые процедуры #entity-framework-4

Вопрос:

Выполняемая нами процедура выполняет поиск в зашифрованном поле путем шифрования поля поиска и сравнения этих зашифрованных значений. Что мне нужно, хотя, чтобы иметь возможность сделать, это передать в proc (через Entity Framework 4) зашифрованное значение (поскольку код шифрует его), но также разрешить null, если значение не указано.

Итак, мне нужно передать байт [], но он также должен принимать нули… возможно ли это вообще, или каков обходной путь, если его нет? Опять же, я вызываю хранимую процедуру через entity framework.

Спасибо.

Комментарии:

1. NULL является допустимым значением для ссылки на байт[]…. итак, в чем проблема?

2. И какую базу данных вы используете? MySQL, MSSQL и т.д.?

3. Извините, SQL Server. массив byte[] с null, ОК. Я не был уверен, возникнет ли какая-либо проблема с EF … или даже если EF переведет переменное значение в массив байтов таким же образом. Я знаю, что LINQ для SQL был немного другим.

4. @Tejs на самом деле вы уверены, что я говорю об обертке EF для хранимой процедуры; мой коллега пытался передать нули, но не смог.

Ответ №1:

Учитывая эту хранимую процедуру:

 create procedure dbo.pConvertBytesToInt

  @bytes varbinary(4)

as

  select convert(int,@bytes)

go
  

Следующий код выполнит его, передавая значение NULL, если переданный параметр равен null:

 static int? Bytes2IntViaSQL( byte[] @bytes )
{
  int? value ;
  const string connectionString = "Data Source=localhost;Initial Catalog=sandbox;Integrated Security=SSPI;" ;
  using ( SqlConnection connection = new SqlConnection( connectionString ) )
  using ( SqlCommand    sql        = connection.CreateCommand() )
  {
    sql.CommandType = CommandType.StoredProcedure ;
    sql.CommandText = "dbo.pConvertBytesToInt" ;

    SqlParameter p1 = new SqlParameter( "@bytes" , SqlDbType.VarBinary ) ;
    if ( @bytes == null ) { p1.Value = System.DBNull.Value ; }
    else                  { p1.Value = @bytes              ; }

    sql.Parameters.Add( p1 ) ;

    connection.Open() ;
    object result = sql.ExecuteScalar() ;
    value = result is DBNull ? (int?)null : (int?)result ;
    connection.Close() ;

  }

  return value ;
}
  

Этот тестовый жгут

 static void Main( string[] args )
{
  byte[][] testcases = { new byte[]{0x00,0x00,0x00,0x01,} ,
                         null                   ,
                         new byte[]{0x7F,0xFF,0xFF,0xFF,} ,
                       } ;

  foreach ( byte[] bytes in testcases )
  {
      int? x =  Bytes2IntViaSQL( bytes ) ;
      if ( x.HasValue ) Console.WriteLine( "X is {0}" , x ) ; 
      else              Console.WriteLine( "X is NULL" ) ;
  }

  return ;
}
  

выдает ожидаемые результаты:

 X is 1
X is NULL
X is 2147483647
  

Ответ №2:

В итоге мы заставили его работать, поместив его в виде строки, а затем проанализировав в процедуре. Это сработало. Но я полагаю, что я читал, что есть двоичный объект, который представляет массив byte [], и это тоже сработало бы.