簡體   English   中英

SQL + Informix:如何在插入時添加 blob? (使用 .NET (C#) SDK)

[英]SQL + Informix: How do I add a blob when doing an insert? (Using the .NET (C#) SDK)

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

基本上,在執行標准插入 sql 語句時,有什么方法可以插入 blob?

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

哦,我擁有的數據是 byte[] 數組的形式。

您最好的選擇是使用參數化查詢。 例如:

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 上述方法的原始功勞來自這篇文章

幾點注意事項:

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 object。

 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 ,您將收到錯誤消息。 相反,如果值為 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 值不是 null 時"INSERT INTO mytable (name, theblob) VALUES (?, ?::blob);";
  • 當 Blob 值為null 時"INSERT INTO mytable (name, theblob) VALUES (?, ?::byte);";

您可以看到,由於類型和值的不同,有不同的查詢會讓人頭疼。 只是不要指定 DbType 或 IfxType 並讓 Informix .NET 提供程序 map 為您提供正確的類型(即使它不能 map 正確地在 Update 數組上)。

希望這對你有用,因為我經歷了同樣的痛苦試圖解決這個問題並發現我認為是 Informix .NET 提供程序(版本:3.5.xC7)中的一個錯誤。

我閱讀了您的兩條消息,這是對我有幫助的解決方案:

 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
 );

這篇文章對解決我的問題非常有用,所以我想分享我的解決方案,它可能對其他人有所幫助。 這是完整的代碼:

        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;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM