[英]Can I stream a file to a SQL Server stored procedure?
我在远程计算机上有一个文件,想要“复制”到SQL Server主机到特定区域。 我想知道通过SQL Server存储过程执行此操作的选项是什么,更具体地说,我想流式传输文件内容,而不是先将全部内容读取到内存中。
我基本上是在寻找这样的流媒体版本:
CREATE PROCEDURE [dbo].[SaveFile]
(@filename nvarchar(255), @contents nvarchar(max))
AS
BEGIN
DECLARE @ObjectToken INT
EXEC sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT
EXEC sp_OASetProperty @ObjectToken, 'Type', 1
EXEC sp_OAMethod @ObjectToken, 'Open'
EXEC sp_OAMethod @ObjectToken, 'WriteText', NULL, @contents
EXEC sp_OAMethod @ObjectToken, 'SaveToFile', NULL, 'C:\\Destination\\' + @filename, 2
EXEC sp_OAMethod @ObjectToken, 'Close'
EXEC sp_OADestroy @ObjectToken
END
filestream
或等效的东西作为存储过程输入参数吗? @ObjectToken
,另一个过程可以从流中@ObjectToken
一个WriteText
块,而第三个过程可以SaveToFile
并Close
它,但这看起来像!a.GoodIdea
,我必须确保关闭和销毁通过某种超时。 它是从C#控制台应用程序中获取的,我更喜欢流式传输这些大文件,而不是像File.ReadAllText()
类的东西,将一个数千兆字节的字符串加载到一个变量中,然后使用该文件的全部内容来调用存储过程。文件。
我做了一些尝试,以使其与OLE Automation( sp_OACreate
, sp_OAMethod
等)一起工作,并遇到了许多问题,并提出了基于CLR的解决方案。
我有一个C#控制台应用程序,C#CLR存储过程和一个示例SQL Server数据库,该示例SQL Server数据库发布在名为StreamFile的存储库中的github帐户上。
基本思想是,我调用一个过程来启动传输,该过程将在数据库中记录一行并创建文件,将n
块发送到追加到文件的另一个存储过程中,然后调用第三个存储过程来表示成功流的完成。
CREATE PROCEDURE [dbo].[StreamFile_AddBytes]
(@fileID int, @chunk varbinary(max))
AS
BEGIN
BEGIN TRY
DECLARE @tmppath nvarchar(max)
SELECT @tmppath = FilePath FROM StreamedFiles WHERE StreamedFileID = @fileID
IF (@tmppath is null)
RAISERROR (N'Invalid StreamedFileID Provided: %d', 11, 1, @fileID);
--C# CLR Based Stored Procedure
EXEC dbo.AppendBytes @tmppath, @chunk
UPDATE StreamedFiles SET Chunks = Chunks + 1, FileSize = FileSize + LEN(@chunk) WHERE StreamedFileID = @fileID
SELECT * FROM StreamedFiles sf WHERE sf.StreamedFileID = @fileID
END TRY
BEGIN CATCH
DECLARE @ErrorMessage NVARCHAR(4000), @ErrorSeverity INT, @ErrorState INT;
SELECT @ErrorMessage = ERROR_MESSAGE(), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE();
RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState);
END CATCH
这是我将要测试的可能解决方案:
CREATE PROCEDURE [dbo].[StreamOpen]
AS
BEGIN
DECLARE @ObjectToken INT
EXEC sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT
EXEC sp_OASetProperty @ObjectToken, 'Type', 1
EXEC sp_OAMethod @ObjectToken, 'Open'
SELECT @ObjectToken
END
CREATE PROCEDURE [dbo].[StreamAddChunk] (@token int, @chunk nvarchar(max))
AS
BEGIN
EXEC sp_OAMethod @token, 'WriteText', NULL, @contents
END
CREATE PROCEDURE [dbo].[StreamClose] (@token int, @filename nvarchar(260))
AS
BEGIN
EXEC sp_OAMethod @token, 'WriteText', NULL, @contents
EXEC sp_OAMethod @token, 'SaveToFile', NULL, 'C:\\Destination\\' + @filename, 2
EXEC sp_OAMethod @token, 'Close'
EXEC sp_OADestroy @token
END
测试完毕后,我将更新此答案,并添加C#调用代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.