我有一些仍在运行 SQL Server 2000 的数据库,我不想为其他人恢复到旧驱动程序。经过一番探索,这是我能想到的最佳解决方法:通过 ADO 使用 OLEDB 连接到 SQL Server 2000 数据库。ADO 是一个 COM 组件,因此您需要启用COM_DOT_NET
扩展。
我已经验证这仍然适用于安装了 Native Client 11 的 Windows Server 2008 R2 下的 PHP 5.4。
<?php
$conn = new COM("ADODB.Connection") or die("Cannot create ADO COM object");
$conn->Open("Provider=SQLOLEDB;Integrated Security=SSPI;Persist Security Info=True;Data Source=LOCALHOST;Initial Catalog=master");
//$conn->Open("Provider=SQLOLEDB;User ID=username;Password=password;Persist Security Info=True;Data Source=host.example.com;Initial Catalog=databasename");
$rs = $conn->Execute("SELECT 1 as Number,GetDate() as Date, CAST(0 as bit) as Boolean, 'hello world' as String");
$fieldnames = [];
$rows = [];
while (!$rs->EOF){
$fieldnames = []; // wasteful, redoing this each time
$thisrow = [];
for ($i=0;$i<($rs->Fields->Count);$i++) {
$field = $rs->Fields[$i];
$fieldname = (string) $field->Name;
$type = $field->Type;
// field->Type is the ADO type; due personal weakness I am only handling types I actually need
if ($type == 3 || $type == 20) {
$value = (integer) $field->Value;
} elseif ($type == 4 || $type==5) {
$value = (float) $field->Value;
} elseif ($type == 11) {
$value = (boolean) $field->Value;
} else {
$value = (string) $field->Value;
}
$thisrow[] = $value; //array by index
$thisrow[$fieldname] = $value; // array by name
$fieldnames[]=$fieldname;
}
$rows[] = $thisrow;
$rs->MoveNext();
}
$rs->Close();
$conn->Close();
echo "your fieldnames are, in column order:\n";
var_dump($fieldnames);
echo "your data is, in record order:\n";
var_dump($rows);
?>
笔记:
- 这仅适用于 Windows 下的 PHP。
- 您需要启用 PHP COM_DOT_NET 扩展。乌格。请参阅这篇文章了解如何操作。
- devnetwork.net 上的这篇文章对于展示如何在 PHP 下使用 ADO 至关重要。
- 使用 ADO 的技巧是数据作为 COM 变体返回。使用 ADO 的最快方法是调用 GetRows() 并将返回的变体转换为 2D 变体数组并从那里开始,但我无法让 PHP 使用它。(这是上述链接中的“DrDev”问题。)
- 为避免出现问题,我遍历每一行的每个字段并显式转换为数据 PHP 类型。(这可以做得更好,但这些都是我关心的所有 ADO 类型。)
待办事项:参数化查询。我多么希望我可以将这些主机更新到 SQL Server 2012 Express Edition...