I am getting the 'function is not implemented' error when attempting to do an insert into a FoxPro table that has an insert trigger related to it within the table setup GUI. Using vs2012, I created a table adapter within a dataset. I added the update statement shown below. The code within my C# project that performs the insert/update is also listed below. I can get a successful insert/update if I remove the associated triggers from the FoxPro table. With the triggers, inserts and updates throw the 'function is not implemented' error. Select's work fine.
Please help
The utacc FoxPro table has triggers setup to insert, update and delete related SQL Server tables. Insert trigger at the bottom of post.
VS 2012 table adapter insert command
INSERT INTO utacc
(fcmodid, fcuname, fccompid, fcacclvl, fcscope)
VALUES (?, ?, ?, ?, ?)
C# code to perform insert/update via table adapter
using (var ta = new DataSet1TableAdapters.utaccTableAdapter())
{
foreach (var u in lUsers.GetList().Where(x => x.selected))
{
foreach (var screen in lScreen.GetList().Where(x => x.selected))
{
if (ta.GetData()
.Any(x => x.fccompid == _fccompid
&& x.fcmodid.Trim() == screen.fcmodid.Trim()
&& x.fcuname.Trim() == u.fcuname.Trim()))
ta.Update(perm, screen.fcmodid, _fccompid, u.fcuname);
else
ta.Insert(screen.fcmodid, u.fcuname, _fccompid, perm, "P");
}
}
}
These triggers are inserts to SQL server tables.
Here is the FoxPro trigger
PROCEDURE M2MTrig_UTACCInsert
LOCAL Cntr, ErrCode, ConStr, ConnName, ConnHandle, RV, ErrHndlr
SET DATA TO UTIL
ErrHndlr = ON("ERROR")
IF EMPTY(UTACC.FCUNAME)AND EMPTY(UTACC.FCMODID)AND EMPTY(UTACC.FCCOMPID ) THEN
RETURN .T.
ENDIF
ErrCode = 0
ON ERROR ErrCode = M2MTrig_ERR(ERROR(),MESSAGE(),ErrHndlr)
FOR Cntr = 1 TO 99
ConnName = "SystemDBConn" + ALLTRIM(STR(Cntr))
TRY
ConStr = DBGETPROP(ConnName,"CONNECTION","ConnectString")
CATCH TO oEx
ErrCode = oEx.ErrorNo
ENDTRY
IF ErrCode = 1562 THEN
EXIT
ENDIF
IF ErrCode <> 0 THEN
ON ERROR &ErrHndlr.
RETURN .F.
ENDIF
ConnHandle = SQLCONNECT(ConnName)
IF ErrCode <> 0 THEN
RETURN .F.
ENDIF
IF ConnHandle < 1 THEN
M2MTrig_ERR(-1, "Unable to connect using " + ConnName, ErrHndlr)
RETURN .F.
ENDIF
IF ErrCode <> 0 THEN
SQLDISCONNECT(ConnHandle)
RETURN .F.
ENDIF
Select UTACC
RV = M2MTrig_ExecSQL("EXEC UpdUTACC " + XC(FCACCLVL)+ ", "+ XC(FCCOMPID)+ ", "+ XC(FCMODID)+ ", "+ XC(FCSCOPE)+ ", "+ XC(FCUNAME), .T., ConnHandle, ErrHndlr)
IF ErrCode <> 0 THEN
SQLDISCONNECT(ConnHandle)
RETURN .F.
ENDIF
SQLDISCONNECT(ConnHandle)
IF ErrCode <> 0 THEN
RETURN .F.
ENDIF
IF RV < 0 THEN
RETURN .F.
ENDIF
IF RV < 1 THEN
M2MTrig_ERR(-1, "Could not update System database", ErrHndlr)
RETURN .F.
ENDIF
NEXT Cntr
ON ERROR &ErrHndlr.
RETURN .T.
The Fox engine in the OLEDB provider supports only a subset of Fox commands and functions. MSDN has lists of supported language elements here, and unsupported ones here.
The remote SQL functions SQLCONNECT() etc. - are on the list of prohibited items. The error handler might use forbidden stuff as well, like MessageBox(), WAIT WINDOW, SET MESSAGE or ?.
Apart from that the code seems to have lots more problems. Starting with the fact that it ignores all guidelines for safe and clean coding, like qualifying rvalue access to memory variables with m. or m-> to avoid nasty surprises with field names in new tables, or the rules regarding what (not) to do in trigger code.
Better scrap the code completely and find a simpler, cleaner solution.
P.S.: one way of using the existing infrastructure would be to control the Fox side not via OLEDB but via COM, i.e. building a little COM server exe. That could be as simple as sending commands to Fox via DoCmd(), or as complicated as a full blown COM object. In VFP9 it is even possible to return arrays and row sets from a COM method, so the interface could be as rich as you like.
P.P.S.: if the data resides in an SQL Server database, then why are you talking to Fox?