Heim  >  Artikel  >  Datenbank  >  So greifen Sie mit Fortschritt auf SQL Server FileStream zu

So greifen Sie mit Fortschritt auf SQL Server FileStream zu

jacklove
jackloveOriginal
2018-06-15 09:21:132246Durchsuche

Ausführliche Referenz-Onlinehilfe für die SQL Server FileStream-Funktion zum Entwerfen und Implementieren des FILESTREAM-Speichers
Hier ist nur eine Anpassung des Codes, der Win32 zum Verwalten von FILESTREAM-Daten verwendet, um einen erweiterten Zugriff zu erreichen, der für den Zugriff auf größere Dateien besser ist
Um FileStream zu verwenden, aktivieren Sie zunächst die FileStream-Option im SQL Server-Konfigurationsmanager: SQL Server-Konfigurationsmanager – SQL Server-Dienst – SQL Server-Dienst suchen – Eigenschaften – FILESTREAM – Ermöglichen Sie Remote-Clients den Zugriff auf FILESTREAM-Daten nach Bedarf in der Dienstliste auf der rechten Seite Wählen Sie die beiden anderen Empfehlungen aus. Nachdem die Konfiguration abgeschlossen ist, müssen Sie den SQL Server-Dienst neu starten, damit die Einstellungen wirksam werden.
Verwenden Sie dann das folgende Skript, um die Testdatenbank und die Testtabelle zu erstellen

 -- =========================================================-- 启用 filestream_access_level-- =========================================================EXEC sp_configure 'filestream_access_level', 2;     -- 0=禁用  1=针对 T-SQL 访问启用 FILESTREAM  2=针对 T-SQL 和 WIN32 流访问启用 FILESTREAMRECONFIGURE;
GO-- =========================================================-- 创建测试数据库-- =========================================================EXEC master..xp_create_subdir 'f:\temp\db\_test';CREATE DATABASE _testON
    PRIMARY(
        NAME = _test, FILENAME = 'f:\temp\db\_test\_test.mdf'),
    FILEGROUP FG_stream CONTAINS FILESTREAM(
        NAME = _test_file_stream, FILENAME = 'f:\temp\db\_test\stream')
    LOG ON(
        NAME = _test_log, FILENAME = 'f:\temp\db\_test\_test.ldf')
;GO-- =========================================================-- FileStream-- =========================================================-- =================================================-- 创建 包含 FileStream 数据的表-- -------------------------------------------------CREATE TABLE _test.dbo.tb_fs(
    id uniqueidentifier ROWGUIDCOL      -- 必需        DEFAULT NEWSEQUENTIALID ( ) PRIMARY KEY,
    name nvarchar(260),
    content varbinary(max) FILESTREAM
);GO
下面的 VB 脚本实现带进度显示的文件存(Write方法)取(Read方法)
Imports System.IO
Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.SqlTypes
Module Module1
    Public Sub Main(ByVal args As String())
        Dim sqlConnection As New SqlConnection("Integrated Security=true;server=localhost")
        Try
            sqlConnection.Open()
            Console.WriteLine("将文件保存到 FileStream")
            Write(sqlConnection, "test", "f:\temp\re.csv")
            Console.WriteLine("从 FileStream 读取数据保存到文件")
            Read(sqlConnection, "test", "f:\temp\re_1.csv")
        Catch ex As System.Exception
            Console.WriteLine(ex.ToString())
        Finally
            sqlConnection.Close()        End Try
        Console.WriteLine("处理结束,按 Enter 退出")
        Console.ReadLine()    End Sub    &#39;&#39;&#39; <summary>
    &#39;&#39;&#39; 将文件保存到数据库    &#39;&#39;&#39; </summary>
    &#39;&#39;&#39; <param name="conn">数据库连接</param>    &#39;&#39;&#39; <param name="name">名称</param>
    &#39;&#39;&#39; <param name="file">文件名</param>
    Sub Write(ByVal conn As SqlConnection, ByVal name As String, ByVal file As String)
        Dim bufferSize As Int32 = 1024
        Using sqlCmd As New SqlCommand
            sqlCmd.Connection = conn            &#39;事务
            Dim transaction As SqlTransaction = conn.BeginTransaction("mainTranaction")
            sqlCmd.Transaction = transaction
            &#39;1. 读取 FILESTREAM 文件路径 ( 注意函数大小写 )
            sqlCmd.CommandText = "
UPDATE _test.dbo.tb_fs SET content = 0x WHERE name = @name;
IF @@ROWCOUNT = 0 INSERT _test.dbo.tb_fs(name, content) VALUES( @name, 0x );
SELECT content.PathName() FROM _test.dbo.tb_fs WHERE name = @name;"
            sqlCmd.Parameters.Add(New SqlParameter("name", name))
            Dim filePath As String = Nothing
            Dim pathObj As Object = sqlCmd.ExecuteScalar()            If Not pathObj.Equals(DBNull.Value) Then
                filePath = DirectCast(pathObj, String)            Else
                Throw New System.Exception("content.PathName() failed to read the path name for the content column.")            End If
            &#39;2. 读取当前事务上下文
            sqlCmd.CommandText = "SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()"
            Dim obj As Object = sqlCmd.ExecuteScalar()
            Dim txContext As Byte() = Nothing
            Dim contextLength As UInteger
            If Not obj.Equals(DBNull.Value) Then
                txContext = DirectCast(obj, Byte())
                contextLength = txContext.Length()
            Else
                Dim message As String = "GET_FILESTREAM_TRANSACTION_CONTEXT() failed"
                Throw New System.Exception(message)
            End If
            &#39;3. 获取 Win32 句柄,并使用该句柄在 FILESTREAM BLOB 中读取和写入数据            Using sqlFileStream As New SqlFileStream(filePath, txContext, FileAccess.Write)
                Dim buffer As Byte() = New Byte(bufferSize - 1) {}
                Dim numBytes As Integer = 0
                Using fsRead As New FileStream(file, FileMode.Open)
                    While True
                        numBytes = fsRead.Read(buffer, 0, bufferSize)                        If numBytes = 0 Then Exit While
                        sqlFileStream.Write(buffer, 0, numBytes)
                        Console.WriteLine(String.Format("{0} -> {1} -> {2}", fsRead.Position, sqlFileStream.Position, numBytes))                    End While
                    fsRead.Close()                End Using
                sqlFileStream.Close()            End Using
            sqlCmd.Transaction.Commit()        End Using
    End Sub    &#39;&#39;&#39; <summary>
    &#39;&#39;&#39; 从数据库读取数据保存到文件    &#39;&#39;&#39; </summary>
    &#39;&#39;&#39; <param name="conn">数据库连接</param>    &#39;&#39;&#39; <param name="name">名称</param>
    &#39;&#39;&#39; <param name="file">文件名</param>
    Sub Read(ByVal conn As SqlConnection, ByVal name As String, ByVal file As String)
        Dim bufferSize As Int32 = 1024
        Using sqlCmd As New SqlCommand
            sqlCmd.Connection = conn            &#39;1. 读取 FILESTREAM 文件路径 ( 注意函数大小写 )
            sqlCmd.CommandText = "SELECT content.PathName() FROM _test.dbo.tb_fs WHERE name = @name;"
            sqlCmd.Parameters.Add(New SqlParameter("name", name))
            Dim filePath As String = Nothing
            Dim pathObj As Object = sqlCmd.ExecuteScalar()
            If Not pathObj.Equals(DBNull.Value) Then
                filePath = DirectCast(pathObj, String)
            Else
                Throw New System.Exception("content.PathName() failed to read the path name for the content column.")
            End If
            &#39;2. 读取当前事务上下文
            Dim transaction As SqlTransaction = conn.BeginTransaction("mainTranaction")
            sqlCmd.Transaction = transaction
            sqlCmd.CommandText = "SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()"
            Dim obj As Object = sqlCmd.ExecuteScalar()
            Dim txContext As Byte() = Nothing
            Dim contextLength As UInteger            If Not obj.Equals(DBNull.Value) Then
                txContext = DirectCast(obj, Byte())
                contextLength = txContext.Length()            Else
                Dim message As String = "GET_FILESTREAM_TRANSACTION_CONTEXT() failed"
                Throw New System.Exception(message)            End If
            &#39;3. 获取 Win32 句柄,并使用该句柄在 FILESTREAM BLOB 中读取和写入数据
            Using sqlFileStream As New SqlFileStream(filePath, txContext, FileAccess.Read)
                Dim buffer As Byte() = New Byte(bufferSize - 1) {}
                Dim numBytes As Integer = 0
                Using fsRead As New FileStream(file, FileMode.Create)
                    While True
                        numBytes = sqlFileStream.Read(buffer, 0, bufferSize)
                        If numBytes = 0 Then Exit While
                        fsRead.Write(buffer, 0, numBytes)
                        Console.WriteLine(String.Format("{0} -> {1} -> {2}", sqlFileStream.Position, sqlFileStream.Position, numBytes))
                    End While
                    fsRead.Close()
                End Using
                sqlFileStream.Close()
            End Using
            sqlCmd.Transaction.Commit()
        End Using
    End Sub
End Module

In diesem Artikel wird erläutert, wie Sie mit Fortschritt auf SQL Server FileStream zugreifen. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website.

Verwandte Empfehlungen:

Was tun, wenn Sie das SQL Server-Administratorkennwort vergessen?

Eine kurze Analyse von concat und group_concat in MySQL verwenden

Einführung in das grafische MySQL-Verwaltungstool

Das obige ist der detaillierte Inhalt vonSo greifen Sie mit Fortschritt auf SQL Server FileStream zu. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn