Microsoft Visual FoxPro
FoxPro
FoxPro はテキストベースの手続き型プログラミング言語でありDBMSである。当初 Fox Software が開発販売し、後にマイクロソフトに引き継がれた。対応プラットフォームとしては、MS-DOS、Microsoft Windows、Macintosh、UNIX があった。
FoxPro は一般に「xBase言語」と呼ばれる言語の一種であり、その文法はdBASEプログラミング言語に基づいている。xBase言語とされるものには他に Clipper がある。xBase言語の初期の歴史については、dBASEを参照。
FoxProはデータベース管理システムだが、表間の関係をサポートしていない。つまり、関係データベースではないし、トランザクション処理能力もない。
最終版はFoxPro 2.6で、それ以降はVisual FoxProに引き継がれた。既に販売終了していてマイクロソフトもサポートしていないが、FoxProユーザーのコミュニティは現在も活動中である。FoxPro 2.6 for UNIX (FPU26)はIntel Binary Compatibility Standard (ibcs2) サポートライブラリを使ってLinuxやFreeBSDにインストール可能である。
FoxPro 2では、"Rushmore" という最適化エンジンが搭載され、データ検索や更新が高速化されている。Rushmoreは全てのデータ関係文を調べてフィルタ式を探し出す。フィルタ式が使われると、同じ式にマッチするインデックスを探す。また、FoxPro 2は当初WatCOM C++で書かれており、これには自前のメモリ拡張機能（当時の最新技術）があった。FoxPro 2は拡張メモリにアクセスでき、DOSが管理可能なほぼ全てのメモリを使うことができた。HIMEM.SYSがロードされていない場合、FoxPro 2は自前の拡張機構を起動するようになっていた。
Visual FoxPro
Visual FoxProとしての最初のバージョンは3.0で、対応プラットフォームはMacintoshとWindowsのみに限定され、さらに後のバージョンではWindowsのみとなった。現在のVisual FoxProはCOMベースであり、マイクロソフトはMicrosoft .NET版を開発する予定はないとしている。
Visual FoxPro（VFPと略記されることが多い）は関係データベースエンジンと密に結合されている。この関係データベースはFoxProのxBase機能を拡張し、SQLクエリ/データ操作を追加サポートしている。多くのデータベース管理システムとは異なり、Visual FoxProは完全な動的プログラミング言語であり、追加の汎用プログラミング環境を必要としない。ファットクライアントのアプリケーション開発だけでなく、ミドルウェアやウェブアプリケーションも開発可能である。
最近の動向
2002年末、Visual FoxProをWineを使って Linuxで利用可能であることが示された。2003年、これを受けてマイクロソフトはWindows以外の上でFoxProを動作させることはライセンス契約に違反していると指摘した。
2005年12月、TIOBEのProgramming Community IndexにVFP（正確にはFoxPro/xBase）が初めて上位20位以内にランキングされた。2007年3月には19位、2007年8月には22位、2008年4月には17位と推移している。
2007年3月、マイクロソフトはVFP 10は開発されないことを発表した。従って、2004年12月17日にリリースされたVFP 9が最後の商用バージョンとなる。VFP 9 のサポートはサービスパックの形式で行われている（2005年12月と2007年10月にリリース）。
その発表と同時に、開発されていた次期バージョンSedna（コード名）が発表された。これはVFP 9へのアドオンであり、SQL Server 2005、.NET Framework、Windows Vista、Office 2007、Windows Search、Team Foundation Server (TFS) などとの連携機能をサポートしている。マイクロソフトはこれをシェアードソースライセンスでCodePlex上でリリースした。ただし、VFPの中核部分は依然としてクローズドソースである。Sednaのリリースは2008年1月25日に行われた。2008年3月現在、VFP 9 SP2（Sednaを含む）のXBaseコンポーネントは全てCodePlexから開発用に利用可能である。
2007年3月、FoxProのスペイン語コミュニティMasFoxProで草の根運動が始まり、マイクロソフトに対してVisual FoxProの開発継続か全ソースのオープンソース化を求める活動を展開した。2007年4月3日、この運動は業界メディアでも報道された。これに対してマイクロソフトは2007年4月3日、声明を発表した。それによると、新たなバージョンは開発せず、2015年までサポートを継続するとのこと。また、オープンソース化については最善の選択としているが、中核部のオープンソース化の具体的な予定は発表されていない。
コード例
Hello World の例:
MESSAGEBOX("Hello World")
オブジェクト
loForm = CREATEOBJECT("HiForm")
loForm.Show(1)

DEFINE CLASS HiForm AS Form
  AutoCenter = .T.
  Caption = "Hello, World"

  ADD OBJECT lblHi as Label WITH ;
    Caption = "Hello, World!"ENDDEFINE
loMine = CREATEOBJECT("MyClass")
? loMine.cProp1   && これは動作する（'&'が2つで行末までコメント）
? loMine.cProp2   && プログラムエラー: Property CPROP2 is not found.

? loMine.MyMethod1()  && これは動作する。
? loMine.MyMethod2()  && プログラムエラー: Property MYMETHOD2 is not found.DEFINE CLASS MyClass AS Custom
  cProp1 = "My Property"    && パブリック・プロパティ
  HIDDEN cProp2     && プライベート・プロパティ

  PROCEDURE Init()    && クラス・コンストラクタ
    This.cProp2 = "This is a hidden property."
  ENDPROC

  PROCEDURE MyMethod1()
    * This is a public method, calling a hidden method that returns
    * the value of a hidden property.
    RETURN This.MyMethod2()
  ENDPROC

  HIDDEN PROCEDURE MyMethod2()  && プライベート・メソッド
    RETURN This.cProp2
  ENDPROCENDDEFINE
データハンドリング
&& テーブル生成CREATE TABLE randData (iData I)

&& xBase と SQL DML コマンドを使ってランダムなデータを格納FOR i = 1 TO 50
    APPEND BLANK
    REPLACE iData WITH (RAND() * 100)

    INSERT INTO randData (iData) VALUES (RAND() * 100)
ENDFOR

&& データ上に構造化インデックスを配置INDEX ON iData TAG iData
CLOSE ALL

&& xBase風コマンドでソートしたデータを表示USE randData
SET ORDER TO iData
GO TOP
LIST NEXT 10  && First 10 SKIP 81
LIST NEXT 10  && Last 10CLOSE ALL

&& SQL DML コマンドでソート済みデータをブラウズSELECT * ;
  FROM randData ;
  ORDER BY iData DESCENDING
SQLパススルーを使ったODBCアクセス
&& ODBCデータソースに接続LOCAL nHnd
nHnd = SQLCONNECT ("ODBCDSN", "user", "pwd")

&& SQL コマンドを実行LOCAL nResult
nResult = SQLEXEC (nHnd, "USE master")
IF nResult < 0
  MESSAGEBOX ("MASTER database does not exist!")
  RETURNENDIF

&& リモートサーバからデータを検索し&& ローカルなデータカーソルにそれを格納nResult = SQLEXEC (nHnd, "SELECT * FROM authors", "QAUTHORS")

&& リモートのテーブルにあるレコードを更新LOCAL cAuthorID, cAuthorName
cAuthorID = "1001"cAuthorName = "New name"nResult = SQLEXEC (nHnd, "UPDATE authors SET auth_name = ?cAuthorName WHERE auth_id = ?cAuthorID")

&& 切断
SQLDISCONNECT(nHnd)