如何插入 BLOB 数据类型

5
我正在使用以下代码向blob字段中插入数据:
MySql.Data.MySqlClient.MySqlConnection conn;
MySql.Data.MySqlClient.MySqlCommand cmd;

conn = new MySql.Data.MySqlClient.MySqlConnection();
cmd = new MySql.Data.MySqlClient.MySqlCommand();

string SQL;
int FileSize;
byte[] rawData;
FileStream fs;

conn.ConnectionString = "server=192.168.1.104;uid=root;" +
        "pwd=root;database=cady234;";

fs = new FileStream(@"d:\Untitled.gif", FileMode.Open, FileAccess.Read);
FileSize = (int)fs.Length;

rawData = new byte[FileSize];
fs.Read(rawData, 0, FileSize);
fs.Close();

conn.Open();

string strFileName = "test name";
SQL = "INSERT INTO file (file_name, file_size, file) VALUES ('" + strFileName + "', "+FileSize+", '"+rawData+"')";

cmd.Connection = conn;
cmd.CommandText = SQL;

cmd.ExecuteNonQuery();
conn.Close();

插入操作是正确的,但在使用“在查看器中打开值”时无法显示图像:

enter image description here
2个回答

19

由于您使用字符串连接,二进制数据没有被正确地传递到插入中-您将得到rawData.ToString(),它可能只打印TypeName(因此您的二进制数据长度为13字节,而文件大小为> 3000字节); 相反,请尝试这样做:

byte[] rawData = File.ReadAllBytes(@"d:\Untitled.gif");
FileInfo info = new FileInfo(@"d:\Untitled.gif");

int fileSize = Convert.ToInt32(info.Length);

using(MySqlConnection connection = new MySqlConnection("server=192.168.1.104;uid=root;pwd=root;database=cady234;"))
{
    using(MySqlCommand command = new MySqlCommand())
    {
        command.Connection = connection;
        command.CommandText = "INSERT INTO file (file_name, file_size, file) VALUES (?fileName, ?fileSize, ?rawData);";
        MySqlParameter fileNameParameter = new MySqlParameter("?fileName", MySqlDbType.VarChar, 256);
        MySqlParameter fileSizeParameter = new MySqlParameter("?fileSize", MySqlDbType.Int32, 11);
        MySqlParameter fileContentParameter = new MySqlParameter("?rawData", MySqlDbType.Blob, rawData.Length);

        fileNameParameter.Value = "test name";
        fileSizeParameter.Value = fileSize;
        fileContentParameter.Value = rawData;

        command.Parameters.Add(fileNameParameter);
        command.Parameters.Add(fileSizeParameter);
        command.Parameters.Add(fileContentParameter);

        connection.Open();

        command.ExecuteNonQuery();

    }
}

我在这里向你介绍了几个概念;首先,如果您要一次性加载所有二进制数据,只需使用静态方法File.ReadAllBytes - 这样可以减少很多代码量。

其次,不必每次都使用完全限定的命名空间 - 使用using指令

第三,(稍有困惑)C#中还有一个using语句。这确保了任何实现IDisposable接口的对象在自身正确清理后被处理。在连接的情况下,如果命令成功或失败,它将显式调用Close和Dispose。

最后,我已经参数化了您的查询。参数有许多用途;它们有助于防止SQL注入,并且在这种情况下,它们还应确保正确处理您的数据类型。您可以阅读更多关于SqlParameter的信息(它像MySqlParameter一样是特定于数据库的实现,但使用相同的原理)。

已在.NET 4下测试与MySQL 5.5.15、MySQL Connector 5.2.7配合使用成功


谢谢! 我已经尝试过了,但是出现了以下异常:{"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' _fileSize, _rawData)' at line 1"}我正在使用MySQL版本5。 - Jobi
1
请尝试以下的 SQL: command.CommandText = "INSERT INTO file (file_name, file_size, file) VALUES (?,?,?)"; 我稍后会有机会测试它。 - dash
现在又出现了另一个异常: {"参数 '?' 必须被定义。"} - Jobi
1
@Jobi 我已经更新了答案 - 在参数前加上 ? 可以奇妙地工作。我已经测试了代码并验证它可以工作 :-) - dash

-4

这样怎么样:

对我来说它运行良好。
但我发现它不适合我。

<?php
// csv invoeren naar pos.

$CSV = "uitvoer.csv";
 // The CSV file has only 2 colums; The "Reference" and the image name (in my case the barcode with "thumb_" in front of it.

$username = "Username";
$password = "Passwwoorrdd";
$database = "POS";
$counter = 0;

// Create connection
$conn = new mysqli("localhost", $username, $password, $database);

// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
} 
echo "Connected successfully <br>";

//$mysqli->select_db();
ini_set('max_execution_time', 1000); //300 seconds = 5 minutes

if (($handle = fopen($CSV, "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 1050, ",")) !== FALSE) {
        // this loops through each line of your csv, putting the values into array elements

    $counter++;

$IDEE = $data[0]; 
        // It seems that after opening the image the $data is mixed up.

$imag = "photos/".$data[1];  // where "photos/' the folder is where this php file gets executed (mostly in /var/www/ of /var/www/html/)

$fh = fopen($imag, "r");
$data = addslashes(fread($fh, filesize($imag)));
fclose($fh);

echo " Ref: ".$IDEE." ----".$counter."----<br>";
   // If there will be a time-out. You could erase the part what is already done minus 1.
$sql =  "UPDATE PRODUCTS SET IMAGE='".$data."' WHERE CODE=$IDEE";

// 带有图像的产品表。该表中还有更多数据,但我只需要更新图像。其余部分已经插入。

if ($conn->query($sql) === TRUE) {
    echo "Tabel <b>products</b> updated successfully<br>";
} else {
    echo "<br>Error updating tabel <b>Products</b>: " . $conn->error;
Exit();
}
    }
    fclose($handle);
}
?>

这是PHP代码...虽然是一种创新的方法,但OP的代码是用C#编写的。他们需要安装PHP解释器才能使用这段代码。 - vapcguy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接