TL; DR 当通过ODBC / OLE DB运行INSERT和APPEND FROM命令时,如何发出命令以将FoxPro错误可靠地记录到纯文本文件?
我正在尝试将一些按摩数据写回FoxPro数据库。与.dbf的实际连接是由同事编写的服务完成的 - 我假设它使用ODBC或OLE DB。我只提供DBF的路径和要运行的查询字符串。但是我遇到了FoxPro的一些问题,不幸的是我所有的经验都在于SQL Server和朋友 - 而不是FoxPro。
我的问题是像下面的INSERT这样的简单语句在Visual Fp中运行良好,但是无法通过服务。除了&#34之外,我没有得到更多有用的错误信息;发生错误"。
INSERT INTO "ADDRESSES" (addressid, firstname, lastname) ;
VALUES (55, 'Test', 'Testerson')
为了让自己的生活更轻松,我尝试发出更多命令,使FoxPro将所有错误信息记录到文本文件中。同样,这适用于Visual FoxPro - 但是无提示失败并且在通过服务运行时不输出文件。我确保目录权限正确无误:
LOCAL lcOldOnError
lcOldOnError = ON("ERROR") && save old error handler
SET PROCEDURE TO [D:\foxpro\errhandler.prg]
ON ERROR DO ErrHandler WITH ERROR(), MESSAGE()
&& This insert causes a duplicate primary key error:
INSERT INTO "address book!addresses" (addressid, firstname, lastname) ;
VALUES (1, 'MyName', 'IsError')
ON ERROR &lcOldOnError && restore old error handler
外部PRG errorhandler.prg看起来像这样。它适用于Visual FoxPro:
PROCEDURE ErrHandler
PARAMETERS gnError, gcMsg
LOCAL aErrInfo[1]
AERROR(aErrInfo)
cErrMsg = LTRIM(STR(aErrInfo[1])) + CHR(13) + CHR(10) + aErrInfo[2] + CHR(13) + CHR(10) + aErrInfo[3] + CHR(13) + CHR(10)
lnFileHandle = FCREATE ([D:\foxpro\errorlog.txt])
FPUTS(lnFileHandle, cErrMsg)
FCLOSE(lnFileHandle)
ENDPROC
任何提示或提示都将不胜感激,谢谢。
@DRapp,这是我的C#代码。我担心这是非常具体的网站,所以不知道它是否有帮助:
static void Main(string[] args)
{
// Test - not production code!
var errormessage = string.Empty;
DataSvc dataService = new DataSvc();
dataService.AppDataPath = @"D:\foxpro\test\DATA\addresses.dbf";
const string commandText = "INSERT INTO [address book!addresses] (addressid, firstname, lastname) VALUES (90, [Iam], [Error])";
var returnValue = dataService.ExecuteCommands(commandText, ref errormessage);
Console.WriteLine("\nResult:{0}\nErrorMsg: {1}", returnValue, errormessage);
Console.ReadLine();
}
我只收到那种错误"发生错误"来自DataSvc,这就是为什么我想用一些更多的命令来装饰INSERT语句,以便将错误信息重新路由到文本文件。
答案 0 :(得分:2)
您提到了服务和OleDb / ODBC。你用什么语言连接.. C#.net,VB.net,还有什么?
然而,注意到一件事......如果您正在对地址表进行插入,以及列"地址ID"是自动增量列的,你不能提供要插入的ID,完全受VFP的控制,并且可能因此而错误输出,或者ID已经存在。
您可能需要UPDATE语句,例如
UPDATE ADDRESSES set firstname='Test', lastname = 'Testerson'
where addressid = 55
通过查看您的答案并添加代码,它可能与您的设备连接一样简单。通常对于DBF的东西,连接到找到DBF文件的PATH,然后一旦连接,你可以对该路径中的dbfs做任何事情。所以我首先要改变
dataService.AppDataPath = @"D:\foxpro\test\DATA\addresses.dbf";
到
dataService.AppDataPath = @"D:\foxpro\test\DATA\";
然后,您的命令不应该需要显式的database.dbc引用。当它被打开时,它应该自动打开相应的数据库容器,以防任何此类触发器可能被附加。
const string commandText = "INSERT INTO [address book!addresses] (addressid, firstname, lastname) VALUES (90, [Iam], [Error])";
到
const string commandText = "INSERT INTO [addresses] (addressid, firstname, lastname) VALUES (90, [Iam], [Error])";
所以,你拥有它的方式就像你试图做以下
insert into D:\foxpro\test\DATA\addresses.dbf\address book!addresses
答案 1 :(得分:1)
您可以尝试构建一组VFP命令并使用EXECSCRIPT。
所以在C#:
var myCommand = @"try" + Environment.NewLine;
myCommand += @" open database mydata" + Environment.NewLine;
myCommand += @" update addresses set firstname='test' where addressid = 55' + Environment.NewLine;
myCommand += @"catch to loException" + Environment.NewLine;
myCommand += @" set textmerge on noshow" + Environment.NewLine;
myCommand += @" set textmerge to c:\temp\vfp.txt" + Environment.NewLine;
myCommand += @" \<<loException.Message>>" + Environment.NewLine;
myCommand += @" set textmerge off" + Environment.NewLine;
myCommand += @" set textmerge to" + Environment.NewLine;
myCommand += @"finally" + Environment.NewLine;
myCommand += @" close all" + Environment.NewLine;
myCommand += @"endtry" + Environment.NewLine;
你可能需要做一些逃避反斜杠的事情。然后通过将OleDB命令设置为myCommand,并使用ExectuteNonQuery()执行,在C#中执行。
说完所有这些,当在C#中执行时,如果你包装一个try ... catch,并且捕获一个OleDbException类型,那么InnerException会不会详细说明VFP端的问题是什么?