2009-06-30 14 views
59

Tengo una matriz de bytes resaltada a continuación, ¿cómo la inserto en una columna Varbinary de la base de datos de SQL Server?Cómo insertar un byte [] en una columna VARBINARY de SQL Server

byte[] arraytoinsert = new byte[10]{0,1,2,3,4,5,6,7,8,9}; 

string sql = 
    string.format 
    (
    "INSERT INTO mssqltable (varbinarycolumn) VALUES ({0});",WHATTODOHERE 
    ); 

Gracias de antemano chicos!

Respuesta

69

Mi solución sería utilizar una consulta parametrizada, como los objetos de conectividad cuidar de formatear los datos correctamente (incluyendo asegurar el tipo de datos correcto, y escapar caracteres "peligrosos" en su caso):

// Assuming "conn" is an open SqlConnection 
using(SqlCommand cmd = new SqlCommand("INSERT INTO mssqltable(varbinarycolumn) VALUES (@binaryValue)", conn)) 
{ 
    // Replace 8000, below, with the correct size of the field 
    cmd.Parameters.Add("@binaryValue", SqlDbType.VarBinary, 8000).Value = arraytoinsert; 
    cmd.ExecuteNonQuery(); 
} 

Editar: Se agregó la declaración de "uso" de envoltura sugerida por John Saunders para deshacerse correctamente de SqlCommand después de que haya terminado con

+3

Jason, ¿podría poner una declaración de uso alrededor de "SqlCommand cmd = new ..."? De lo contrario, me sentiré obligado a rechazar, y odiaría eso. –

+11

Si la columna es VARBINARIA (MÁXIMA), entonces reemplace 8000 por -1, consulte http://social.msdn.microsoft.com/Forums/en-US/sqldataaccess/thread/e61f0616-0866-4f3f-aeba-6a76e144e169/ –

74

Prueba esto:

"0x" + BitConverter.ToString(arraytoinsert).Replace("-", "") 

A pesar de que realmente debería estar utilizando una consulta parametrizada en lugar de la concatenación de cadenas, por supuesto ...

+0

Hola David, gracias por la respuesta, ¿por qué debería estar usando una consulta parametrizada? – divinci

+4

Mínimo aquí, pero las consultas parametrizadas se pueden compilar y almacenar en caché, ahorrando el costo de compilación con cada consulta posterior. También protegen contra ataques de inyección SQL. Finalmente, puede establecer directamente el valor del parámetro en la matriz de bytes y evitar las cosas de BitConverter ... –

+0

No crea que trabajar con VARBINARIOS como este es una buena idea en general. SQL Server permite VARBINARIOS muy grandes (¿eran 2 Gb?) Y que probablemente no "escalaran muy bien" con este método. No puedo evaluar si esto sería un problema en este caso particular, por lo que estoy dejando el -1 por ahora. – peSHIr

1

No hay problema si todas las matrices que va a utilizar en este escenario son pequeñas como en su ejemplo .

Si va a utilizar esto para blobs grandes (por ejemplo, almacenar archivos binarios grandes Mbs o incluso Gbs en un VARBINARY) entonces probablemente sería mejor usar soporte específico en SQL Server para leer/escribir subsecciones de tales blobs grandes. Cosas como READTEXT y UPDATETEXT, o en las versiones actuales de SQL Server SUBSTRING.

Para obtener más información y ejemplos, consulte mi artículo de 2006 en .NET Magazine ("BLOB + Stream = BlobStream", en holandés, con el código fuente completo), o una traducción al inglés y generalización de este de on CodeProject por Peter de Jonghe. Ambos están enlazados desde my weblog.

0

verificación de este enlace de imagen para todos los pasos https://drive.google.com/open?id=0B0-Ll2y6vo_sQ29hYndnbGZVZms

PASO 1: He creado un campo de tipo varbinary en la tabla

PASO 2: He creado un procedimiento almacenado para aceptar un parámetro de tipo sql_variant

PASO 3: en mi página de asp.net, creé un parámetro fuente de datos sql del tipo de objeto

 <tr> 
     <td> 
      UPLOAD DOCUMENT</td> 
     <td> 
      <asp:FileUpload ID="FileUpload1" runat="server" /> 
      <asp:Button ID="btnUpload" runat="server" Text="Upload" /> 
      <asp:SqlDataSource ID="sqldsFileUploadConn" runat="server" 
       ConnectionString="<%$ ConnectionStrings: %>" 
       InsertCommand="ph_SaveDocument"  
       InsertCommandType="StoredProcedure"> 
       <InsertParameters> 
        <asp:Parameter Name="DocBinaryForm" Type="Object" /> 
       </InsertParameters> 

      </asp:SqlDataSource> 
     </td> 
     <td> 
      &nbsp;</td> 
    </tr> 

PASO 4: En mi código detrás, trato de cargar los FileBytes de control FileUpload a través de esta llamada de procedimiento almacenado mediante un control de origen de datos SQL

 Dim filebytes As Object 
     filebytes = FileUpload1.FileBytes() 
     sqldsFileUploadConn.InsertParameters("DocBinaryForm").DefaultValue = filebytes.ToString 
     Dim uploadstatus As Int16 = sqldsFileUploadConn.Insert() 

       ' ... code continues ... ' 
0

Usted puede hacer algo como esto, muy simple y eficiente solución: Lo que hice fue usar un parámetro en lugar del marcador de posición básico, crear un objeto SqlParameter y utilizar otro método de ejecución existente. Por ejemplo, en su escenario:

string sql = "INSERT INTO mssqltable (varbinarycolumn) VALUES (@img)"; 
SqlParameter param = new SqlParameter("img", arraytoinsert); //where img is your parameter name in the query 
ExecuteStoreCommand(sql, param); 

Esto debería funcionar como un amuleto, siempre que tenga una conexión abierta de sql establecida.

Cuestiones relacionadas