【问题标题】:SQL + Informix: How do I add a blob when doing an insert? (Using the .NET (C#) SDK)SQL + Informix:如何在插入时添加 blob? (使用 .NET (C#) SDK)
【发布时间】:2011-09-10 03:55:19
【问题描述】:

我正在使用 Informix 和 .NET SDK (C#):

基本上,在执行标准的插入sql语句时,有什么方法可以插入blob?

INSERT INTO mytable (name, theblob) VALUES ('foo', ? what goes here ?);

哦,我的数据是字节[]数组的形式。

【问题讨论】:

    标签: c# sql insert blob informix


    【解决方案1】:

    最好的办法是使用参数化查询。例如:

    using(System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("INSERT INTO mytable (name, theblob) VALUES ('foo', @binaryValue)", conn))
    {
      cmd.Parameters.Add("@binaryValue", System.Data.SqlDbType.Text, 8000).Value = arraytoinsert;
      cmd.ExecuteNonQuery();
    }
    

    我假设您的列类型是Text。 上述方法的原始功劳来自this post

    【讨论】:

    • 这似乎不起作用。它以@binaryValue 的形式输入,而不是替换参数。
    • 尝试将 Add 的第二个参数更改为 System.Data.SqlDbType.VarBinary。您可以发布您的 sql 表定义和您尝试使用的代码吗?
    【解决方案2】:

    几点说明:

    1) 你应该使用参数化查询

    //Assuming you already have a connection somewhere that is opened.
    
    var sql = "INSERT INTO mytable (name, theblob) VALUES (?, ?);";
    
    using (var command = new IfxCommand(sql, connection))
    {
        command.Parameters.Add(new IfxParameter()).Value = "foo";
        command.Parameters.Add(new IfxParameter()).Value = ifxBlob;
    }
    


    有几点需要注意:Informix 在客户端 SDK 3.5.xC7(到目前为止)方面存在一个错误。您可以在插入期间轻松传入字节数组,但如果传入 byte[] 数组,则在执行更新时会出现 609 错误。相反,您必须使用IfxBlob 对象。
    public IfxBlob CreateIfxBlob(byte[] data)
    {
        //Get the connection however you like and make sure it's open...
        //Obviously you should make this method handle exceptions and the such.
    
        IfxBlob blob = connection.GetIfxBlob();
    
        blob.Open(IfxSmartLOBOpenMode.ReadWrite);
        blob.Write(data);
        blob.Close();
    
        return blob;
    }
    

    您必须在更新期间传入一个 IfxBlob,因此您最好在插入期间也这样做。

    另外,请记住,如果您尝试设置null,则会收到错误消息。相反,如果值为空,则传入 DBNull.Value。

    public Object AsDBValue(Object value) //Or this Object value if you want it as an extension
    {
        if (value == null)
            return DBNull.Value;
    
        //Other checks
        if (value is Enum)
            return Convert.ChangeType(value, value.GetType().GetEnumUnderlyingType());
    
        //Is Blob?
        if (value is byte[])
            return GetIfxBlob(value as byte[]);
    
        return value;
    }
    

    不要指定参数的类型

    //These will lead to errors unless you typecast the parameters in the query.
    new IfxParameter { IfxType = IfxType.Blob };
    new IfxParameter { DbType = DbType.Binary };
    

    如果您执行其中任何一项,则必须执行以下操作:

    • 当 Blob 值不为空时:"INSERT INTO mytable (name, theblob) VALUES (?, ?::blob);";
    • 当 Blob 值为空时:"INSERT INTO mytable (name, theblob) VALUES (?, ?::byte);";

    您可以看到,由于类型和值的不同,有不同的查询会让人头疼。只是不要指定 DbType 或 IfxType 并让 Informix .NET 提供程序为您映射正确的类型(即使它无法在更新上正确映射 byte[] 数组)。

    希望这对你有用,因为我经历了同样的痛苦试图解决这个问题并发现我认为是 Informix .NET 提供程序(版本:3.5.xC7)中的错误。

    【讨论】:

      【解决方案3】:

      我阅读了您的两条消息,这是对我有帮助的解决方案:

       byte[] data = File.ReadAllBytes(PathFile);
      
       StringBuilder sql = new StringBuilder();
      
      sql.Append(" UPDATE  updater SET report = ?  where path = " + "\'" + Path + "\' and status = 1;");
      IfxCommand cmd = new IfxCommand(sql.ToString(), i_connect);
      cmd.Parameters.Add("@binaryValue", IfxType.Byte).Value = data;
      int res = cmd.ExecuteNonQuery();
      

      PathFile - 是一个 File.txt

      我的信息表:

         CREATE TABLE updater
       (
          nzp_up SERIAL PRIMARY KEY,
          version VARCHAR(50),
          status INT,
          path VARCHAR(200),
          key VARCHAR(100),
          soup VARCHAR(20),
          report TEXT
       );
      

      【讨论】:

        【解决方案4】:

        这篇文章对解决我的问题非常有用,所以我想分享我的解决方案,它可能对其他人有所帮助。完整代码如下:

                try
                {
                    //pFoto is a byte[] loaded in another method.
                    if (pFoto != null && pFoto.Length > 0)
                    {
                        StringBuilder sentenciaSQL = new StringBuilder();
                        sentenciaSQL.Append("INSERT INTO bd_imagenes:imagenes ");
                        sentenciaSQL.Append("(identificador, cod_imagen, fecha_desde, fecha_hasta, fecha_grabacion, usuario, sec_transaccion, imagen) ");
                        sentenciaSQL.Append("VALUES (?, 'FP', current, null, current, ?, 0, ?);");
        
                        using (IfxConnection conIFX = new IfxConnection("Database=bd_imagenes; Server=xxxxxxxx; uid=xxxxxxx; password=xxxxxxxx; Enlist=true; Client_Locale=en_US.CP1252;Db_Locale=en_US.819"))
                        {
                            conIFX.Open(); //<- Abro la conexion.
                            //Aqui convierto la foto en un BLOB:                        
                            IfxBlob blob = conIFX.GetIfxBlob();
                            blob.Open(IfxSmartLOBOpenMode.ReadWrite);
                            blob.Write(pFoto);
                            blob.Close(); 
        
                            //Creo el Comando con la SQL:
                            using (IfxCommand cmd = new IfxCommand(sentenciaSQL.ToString(), conIFX))
                            {
                                //Agrego los parámetros en el mismo orden que la SQL:
                                cmd.Parameters.Add(new IfxParameter()).Value = pCedula;
                                cmd.Parameters.Add(new IfxParameter()).Value = SecurityHandler.Auditoria.NombreUsuario;
                                cmd.Parameters.Add(new IfxParameter()).Value = blob;
                                //Ejecuto la Consulta:
                                Resultado = cmd.ExecuteNonQuery();
                            }
                            conIFX.Close();  
                        }
                        if (Resultado != 0) { retorno = true; }
                    }
                }
                catch (IfxException ae)
                {
                    if (exepcionesValidacion == null) { exepcionesValidacion = new ArrayList(); }
                    exepcionesValidacion.Add(Util.CrearExcepcion(ae.Message, "ERROR_INESPERADO", ae.StackTrace));
                }
                catch (Exception ex)
                {
                    if (exepcionesValidacion == null) { exepcionesValidacion = new ArrayList(); }
                    exepcionesValidacion.Add(Util.CrearExcepcion(ex.Message, "ERROR_INESPERADO", ex.StackTrace));
                }
                return retorno;
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-05-23
          • 1970-01-01
          • 2012-09-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-06-02
          相关资源
          最近更新 更多