Как я могу записывать ошибки FoxPro в текстовый файл?

TL; DR Как я могу вводить команды для надежной регистрации ошибок FoxPro в текстовом файле при выполнении команд INSERT и APPEND FROM через ODBC / OLE DB?

Я пытаюсь записать обработанные данные обратно в базу данных FoxPro. Фактическое соединение с .dbf осуществляется службой, написанной моим коллегой - я предполагаю, что она использует ODBC или OLE DB. Я указываю только путь к DBF и строки запроса для запуска. Однако я сталкиваюсь с некоторыми проблемами с FoxPro, и, к сожалению, весь мой опыт связан с SQL Server и друзьями, а не с FoxPro.

Моя проблема в том, что простые инструкции, такие как INSERT ниже, отлично работают в Visual Fp, но не проходят через службу. Я не получаю много полезной информации об ошибке, кроме «Произошла ошибка».

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 еще несколькими командами для перенаправления информации об ошибках в текстовый файл.


person Grubl3r    schedule 03.09.2014    source источник


Ответы (2)


Вы упомянули сервис и OleDb / ODBC. С каким языком ВЫ подключаетесь ... C # .net, VB.net, что-то еще?

Однако, заметив одну вещь ... если вы выполняете вставку в таблицу адресов, а столбец «AddressID» является столбцом с автоинкрементом, вы НЕ МОЖЕТЕ предоставить идентификатор для вставки, который полностью находится под контролем VFP. , и, возможно, из-за этого вы ошибаетесь, или идентификатор уже существует.

Вместо этого вам может потребоваться инструкция UPDATE, например

UPDATE ADDRESSES set firstname='Test', lastname = 'Testerson'
   where addressid = 55

Посмотрев на свой ответ и добавленный код, он МОЖЕТ БЫТЬ таким же простым, как подключение вашего устройства. ТИПИЧНО для DBF-файлов подключение осуществляется к ПУТИ, в котором находятся файлы DBF, а затем после подключения вы можете делать что угодно с dbfs в пределах этого пути. Итак, я бы начал с изменения

 dataService.AppDataPath = @"D:\foxpro\test\DATA\addresses.dbf";

to

 dataService.AppDataPath = @"D:\foxpro\test\DATA\";

Тогда вашей команде не потребуется явная ссылка на database.dbc. Когда он открывается, он должен автоматически открывать соответствующий контейнер базы данных на случай, если какие-либо такие триггеры могут быть присоединены.

const string commandText = "INSERT INTO [address book!addresses] (addressid, firstname, lastname) VALUES (90, [Iam], [Error])";

to

const string commandText = "INSERT INTO [addresses] (addressid, firstname, lastname) VALUES (90, [Iam], [Error])";

Итак, у вас это похоже на то, что вы пытались сделать следующее

insert into D:\foxpro\test\DATA\addresses.dbf\address book!addresses
person DRapp    schedule 03.09.2014
comment
Мое приложение написано на C #. Я знаю о полях с автоматическим приращением. Это просто примерная таблица без автоматического увеличения. Я не использую адресную таблицу в разрабатываемом решении. - person Grubl3r; 03.09.2014
comment
@ Grubl3r, можете ли вы действительно показать, что у вас есть в C #, чтобы лучше адресовать и моделировать. Я тоже работаю с VFP и C # и могу попытаться сделать и предложить вам более близкую к отслеживаемой ошибке .. - person DRapp; 03.09.2014
comment
Спасибо, я добавил это к своему вопросу. Боюсь, это довольно специфично для сайта .. Кстати, я попробовал другой способ, который действительно работал. Я сделал собственное подключение OleDB к базе данных FoxPro, и я мог без проблем записывать данные - даже поля Memo с более чем 256 символами и новой строкой. - person Grubl3r; 03.09.2014
comment
@ Grubl3r, пересмотрел мой ответ, и я думаю, что это простая проблема с путями. - person DRapp; 03.09.2014
comment
Большое спасибо за ваши усилия. К сожалению, у меня все еще та же проблема ... Похоже, мне нужно попросить моего коллегу поближе взглянуть на службу данных или использовать мое собственное соединение OleDB. - person Grubl3r; 03.09.2014
comment
@ Grubl3r, это может быть, и я много писал об использовании VFP OleDB, и НАСТОЯТЕЛЬНО предлагаю вам параметризовать все свои запросы. Должно быть очень легко штрафовать через [OleDb] [VFP] в поиске - person DRapp; 03.09.2014

Вы можете попробовать создать набор команд VFP и, возможно, использовать EXECSCRIPT.

So in 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;

Возможно, вам придется что-то сделать, чтобы избежать обратной косой черты. Затем выполните на C #, установив для команды OleDB значение myCommand и выполнив ее с помощью ExectuteNonQuery ().

Сказав все это, при выполнении на C #, если вы завершите попытку ... catch и поймаете тип OleDbException, разве InnerException этого не детализирует, в чем проблема на стороне VFP?

person Alan B    schedule 03.09.2014
comment
Спасибо я попробую это - person Grubl3r; 03.09.2014