简体   繁体   English

在C#中将Blob数据从一个表复制到另一个表

[英]copy blob data from one table to another in c#

basically i have a service which looks at two tables - one resides on a remote server, the other locally. 基本上我有一个服务,它查看两个表-一个驻留在远程服务器上,另一个驻留在本地。 I am trying to write a program which will select any required files from the remote server and copy them locally. 我正在尝试编写一个程序,该程序将从远程服务器中选择任何必需的文件并将其复制到本地。 i can get this working for standard records but how do i handle the blob in c# - i am just starting out with the language so be gentle 我可以将其用于标准记录,但是我该如何处理C#中的Blob-我只是从语言入手,所以要保持温柔

a snippet of what i have is below 我所拥有的片段如下

public static void BroadcastCheck(String ip_addr)
    {
        OdbcConnection local = new OdbcConnection("DSN=local");
        OdbcConnection cloud = new OdbcConnection("DSN=cloud");
        local.Open();
        cloud.Open();
        OdbcCommand update1 = new OdbcCommand("UPDATE exchange set status = '1' where `status`='0' and inp_date=chg_date and LEFT(filename,12)='" + ip_addr + "' and type='UPDATE'", cloud);
        update1.ExecuteNonQuery();
        OdbcCommand broadcastSelect = new OdbcCommand("select * from exchange where inp_date=chg_date and LEFT(filename,12)='" + ip_addr + "' and status='1' and type='UPDATE'", cloud);
        OdbcDataReader DbReader = broadcastSelect.ExecuteReader();
        int fCount = DbReader.FieldCount;
        byte[] outByte = new byte[500]; 
        while (DbReader.Read())
        {
           String type = DbReader.GetString(0);
           String filename = DbReader.GetString(1);
           String data = DbReader.GetBytes(1);
           OdbcCommand broadcastCopy = new OdbcCommand("INSERT INTO exchange(type,filename) VALUES('"+type+"','"+filename+"'"+data+")", local);
           broadcastCopy.ExecuteNonQuery();


        }
        itouchcloud.Close();
        itouchlocal.Close();
        Console.Write("Broadcast Check Completed \n");

    }

Basically the cloud db is queried and may return multiple results, i want to process each record returned and copy it to the local DB. 基本上查询云数据库并可能返回多个结果,我想处理返回的每个记录并将其复制到本地数据库。 i have looked around and cant seem to really get a decent solution, i can do this simply in Visual FoxPro 9 so im guessing there is a similar solution. 我环顾四周,似乎无法真正得到一个不错的解决方案,我可以在Visual FoxPro 9中简单地做到这一点,所以我想还有一个类似的解决方案。

any help appreciated :) 任何帮助表示赞赏:)

The first part of the answer is, avoid dynamic SQL if you can. 答案的第一部分是,如果可以,请避免使用动态SQL。 You're using "... VALUES ('"+type+"','"+filename+"'"+data+")" when you should be using "... VALUES (?, ?, ?)". 当您应该使用“ ... VALUES(?,?,?)”时,您正在使用“ ... VALUES('“ + type +”','“ +文件名+”'“ +数据+”)“。

Then, add the parameters using, for instance, 然后,例如使用

// sample: the name of the parameter (here @Type) can be anything, and the type and length should match your schema.
broadcastCommand.Parameters.Add("@Type", OleDbType.VarChar, 10).Value = type; 

The question marks will be replaced by the parameters in the order you specify them, so you should add type, then filename, then data, in that order. 问号将按您指定的顺序替换为参数,因此您应按该顺序依次添加类型,文件名和数据。

Now, the value you specify should ALSO correspond to the type of field you are inserting into. 现在,您指定的值还应该与您要插入的字段类型相对应。 So instead of String, String, String, you might want your variables to be of type String, String, byte[]. 因此,您可能希望变量不是String,String,String,而是String,String,byte []类型。

There are about a million reasons not to construct your queries dynamically, so I would recommend studying up on how to use the Parameters collection on your OdbcCommand. 有大约一百万个理由不动态构建查询,因此,我建议您研究如何在OdbcCommand上使用Parameters集合。 Start here . 这里开始。

UPDATE 更新

In general you can get DataReader values simply by using the indexer [], without needing to go through the GetXXX() methods. 通常,您只需使用索引器[]就可以获取DataReader值,而无需遍历GetXXX()方法。 For byte arrays, that's usually simpler, because you don't need to know or try to guess the length beforehand. 对于字节数组,这通常更简单,因为您无需事先知道或尝试猜测其长度。

You can convert your code to use indexers this way: 您可以通过以下方式将代码转换为使用索引器:

String type = (string)DbReader[0];
String filename = (string)DbReader[1];
byte[] data = (byte[])DbReader[2];

Note that your GetBytes() call originally had a 1 in there, but I assume you aren't trying to get the bytes of the filename field. 请注意,您的GetBytes()调用最初在其中具有1,但是我假设您没有尝试获取文件名字段的字节。 So, if your byte[] data is in another field, use that instead. 因此,如果您的byte[]数据在另一个字段中,请改用该字段。 Be aware, however, that you could also use the string field names just as easily (and it might be clearer the next time you need to read the code): 但是请注意,您也可以轻松地使用字符串字段名称(下次需要阅读代码时可能会更清楚):

String type = (string)DbReader["type"]; // replace with whatever your fields are actually called
String filename = (string)DbReader["filename"];
byte[] data = (byte[])DbReader["data"];

On the off-chance you had filename and data both using the same field because data isn't actually in the database and instead you want to take the filename and read that filesystem object in as your data for the insert query, you'll need to use a different method. 有时,您使用相同的字段来使用filenamedata ,因为data实际上不在数据库中,而是您想要获取文件名并读取该文件系统对象作为插入查询的数据,您将需要使用不同的方法。

byte[] data = System.IO.File.ReadAllBytes(filename); // requires .NET 2.0+

Either way you fill your variables, insert them with a parameterized query as explained above. 无论哪种方式填充变量,都可以使用上述参数化查询插入变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM