If it's possible upgrade to VFP9. VFP9 has cursoradapter class which makes it much easier to deal with multiple data sources, use stored procedures as sources etc.
In VFP6 and later you can use Remote View and SPT. Remote Views are easier for the developer because VFP handles most the tasks for you, however you have less control upon it. SPT's are a little harder but lets you take the control and said to be faster.
From VFP side it's not complex. However you need to be familiar with SQL server and Oracle IMHO. VFP's own F1 help give a lot of information about it. Here are quick starters:
-Connect with a connection string
lnHandle = SQLStringConnect( "Driver=SQL server;Server=(local);Trusted_connection=yes;Database=pubs")
-Use parametric queires rather than hardcoding
* Do not prefer this
lcLastName = 'Karson'
SQLExec( m.lnHandle, "select * from authors where LName = '"+m.lcLastName+"'", "myCursor")
* But this
lcLastName = 'Karson'
SQLExec( m.lnHandle, "select * from authors where LName = m.lcLastName", "myCursor")
Parametric approach especially solves problems with passing correct parameters with other types such as date/datetimes.
-Try to use [ ] around your table and field names (designer doesn't do this for you unfortunately). It makes backend understand that you're not referring to a keyword but a field/table when you used a table/fieldname that's same as a keyword. ie:
select [desc] from [values]
However generally it's a bad idea to use keywords as field/tablenames and thus you might not need this at all (check a recent post related to this).
I think following code shows how to use SQL server via SPT in a nutshell for a starter:
Clear All
csql = "SELECT EmployeeID, LastName, FirstName," + ;
"Title, TitleOfCourtesy, BirthDate," + ;
"Hiredate, Address, City, Region," + ;
"PostalCode, Country, HomePhone," + ;
"Extension, Photo, Notes," + ;
"ReportsTo, PhotoPath FROM dbo.Employees"
lnHandle=Sqlstringconnect('DRIVER=SQL Server;'+;
'SERVER=(local);DATABASE=Northwind;Trusted_Connection=Yes')
SQLExec(lnHandle,csql,'v_emp') && v_emp has data now but not updatable
* You can browse and change data but it wouldn't update
* at backend unless you prepare it to be updatable
* Make v_emp updatable
CursorSetProp('KeyFieldList','Employeeid','v_emp')
CursorSetProp('WhereType',1,'v_emp')
CursorSetProp('Tables','employees','v_emp')
* Specify fields' mapping
* Mapping is in pairs
* On left there is local field name and on right
* tablename.Fieldname on backend.
* employeeID employees.employeeid
* employeeID is local field name mapping to
* employees.employeeid on backend
* In other words if set to be updatable
* v_emp.employeeID would update employees.employeeID at backend
* Note: Include key field in this list even though you might not
* want it to be updatable
TEXT to m.lcUpdateNameList noshow
employeeID employees.employeeid,
Lastname employees.Lastname,
Firstname employees.FirstName,
Title employees.Title,
TitleOfCourtesy employees.TitleOfCourtesy,
BirthDate employees.BirthDate,
Hiredate employees.Hiredate,
Address employees.Address,
City employees.City,
Region employees.Region,
PostalCode employees.PostalCode,
Extension employees.Extension,
Notes employees.Notes,
ReportsTo employees.ReportsTo,
PhotoPath employees.PhotoPath
ENDTEXT
CursorSetProp("UpdateNameList", ;
Chrtran(m.lcUpdateNameList,Chr(13)+Chr(10),''),'V_emp')
* Specify fields that could be updated
CursorSetProp('UpdatableFieldList',;
"LastName, FirstName," + ;
"Title, TitleOfCourtesy, BirthDate," + ;
"Hiredate, Address, City, Region," + ;
"PostalCode, Country, HomePhone," + ;
"Extension, Notes," + ;
"ReportsTo, PhotoPath",'v_emp')
CursorSetProp('SendUpdates',.T.,'v_emp')
* We want all updates to occur in a batch
* so setting to table level buffering
CursorSetProp('Buffering',5,'v_emp')
Browse Title 'Editable fields are all except Id and Photo'
* Update backend with changes
If !Tableupdate(2,.T.,'v_emp')
Aerror(arrWhy)
Display Memo Like arrWhy
EndIf
* Requery data from backend to see if it has been really updated
SQLExec(lnHandle,'select * from dbo.employees','afterupdate')
SQLDisconnect(lnHandle)
Select afterupdate
Browse
For a starter to SQL server, easiest is Remote Views IMHO. Create a connection in a database (you can use connectionstring as in SPT sample). Using that connection create remote views in designer (do not forget to mark 'Send Updates' if you'd want updates to persist). Those views are just like any other local table/view from your POV (with default buffering of 3 - you can change buffering to say 5 and views are always buffered).
These should be enough to wet your appetite. You asked for articles and such but I don't know what to suggest and where:) I'd just start in a test folder and ask specific questions when something doesn't seem to work the way it should. Aerror() would be your best friend in that case. IMHO it's an illusion that you could write the same codebase for both backends. Both have extensions of their own to ANSI SQL and you'd want to leverage them. However you could keep these in classes and call one or the other depending on the provider.
Good luck and don't be afraid, at first it sounds to be complex and you have many hurdles but it is really a fun once you start. Do not forget to download SSE (SQL server 2005 express) with its management studio (alternatively you might get SQL server developer edition for 49$). They have tools that would let you write and test needed SQL query blocks.