【发布时间】:2021-09-01 01:06:35
【问题描述】:
标题听起来很混乱,但我不知道如何更好地描述它。
我的任务是进行从程序 A 到程序 B 的数据库迁移。
程序 A 使用 MSSQL 数据库并将其所有文件存储在数据库中。
程序 B 处理以“正常”方式存储的文件,即在文件系统中。
现在我必须使用 PHP 将数据库存储的文件提取、转换和下载到文件系统文件,但我尝试转换它们没有成功。
出于测试目的,我创建了一个简单的.txt 文件,内容为Test document for migration,程序A 将其存储在数据库中:
0x5465737420646F63756D656E7420666F72206D6967726174696F6E'
那是什么格式,如何将其转换为普通的document.txt 文件?
编辑
非常感谢@PanagiotisKanavos。这现在确实适用于流:
$query = "select top(1) DESCRIPTION, FILETYPE, DOCUMENT from dbo.Documents;";
$stmt = sqlsrv_query($this->sqlsrv_conn, $query);
if (sqlsrv_fetch($stmt)) {
$document = sqlsrv_get_field($stmt, 2, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY));
$fileName = sqlsrv_get_field($stmt, 0, SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR));
$ext = sqlsrv_get_field($stmt, 1, SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR));
file_put_contents(
$fileName . '.' . $ext,
stream_get_contents($document),
);
}
现在对所有文件执行此操作的最有效方法是什么?我必须对每一行都执行查询吗?
有了 PDO,我可以使用 $stmt->fetchAll(FETCH_ASSOC),它给了我一个很好的 assoc 数组,里面有数据。sqlsrv 有一个类似的函数 sqlsrv_fetch_array 解释了 php.net 和 [docs.microsoft]下面的例子:
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
echo $row['LastName'].", ".$row['FirstName']."<br />";
}
但尽我所能搜索,我找不到一种方法来循环遍历结果集而不获取它,然后单独获取每一行,同时混合流和字符串类型。 sqlsrv_fetch_array 只接受SQLSRV_FETCH_NUMERIC、SQLSRV_FETCH_ASSOC 和SQLSRV_FETCH_BOTH 然后结果集已经获取,我不能使用sqlsrv_get_field 来设置每个字段的类型。
我不可能是第一个需要这样的东西的人,但我找不到任何关于它的东西。可能我搜索错误,或者我误解了一个概念。
【问题讨论】:
-
你为什么假设它应该是一个txt文件?它可以是任何二进制格式。我假设数据库中的其他地方必须有元数据(通常在同一个表或相关表中),它告诉您存储在其中的每个文件的名称和可能的 mime 类型。否则也很难看出原始应用程序如何利用这些数据。
-
我自己创建了这个文本文件,所以我知道,但它们有许多不同的文件类型,你说得对。他们确实有文档的扩展名和名称以及其他元数据,如日期时间和页数,但我找不到 mime 类型。但是我找到了解决方案,我会尽快写一篇文章
-
@SamuelGfeller 解决方案是错误的。这不是“格式”,这就是 SSMS 显示二进制数据的方式。您的数据访问库已经有办法做到这一点。指定您的库并添加实际的数据访问代码
-
@PanagiotisKanavos 为不清楚的问题道歉。如果我分享我尝试实现的目标可能会更好,即将存储在 SQL Server 2008 数据库(大约 9 个表)中的所有文件“转换”为文件系统文件。最好使用 PHP,因为我知道该语言,但是任何语言的小脚本都可以使用任何库。 (如果是 PHP,它必须能够在 Windows 上运行)。你会怎么做?
标签: php file hex filesystems