gpt4 book ai didi

SQL Server FileStream - 如何获取文件路径

转载 作者:太空狗 更新时间:2023-10-30 01:57:47 26 4
gpt4 key购买 nike

我正在开发这个应用程序,我需要将大型数据文件上传到我的 SQL Server 数据库,我一直在使用 FileStream 来更高效地完成这项工作。

我知道文件直接存储在我系统的文件夹中 (C:\CryptoDB)。

问题是,我需要操作这些文件(解密它们),但我无法恢复它们的文件路径。这样做,我将能够直接操作它们,而不必通过 SQL 重新下载它们,这是一种真正的浪费。

到目前为止我能做的:

我的 table :

CREATE TABLE [arquivo] (
[idUsuario] INT NOT NULL,
[fileState] INT NOT NULL,
[fileContent] varbinary(max) FILESTREAM,
[fileName] VARCHAR (150) NULL,
[fileSize] VARCHAR (50) NULL,

id UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL UNIQUE,

CONSTRAINT [FK_arquivo_usuario] FOREIGN KEY ([idUsuario]) REFERENCES usuario(id)
);

插入:

Insert into arquivo(id, idUsuario, fileState, fileContent, fileName, fileSize) Values(
newId(),
1,
5,
(SELECT * FROM OPENROWSET(BULK 'c:\medio.jpeg', SINGLE_BLOB) AS varbinary(max)) ,
'medio.jpeg',
'123'
)

当我尝试恢复文件路径时:

DECLARE @filePath varchar(max)

SELECT @filePath = fileContent.PathName()
FROM arquivo

PRINT @filepath

我得到的结果:

\\TEHORT-PC\MSSQLSERVER\v02-A60EC2F8-2B24-11DF-9CC3-AF2E56D89593\CryptoDB\dbo\arquivo\fileContent\31E3697E-0576-4B0F-B0AA-6E046F4116A1\VolumeHint-HarddiskVolume2

文件的实际位置:

C:\CryptoDB\DATA\902a7d8d-c8c1-43b0-8c94-b12319293f42\7febdbd1-02c6-4b00-aa3c-a72bee80ef9c\

最佳答案

  1. 获取所有 FILESTREAM 数据的物理位置的 SQL 查询 (source)

    SELECT t.name AS 'table', c.name AS '列', fg.name AS 'filegroup_name', dbf.type_desc AS 'type_description', dbf.physical_name AS 'physical_location'来自 sys.filegroups fg内连接 sys.database_files dbfON fg.data_space_id = dbf.data_space_idINNER JOIN 系统表 tON fg.data_space_id = t.filestream_data_space_idINNER JOIN sys.columns cON t.object_id = c.object_idAND c.is_filestream = 1

All FILESTREAM BLOB-fields query result sample

  1. 为服务器上的 FILESTREAM 数据获取子文件夹的 SQL 查询:(这些表仅在专用管理员连接 (DAC) 中使用)。

    SELECT o.name AS [Table], cp.name AS [Column], r.rsguid AS [Rowset GUID], rs.colguid AS [Column GUID] FROM SYS.SYSROWSETS r CROSS APPLY sys.sysrscols rs加入 sys.partitions p ON rs.rsid = p.partition_idJOIN sys.objects o ON o.object_id = p.object_id在 cp.colid = rs.rscolid 上加入 sys.syscolpars cp其中 rs.colguid 不为空且 o.object_id = cp.id 且 r.rsguid 不为空且 r.rowsetid = rs.rsid 且 o.name = 'DOCUMENT' 且 cp.name = 'DIGITAL_FILE';

2.1。查询结果:

Table: DOCUMENT
Column: DIGITAL_FILE
Rowset GUID: 0x6AA5E6045794D34D8B1FAC0F49A49B0A
Column GUID: 0xD756E638FB2CC843AE98F489B57F6D7D

从这个 guids 计算子路径:

0x6AA5E6045794D34D8B1FAC0F49A49B0A equals this path: 04e6a56a-9457-4dd3-8b1f-ac0f49a49b0a

[reversed 6AA5E604]-[reversed 5794]-[reversed D34D]-[reversed 8B1F]-[original AC0F49A49B0A]

0xD756E638FB2CC843AE98F489B57F6D7D equals this path: 38e656d7-2cfb-43c8-ae98-f489b57f6d7d (rules in previus guid parsing)

2.2 结果计算出 FILESTREAM 存储的完整路径:

i:\SQL Base posc_astrachan FileStreams\GTMK\GTM_FILE_STREAM\04e6a56a-9457-4dd3-8b1f-ac0f49a49b0a\38e656d7-2cfb-43c8-ae98-f489b57f6d7d

  1. 获取 NTFS 文件夹中 BLOB 值的原始文件名。

3.1。查询高级SQL Server页面信息的存储过程

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[procDBCC_PAGE]
@db_name varchar (500),
@filenum INT,
@pagenum INT
AS
BEGIN
SET NOCOUNT ON
DBCC TRACEON (3604);
DBCC PAGE (@db_name, @filenum, @pagenum, 3) WITH TABLERESULTS;
SET NOCOUNT OFF
END

3.2。为表的 FILESTREAM'ed BLOB 字段查询原始文件名的存储过程

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[procFindLogSequenceNumber]
-- @TableName varchar (500),
@instanceS varchar (19), -- key value for filed INSTANCE_S
@tableName varchar(500), -- DOCUMENT
@keyFieldName varchar(500), -- INSTANCE_S
@LogSequenceNumber varchar (500) OUTPUT
AS
SET NOCOUNT ON

DECLARE @db_name varchar (500)
DECLARE @filenum INT
DECLARE @pagenum INT
DECLARE @slotnum INT
DECLARE @rid varchar (100)
DECLARE @ridDotted varchar (100)

DECLARE @parent_object varchar (500)

DECLARE @sql nvarchar(2000)
DECLARE @sqlTable Table(physloc varchar(100))

DECLARE @DBCC_PAGE_Output Table ([ParentObject] varchar (MAX), [Object] varchar (MAX), [Field] varchar (MAX), [VALUE] varchar (MAX))

SET @db_name = db_name()

SET @sql = 'SELECT top 1 sys.fn_PhysLocFormatter (%%physloc%%) AS [PhysicalRID] FROM '+@tableName+' WHERE '
+@keyFieldName+' = '''+@instanceS+''''

INSERT @sqlTable (physloc)
EXECUTE sp_executesql @sql

SET @rid = (select top 1 physloc from @sqlTable)
if @rid is NULL
BEGIN
RETURN -1;
END

-- parse (@rid): (1:1172779:6) 1-@filenum, 2- @pagenum, 3- @slotnum
SET @ridDotted = Replace(@rid, ':', '.');
SET @ridDotted = Replace(@ridDotted, '(', '');
SET @ridDotted = Replace(@ridDotted, ')', '');

SET @filenum = (SELECT Parsename(@ridDotted, 3))
SET @pagenum = (SELECT Parsename(@ridDotted, 2))
SET @slotnum = (SELECT Parsename(@ridDotted, 1))

INSERT @DBCC_PAGE_Output ([ParentObject], [Object], [Field], [VALUE])
EXECUTE procDBCC_PAGE @db_name, @filenum , @pagenum

SET @parent_object = (SELECT TOP 1 [ParentObject] FROM @DBCC_PAGE_Output WHERE [Field] = 'INSTANCE_S'
AND [VALUE] = @instanceS)

--CreateLSN field Only
SET @LogSequenceNumber = (SELECT [VALUE] FROM @DBCC_PAGE_Output WHERE
[ParentObject] = @parent_object AND
[Field] = 'CreateLSN'
)

if @LogSequenceNumber is NULL
BEGIN
RETURN -1;
END

-- result 0006c050:00000120:0090 (442448:288:144)
-- clear (...)
SET @LogSequenceNumber = Replace(@LogSequenceNumber, ' ', '.');
SET @LogSequenceNumber = (SELECT Parsename(@LogSequenceNumber, 2))

--replace ":" to "-"
SET @LogSequenceNumber = Replace(@LogSequenceNumber, ':', '-');

SET NOCOUNT OFF

3.3。用于获取 BLOB 的 NTFS 文件夹上的文件名的存储过程的示例查询:

declare @filestreamFileName varchar(500);
exec procFindLogSequenceNumber 'ZW_NU9hGZ0CKoSXYAoc', 'DOCUMENT', 'INSTANCE_S', @filestreamFileName OUTPUT
select @filestreamFileName

3.4。结果(NTFS文件夹中的原始文件名):

0003137a-00001244-00d0

3.5。结果完整路径:

i:\SQL Base posc_astrachan FileStreams\GTMK\GTM_FILE_STREAM\04e6a56a-9457-4dd3-8b1f-ac0f49a49b0a\38e656d7-2cfb-43c8-ae98-f489b57f6d7d\0003137a-00001244-00d0

关于SQL Server FileStream - 如何获取文件路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19627437/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com