基本上我有一个查看两个表的服务 - 一个驻留在远程服务器上,另一个驻留在本地。我正在尝试编写一个程序,它将从远程服务器中选择任何所需的文件并在本地复制它们。我可以使用标准记录,但我如何处理c#中的blob - 我刚刚开始使用该语言,所以要温和
我所拥有的片段在下面
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");
}
基本上,查询云数据库并可能返回多个结果,我想处理返回的每个记录并将其复制到本地数据库。 我环顾四周,似乎无法得到一个像样的解决方案,我只能在Visual FoxPro 9中这样做,所以我猜测有一个类似的解决方案。
任何帮助表示赞赏:)
答案 0 :(得分:1)
答案的第一部分是,如果可以,请避免使用动态SQL。您正在使用“... VALUES('”+ type +“','”+ filename +“'”+ data +“)”当您应该使用“... VALUES(?,?,?)”。
然后,使用例如
添加参数// 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;
问号将被您指定的顺序中的参数替换,因此您应该按顺序添加类型,然后是文件名,然后是数据。
现在,您指定的值应该与您要插入的字段类型相对应。因此,您可能希望变量的类型为String,String,byte []。而不是String,String,String。
有大约一百万个理由不动态构建您的查询,因此我建议您研究如何在OdbcCommand上使用Parameters集合。开始here。
<强>更新强>
通常,只需使用indexer []即可获得DataReader
值,而无需通过GetXXX()
方法。对于字节数组,这通常更简单,因为您不需要事先知道或尝试猜测长度。
您可以通过以下方式将代码转换为使用索引器:
String type = (string)DbReader[0];
String filename = (string)DbReader[1];
byte[] data = (byte[])DbReader[2];
请注意,您的GetBytes()
调用最初有一个1,但我假设您没有尝试获取文件名字段的字节。因此,如果您的byte[]
数据位于其他字段中,请使用该字段。但是,请注意,您也可以轻松地使用字符串字段名称(下次需要阅读代码时可能会更清楚):
String type = (string)DbReader["type"]; // replace with whatever your fields are actually called
String filename = (string)DbReader["filename"];
byte[] data = (byte[])DbReader["data"];
关于您有filename
和data
使用相同字段的可能性,因为data
实际上并不在数据库中,而是您想要获取文件名并读取文件系统对象作为插入查询的数据,您需要使用不同的方法。
byte[] data = System.IO.File.ReadAllBytes(filename); // requires .NET 2.0+
无论哪种方式填充变量,请使用参数化查询插入它们,如上所述。