在使用参数化查询插入之前查看foxpro数据库中存在的记录
问题描述:
我已经创建了一个程序,用于从excel电子表格中提取数据并将其推送到foxpro数据库。但是,我遇到了出现重复客户端记录的问题。在使用参数化查询插入之前查看foxpro数据库中存在的记录
这是由于一个客户端与多个其他记录相关联。
我需要知道如何在写入之前检查数据库以查看某个特定记录是否存在,但是我正在绘制一个完整的空白。
我的代码(这个特殊类),因为它代表读起来就像下面:
namespace PropertyImport
{
public class Landlord
{
public void Import()
{
int IDCOUNT = 0;
using (var exportConnection = new OleDbConnection(connectionString: Settings.ImportFrom))
using (var importConnection = new OleDbConnection(connectionString: Settings.ImportTo))
using (OleDbCommand exportCommand = new OleDbCommand(@"SELECT
[clcodel salute],
[clcodel fname],
[clcodel sname]
from [export_test$]"
, exportConnection))
using (OleDbCommand importCommand = new OleDbCommand(@"INSERT INTO CLIENT
(CLCODE,CLCODEDESC,CLCLASS,
FNAME,MNAME,SNAME
)
VALUES
(?,?,?,?,?,?,?,?)",
importConnection))
{
OleDbDataReader exportReader;
//
importCommand.Parameters.AddWithValue("CLCODE", "");
importCommand.Parameters.AddWithValue("CLCODEDESC", "");
//importCommand.Parameters.AddWithValue("CLCLASS", "");
//importCommand.Parameters.AddWithValue("NEGOTIATOR", "");
//importCommand.Parameters.AddWithValue("TITLE", "");
importCommand.Parameters.AddWithValue("FNAME", "");
importCommand.Parameters.AddWithValue("MNAME", "");
importCommand.Parameters.AddWithValue("SNAME", "");
// Open connections to excel sheet and foxpro database
exportConnection.Open();
importConnection.Open();
Console.WriteLine("Visual Foxpro connection open");
Console.WriteLine("Writing to table");
Console.WriteLine("...");
int nLoopCount = 0;
string space = " ";
// Initiate the reader to excel
exportReader = exportCommand.ExecuteReader();
// Start reading
while (exportReader != null && exportReader.Read())
{
//Set parameter values whilst reading from excel
string LandTitle = exportReader.IsDBNull(0)
? string.Empty
: Convert.ToString(exportReader.GetValue(0)).Trim();
string LandFname = exportReader.IsDBNull(1)
? string.Empty
: Convert.ToString(exportReader.GetValue(1)).Trim();
string LandSname = exportReader.IsDBNull(2)
? string.Empty
: Convert.ToString(exportReader.GetValue(2));
string CLCODE = string.Concat(LandFname, space, LandSname, " (P)").Trim();
Console.WriteLine("Working on record {0}, {1}", IDCOUNT, CLCODE);
importCommand.Parameters["CLCODE"].Value = string.Concat(LandFname, space, LandSname, " (P)").Trim();
importCommand.Parameters["CLCODEDESC"].Value = string.Concat(LandTitle, space, LandFname, space, LandSname).Trim();
importCommand.Parameters["TITLE"].Value = LandTitle.Trim();
importCommand.Parameters["FNAME"].Value = LandFname.Trim();
importCommand.Parameters["SNAME"].Value = LandSname.Trim();
try
{
importCommand.ExecuteNonQuery();
}
catch (Exception e)
{
Console.Write("Error Writing to database");
Console.Write(e);
Console.ReadKey();
}
// We must close and re-open the connection after a certain number of records or the OLEDB FoxPro SQL will eventually fail
if (nLoopCount % 100 == 0)
{
importConnection.Close();
importConnection.Open();
}
}
// done
exportConnection.Close();
importConnection.Close();
Console.WriteLine("Landlord Import Complete!");
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
if (Settings.ImportPropertyPause) Console.ReadKey();
}
}
}
}
我想要做的事,如:
if (CLCODE exists)
{
Do not not create record
}
else
{
create record
}
答
约书亚, 你使它变得不必要的复杂。在多用户环境中,您将遇到“检查并插入(如果不存在)”逻辑的问题。如果您认为这不是问题,那么可以执行ExecuteScalar()来检查具有该代码的行数。如果0则不存在。
如果你想这样做,那么宁愿使用Linq。对于Linq,它只是一个:
bool exists = vfpdb.Clients.Any(c=>c.ClCode == "codetocheck");
看看它是否存在与否。
无论如何,有一个更简单的方法,它是一个真正的伎俩,但一个工程。假设你已经在client.dbf “d:\后院\ TEMP” 和 “d:\ TEMP \ myclients.xlsx” 文件(仅用于演示目的,这就是我选择):
void Main()
{
string vfpInsert = @"Insert Into client
(CLCODE,CLCODEDESC,CLCLASS,FNAME,MNAME,SNAME)
SELECT CLCODE,CLCODEDESC,CLCLASS,FNAME,MNAME,SNAME
from (Iif(Xmltocursor(?,'xlData') > 0, 'xlData','')) xl
where Not Exists
(Select * From client c2 Where c2.CLCODE == xl.CLCODE)";
var xml = GetExcelData();
using (OleDbConnection con=new OleDbConnection(@"provider=VFPOLEDB;Data Source="[email protected]"d:\backyard\temp"))
using (OleDbCommand cmd = new OleDbCommand(vfpInsert,con))
{
cmd.Parameters.Add("xldata", OleDbType.VarChar).Value = xml;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
private string GetExcelData()
{
string dataSource = @"D:\temp\myclients.xlsx";
DataTable t = new DataTable("Clients");
using (OleDbConnection con = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;" +
string.Format("Data Source={0};", dataSource) +
"Extended Properties=\"Excel 12.0;HDR=Yes\""))
using (OleDbCommand cmd = new OleDbCommand("Select * from [clients$]", con))
{
con.Open();
t.Load(cmd.ExecuteReader());
con.Close();
}
using (MemoryStream ms = new MemoryStream())
using (var xmlwriter = XmlTextWriter.Create(ms))
{
t.WriteXml(xmlwriter, XmlWriteMode.WriteSchema);
xmlwriter.Flush();
xmlwriter.Close();
ms.Position = 0;
using (StreamReader streamreader = new StreamReader(ms))
{
return streamreader.ReadToEnd();
}
}
}
编辑:这里是解释代码的作用:
- 从excel中获取数据作为DataTable并转换为XML字符串。
- 将XML作为参数传递给VFP插入命令。
- 插入命令,将XML扩展为一个游标(几乎总是在内存中),然后选择那些已经不存在的(使用ClCode)并一次性插入到客户端表中。
只需对该项目执行SELECT操作 - 如果返回结果,则存在,如果不存在,则不存在。 – Tim
有没有一个* single *字段值可以在目标表中检查以查看该记录是否已经存在?如果是这样,做一个“选择*从表where字段='等等'”,看看它是否找到记录。如果需要*多个*字段值来创建检查现有记录所需的唯一性,那么只需包含所有字段名称及其值,然后检查是否存在以下记录:“Select * from Table where field1 ='blah1'和field2 ='blah2'“ – MattSlay
欢呼声,我想我现在正在做些什么,如果我解决了它,我会发布答案 –