Hola Luis
Cómo te conteste anteriormente, yo hago esto a través de vistas remotas, es decir tengo una capa adicional de vistas remotas entre la capa intermedia y la base de datos. Si quiero incertar una línea, la incerto en la vista remota, el momento que haces table updated de la vista remota se actualiza la tabla de SQL Server, el momento que se actualiza, también genera el valor Identity, este valor aparece en la vista remota cuando haces requery y lo puedes leer como se lee cualquier campo. La ventaja de utilizar la vista remota en la capa intermedia es que te acelera mucho el desarrollo, y es muy fácil convertir cualquier cursor en formato XML para enviarlo a la capa superior. Por ejemplo te envio un código de como creo un registro desde mi capa intermedia, que es un COM+ registrado como Webservice.
PROCEDURE create_box (lcXML AS STRING ) AS STRING
LOCAL m.lcXMLRecive,m.lcUnico
lcMessage=' '
m.lcXMLRecive=lcXML
m.lcUnico=' '
TRY
SELECT 0
USE vr_packings_boxes
=CURSORSETPROP("Buffering", 5, "vr_packings_boxes")
XMLTOCURSOR(lcXMLRecive,"c_box",0)
SELECT c_box
DO CASE
CASE EMPTY(NVL(qty,' '))
THROW 'Cantidad no puede ser 0 '
CASE EMPTY(NVL(box_uq,' '))
THROW 'Tiene que escoger un tipo de caja '
CASE EMPTY(NVL(packing_uq,' '))
THROW 'Tiene que escoger un packing '
ENDCASE
SELECT vr_packings_boxes
APPEND FROM DBF('c_box')
REPLACE vr_packings_boxes.boxdate WITH DATETIME()
REPLACE vr_packings_boxes.TIMESTAMP WITH DATETIME()
BEGIN TRANSACTION
IF NOT TABLEUPDATE(.T.)
IF laError[1]=1526
THROW laError[3]
ELSE
THROW laError[2]
ENDIF
ENDIF
END TRANSACTION
lcMessage='Caja ingresada correctamente'
CATCH TO loException
IF TXNLEVEL() > 0
ROLLBACK
ENDIF
IF loException.ErrorNo=2071
lcMessage='Error:'+' '+loException.UserValue
ELSE
lcMessage='Error:'+' '+loException.MESSAGE
ENDIF
FINALLY
USE IN SELECT ('vr_packings_boxes')
USE IN SELECT ('c_box')
ENDTRY
RETURN lcMessage
ENDPROC
Carlos A. Miranda
E.I.S.lnc
President