Makale numarası: 194975 - Son Gözden Geçirme: 14 Mart 2005 Pazartesi - Gözden geçirme: 3.5

Okuma ve yazma işlemlerinin nasıl GetChunk kullanma ve AppendChunk BLOBs...

Sistem İpucuBu makale, kullandığınızdan farklı bir işletim sistemine yöneliktir. Sizinle ilgili olmayabilecek makale içeriği devre dışı bırakıldı.
Bu makalenin Microsoft Visual Basic .NET sürümü için bkz: 317034  (http://support.microsoft.com/kb/317034/EN-US/ ) .
Bu makalenin Microsoft Visual Basic .NET sürümü için bkz: 316887  (http://support.microsoft.com/kb/316887/EN-US/ ) .

Bu Sayfada

Hepsini aç | Hepsini kapa

Özet

Bu ikili büyük GetChunk ve AppendChunk ADO alanlarına karşı yöntemlerle Objects (BLOB'lar) okuyup makalede. NWIND örnek veritabanını kullanan örnek kod da içerir.

Daha fazla bilgi

GetChunk ve AppendChunk yöntemler LongVarChar LongVarWChar ve LongVarBinary sütun türlerini, TEXT, NTEXT ve RESIM olarak da bilinir, sütun, Microsoft SQL Server ve Microsoft Jet veritabanlarında, MEMO ve OLE alanları olarak çalışır. ADO bu sütunlarda, Type özelliği bir alanın değerlerini adLongVarChar, adLongVarWChar ve adLongVarBinary sınayarak tanımlayabilirsiniz. Attributes özelliği bir alanın adFldLong bayrak için sınama da yapabilirsiniz:
If fld.Attributes And adFldLong Then
   ' You can use GetChunk/AppendChunk
				
karşın, metin verisi içerebilir uzun sütun sık için BLOB'lar (ikili geniş nesne)</a0> adlandırılır. Aşağıdaki örnek kodu BlobToFile ve FileToBlob iki yordamlar sağlar.

BlobToFile

BlobToFile ve BLOB verileri için bir disk dosyasına yazmak için üç yöntem, alanın veri türünü belirler. BLOB verileri yeterince küçükse, GetChunk çağırmadan okumalıdır <a2>alanın</a2> değerini başvuru. BLOB boyutu bilinmiyorsa, WriteFromUnsizedBinary veya WriteFromUnsizedText verileri yazmak için çağırır. Bu bilinen bir BLOB verilerin boyutu, kullanılan WriteFromBinary ve WriteFromText yordamlarına göre yerel bellekte verilerin ek kopyalarını yapmak açısından daha az verimlidir:
    BlobToFile                Calls one of the below routines to use GetChunk
    WriteFromBinary         Writes a LongVarBinary of known size to disk
    WriteFromUnsizedBinary  Writes a LongVarBinary on unknown size
    WriteFromText           Writes a LongVarChar of known size
    WriteFromUnsizedText    Writes a LongVarChar of unknown size
				

FileToBlob

FileToBlob AppendChunk kullanın veya doğrudan veri dosyasının boyutuna göre BLOB alan atamak belirler. Dosyanın boyutunu her zaman belirlenebilir çünkü vardır "Unsized" hiçbir yordamlar BlobToFile örnek kodda olduğundan:
    FileToBlob          Calls one of the below routines to use AppendChunk
    ReadToBinary      Reads a file into a LongVarBinary column
    ReadToText        Reads a file into a LongVarChar column
				

ÖRNEK

Sınama kod, varsayılan formun olsa BlobToFile ve FileToBlob örnek kodunu bir modülünde depolanır. Sınama kodu (RESIM/OLE/LongVarBinary) fotoğrafı diske kaydetmek için üç yöntemden birini kullanır ve (TEXT/MEMO/LongVarChar/LongVarWChar) alanlar için Barış Çetinok NWIND veritabanını Çalışanlar tablosundan notlar. Bunun ardından okuma, dosyaları geri ve her biri üç grup dosyaları üzerinden iki farklı yöntemler okuma, okuma, altı yeni kayıtlar oluşturur. Not: ADO 2.1 ve sonrasıyla kullanarak, aşağıdaki hata kodu satırdaki görebilirsiniz:
Data = fld.GetChunk(BLOCK_SIZE) :

        Run-time error '94':
        Invalid use of Null
				
ADO 2.1 ve sonrasıyla metin türünü BLOB alanının ActualSize özelliği, iki kez karakter sayısı bildirebilir. Unicode karakter başına 2 bayt kullanır BLOB alan Unicode metin içeriyorsa doğru olmasıdır. BLOB alan karakter başına 1 bayt kullanır ANSI metin içeriyorsa bu yanlıştır. Daha sonra ActualSize iki kez bir <a0>ANSI</a0> alanının uzunluğu, GetChunk alanın sonunun almak sonuç çalışır.

Bu davranış, aşağıdaki senaryolarda görebilirsiniz ve bunu diğer senaryolarda görebilirsiniz:

Senaryo 1:

SQL Server 7 NTEXT olan bir alana (ANSI metin), SQL Server veya SQL Server ODBC sürücüsü ODBC sağlayıcısında ya da OLE DB sağlayıcı kullanarak.

SQL Server METNEÇEVIR kullanarak <a1>alan</a1> (Unicode) her iki sağlayıcı ile çalıştığını unutmayın.

Senaryo 2:

Access 97 MEMO alanları ve Access 2000 MEMO alanları içeren veya içermeyen Unicode sıkıştırma ile Jet 4.0 ya da ODBC Sağlayıcı Jet ODBC 4.0 sürücüsüyle ODBCJT32.DLL ya da OLE DB Provider'ı kullanma.

Her iki OLE DB Sağlayıcı Jet 3.51 ve ODBC Provider Jet ODBC 3.51 sürücü çalışma için Access 97 MEMO alanları ile doğru unutmayın.

Çalışma zamanı hatası '94' için birkaç olası geçici çözümler vardır:
  • RS.Fieldname.ActualSize kullanır \ rs.Fieldname.ActualSize yerine 2. Bu, her biri, yukarıda listelenen özel senaryolar sorununu çözdü.

  • 2 Veya 3 aşağıdaki hiçbiri, ActualSize özelliği kullanan yöntemini kullanın.

Veri hazırlama

  1. Microsoft Access veya başka bir araç, NWIND.MDB açın.
  2. Çalışanlar tablosunu (veya form)'nı açın ve "Barış Çetinok" bulun.
  3. (Arasında 30000 ve 60000 bayt) büyük bir metin dosyası içeriğini Notlar alanına yapıştırın.
  4. Değişiklikleri kaydetmek ve Access çıkın.
  5. NWIND.MDB dosyaya işaret eden bir ODBC veri kaynağı'nı ekleyin.

Örnek kod

  1. Yeni bir Visual Basic projesi oluşturmak ve proje menüsünden References seçin ve Microsoft ActiveX Data Objects kitaplığı veya Microsoft ActiveX Data Objects kitaplığı seçin.
  2. Iki CommandButtons (cmdSave ve cmdLoad) için varsayılan form(Form1) ekleyin.
  3. Aşağıdaki kodu ekleyin. "Open" satırında sağlanan bağlantı dizesini değiştirmeniz gerekecektir:
          Option Explicit
    
          Private Sub CmdSave_Click()
          Dim cn As ADODB.Connection, rs As ADODB.Recordset, SQL As String
            Set cn = New ADODB.Connection
            Set rs = New ADODB.Recordset
            cn.CursorLocation = adUseServer
            cn.Open "dsn=nwind_jet"   ' *** change this ***
            SQL = "SELECT * FROM Employees WHERE LastName='Fuller'"
            rs.Open SQL, cn, adOpenStatic, adLockReadOnly
          '
          ' Save using GetChunk and known size.
          ' FieldSize (ActualSize) > Threshold arg (16384)
          '
            BlobToFile rs!Photo, "c:\photo1.dat", rs!Photo.ActualSize, 16384
            BlobToFile rs!Notes, "c:\notes1.txt", rs!Notes.ActualSize, 16384
             
          ' Uncomment the next line of code, and comment the line above,
          ' to workaround Runtime error '94': Invalid use of Null
          ' BlobToFile rs!Notes, "c:\notes1.txt", rs!Notes.ActualSize \ 2, 16384
    
          '
          ' Save using GetChunk and unknown size.
          ' FieldSize not specified.
          '
            BlobToFile rs!Photo, "c:\photo2.dat"
            BlobToFile rs!Notes, "c:\notes2.txt"
          '
          ' Save without using GetChunk
          ' FieldSize (ActualSize) < Threshold arg (defaults to 1Mb)
          '
            BlobToFile rs!Photo, "c:\photo3.dat", rs!Photo.ActualSize
            BlobToFile rs!Notes, "c:\notes3.txt", rs!Notes.ActualSize
    
          ' Uncomment the next line of code, and comment the line above,
          '   to workaround Runtime error '94': Invalid use of Null
          ' BlobToFile rs!Notes, "c:\notes3.txt", rs!Notes.ActualSize \ 2
    
            rs.Close
            cn.Close
          End Sub
    
          Private Sub CmdLoad_Click()
          Dim cn As ADODB.Connection, rs As ADODB.Recordset, SQL As String
            Set cn = New ADODB.Connection
            Set rs = New ADODB.Recordset
            cn.CursorLocation = adUseServer
            cn.Open "dsn=ole_db_nwind_jet"
            SQL = "SELECT * FROM Employees"
            rs.Open SQL, cn, adOpenKeyset, adLockOptimistic
          '
          ' Load using AppendChunk
          '
            rs.AddNew
            rs!FirstName = "Test"
            rs!LastName = "Fuller11"
            FileToBlob "c:\photo1.dat", rs!Photo, 16384
            FileToBlob "c:\notes1.txt", rs!Notes, 16384
            rs.Update
    
            rs.AddNew
            rs!FirstName = "Test"
            rs!LastName = "Fuller21"
            FileToBlob "c:\photo2.dat", rs!Photo, 16384
            FileToBlob "c:\notes2.txt", rs!Notes, 16384
            rs.Update
    
            rs.AddNew
            rs!FirstName = "Test"
            rs!LastName = "Fuller31"
            FileToBlob "c:\photo3.dat", rs!Photo, 16384
            FileToBlob "c:\notes3.txt", rs!Notes, 16384
            rs.Update
    
          '
          ' Load without using AppendChunk
          '
            rs.AddNew
            rs!FirstName = "Test"
            rs!LastName = "Fuller12"
            FileToBlob "c:\photo1.dat", rs!Photo
            FileToBlob "c:\notes1.txt", rs!Notes
            rs.Update
    
            rs.AddNew
            rs!FirstName = "Test"
            rs!LastName = "Fuller22"
            FileToBlob "c:\photo2.dat", rs!Photo
            FileToBlob "c:\notes2.txt", rs!Notes
            rs.Update
    
            rs.AddNew
            rs!FirstName = "Test"
            rs!LastName = "Fuller32"
            FileToBlob "c:\photo3.dat", rs!Photo
            FileToBlob "c:\notes3.txt", rs!Notes
            rs.Update
    
            rs.Close
            cn.Close
          End Sub
    					
  4. Yeni bir modül, aşağıdaki kodla (Module1) projeye ekleyin:
          Option Explicit
    
          Const BLOCK_SIZE = 16384
    
          Sub BlobToFile(fld As ADODB.Field, ByVal FName As String, _
                         Optional FieldSize As Long = -1, _
                         Optional Threshold As Long = 1048576)
          '
          ' Assumes file does not exist
          ' Data cannot exceed approx. 2Gb in size
          '
          Dim F As Long, bData() As Byte, sData As String
            F = FreeFile
            Open FName For Binary As #F
            Select Case fld.Type
              Case adLongVarBinary
                If FieldSize = -1 Then   ' blob field is of unknown size
                  WriteFromUnsizedBinary F, fld
                Else                     ' blob field is of known size
                  If FieldSize > Threshold Then   ' very large actual data
                    WriteFromBinary F, fld, FieldSize
                  Else                            ' smallish actual data
                    bData = fld.Value
                    Put #F, , bData  ' PUT tacks on overhead if use fld.Value
                  End If
                End If
              Case adLongVarChar, adLongVarWChar
                If FieldSize = -1 Then
                  WriteFromUnsizedText F, fld
                Else
                  If FieldSize > Threshold Then
                    WriteFromText F, fld, FieldSize
                  Else
                    sData = fld.Value
                    Put #F, , sData  ' PUT tacks on overhead if use fld.Value
                  End If
                End If
            End Select
            Close #F
          End Sub
    
          Sub WriteFromBinary(ByVal F As Long, fld As ADODB.Field, _
                              ByVal FieldSize As Long)
          Dim Data() As Byte, BytesRead As Long
            Do While FieldSize <> BytesRead
              If FieldSize - BytesRead < BLOCK_SIZE Then
                Data = fld.GetChunk(FieldSize - BLOCK_SIZE)
                BytesRead = FieldSize
              Else
                Data = fld.GetChunk(BLOCK_SIZE)
                BytesRead = BytesRead + BLOCK_SIZE
              End If
              Put #F, , Data
            Loop
          End Sub
    
          Sub WriteFromUnsizedBinary(ByVal F As Long, fld As ADODB.Field)
          Dim Data() As Byte, Temp As Variant
            Do
              Temp = fld.GetChunk(BLOCK_SIZE)
              If IsNull(Temp) Then Exit Do
              Data = Temp
              Put #F, , Data
            Loop While LenB(Temp) = BLOCK_SIZE
          End Sub
    
          Sub WriteFromText(ByVal F As Long, fld As ADODB.Field, _
                            ByVal FieldSize As Long)
          Dim Data As String, CharsRead As Long
            Do While FieldSize <> CharsRead
              If FieldSize - CharsRead < BLOCK_SIZE Then
                Data = fld.GetChunk(FieldSize - BLOCK_SIZE)
                CharsRead = FieldSize
              Else
                Data = fld.GetChunk(BLOCK_SIZE)
                CharsRead = CharsRead + BLOCK_SIZE
              End If
              Put #F, , Data
            Loop
          End Sub
    
          Sub WriteFromUnsizedText(ByVal F As Long, fld As ADODB.Field)
          Dim Data As String, Temp As Variant
            Do
              Temp = fld.GetChunk(BLOCK_SIZE)
              If IsNull(Temp) Then Exit Do
              Data = Temp
              Put #F, , Data
            Loop While Len(Temp) = BLOCK_SIZE
          End Sub
    
          Sub FileToBlob(ByVal FName As String, fld As ADODB.Field, _
                         Optional Threshold As Long = 1048576)
          '
          ' Assumes file exists
          ' Assumes calling routine does the UPDATE
          ' File cannot exceed approx. 2Gb in size
          '
          Dim F As Long, Data() As Byte, FileSize As Long
            F = FreeFile
            Open FName For Binary As #F
            FileSize = LOF(F)
            Select Case fld.Type
              Case adLongVarBinary
                If FileSize > Threshold Then
                  ReadToBinary F, fld, FileSize
                Else
                  Data = InputB(FileSize, F)
                  fld.Value = Data
                End If
              Case adLongVarChar, adLongVarWChar
                If FileSize > Threshold Then
                  ReadToText F, fld, FileSize
                Else
                  fld.Value = Input(FileSize, F)
                End If
            End Select
            Close #F
          End Sub
    
          Sub ReadToBinary(ByVal F As Long, fld As ADODB.Field, _
                           ByVal FileSize As Long)
          Dim Data() As Byte, BytesRead As Long
            Do While FileSize <> BytesRead
              If FileSize - BytesRead < BLOCK_SIZE Then
                Data = InputB(FileSize - BytesRead, F)
                BytesRead = FileSize
              Else
                Data = InputB(BLOCK_SIZE, F)
                BytesRead = BytesRead + BLOCK_SIZE
              End If
              fld.AppendChunk Data
            Loop
          End Sub
    
          Sub ReadToText(ByVal F As Long, fld As ADODB.Field, _
                         ByVal FileSize As Long)
          Dim Data As String, CharsRead As Long
            Do While FileSize <> CharsRead
              If FileSize - CharsRead < BLOCK_SIZE Then
                Data = Input(FileSize - CharsRead, F)
                CharsRead = FileSize
              Else
                Data = Input(BLOCK_SIZE, F)
                CharsRead = CharsRead + BLOCK_SIZE
              End If
              fld.AppendChunk Data
            Loop
          End Sub
    					
  5. Projeyi çalıştırın ve cmdSave düğmesini tıklatın.
  6. C:\ dizininde, aşağıdaki dosyaları bulmalısınız: notes1.txt
    notes2.txt
    notes3.txt

    photo1.dat
    photo2.dat
    photo3.dat

    "Fotoğraf" üç dosya, birbirinin aynı boyutta olması gerekir. "Not" üç dosya, birbirinin aynı boyutta olması gerekir.

  7. CmdLoad düğmesini tıklatın.
  8. Açık veritabanı erişimi ve kullanarak fotoğraf ve notlar doğru şekilde geri yükledi, altı ek çalışanları görmelisiniz.

NOTLAR

Aşağıda, ADO ile BLOB'lar kullanmayla ilgili bazı öneriler verilmiştir. Bu, çoğu aşağıdaki Microsoft Bilgi Bankası makalesindeki öneri paralel:
153238  (http://support.microsoft.com/kb/153238/EN-US/ ) GetChunk ve AppendChunk yöntemleri RDO nesnesinin nasıl kullanılır
  1. Yalnızca ana kayıttaki bir işaretçi sunucudaki dosyalar üzerindeki verileri depolamak için bir BLOB veri alma açısından daha verimli olarak (veya yapılandırılmış dizin/dosya birincil anahtar değerini esas alan sistem adlandırma çeşit kullanabilirsiniz). (A) (b) (c) (d) Bu, sunucu yükünü ortadan kaldırarak, bir ikinci sunucuda saklanan dosyaları sağlayarak, ağ güvenlik öznitelikleri tek tek dosyaları ayarlanmasına izin vermek ve dosyalarının alınmasını bile sunucu kapalı olduğunda izin avantajı vardır. Belge türü (bit eşlem (.bmp), sözcük işlemcisi dosyaları (.doc) veya <a1>Tablolar</a1> (.xls) gibi bazı tür doğrudan dosya sunucusunda ana bilgisayar uygulamasına işaret dosyalar, bu özellikle geçerlidir.
  2. Bazı sağlayıcılar, özellikle SQL Server ODBC ve diğer veritabanlarında kullanırken BLOB verileri alınıyor, gibi BLOB sütun alan listesinin sonunda yerleştirme ve erişim BLOB sütun için önce tüm olmayan BLOB alanları başvuran özel bir dikkat olması gerekebilir. Bu gibi üzerinde birkaç etkene bağlıdır:
    • <a1>Sağlayıcı</a1> (genellikle ODBC)
    • Arka Uç Sunucu
    • Imleç konumu (genellikle istemci)
    • Imleç türü
    • Bir VIEW seçme veya bir saklı yordamdan dönen kayıtları alınıyor.
Bu çeşitli etkenlere bağlıdır BLOB sütunları ile sorunlarınız varsa aşağıda bir kılavuz, çünkü:
  • Bir ODBC sağlayıcı yerine yerel bir OLE DB sağlayıcısı deneyin.
  • Sunucu tarafı imleçleri (örneğin, adOpenKeyset) kullanın.
  • Ek olarak başka bir sütunu birincil anahtar sütunu/sütunları seçin.
  • BLOB sütunları son'i seçin. Tek bir alan seçin "*".
  • Tüm olmayan BLOB sütunları erişmeleri (gerekirse depolamaya).
  • Belirtilen sırada erişim BLOB sütunlar. Yalnızca imlecin değerini kaybetmeden önce bir kez başvuruda bulunmak mümkün olabilir.
  • AppendChunk yöntemi kullanarak bir BLOB sütunu düzenlerken, en az bir kayıt da olmayan BLOB sütununda düzenlemek zorunda kalabilirsiniz. BLOBs genellikle statik veya ODBC datasources üzerinde salt ileri imleçler güncelleştirilebilir değil.
  • Jet ODBC kullanırsanız, bu sürücünün salt okunur olması için zorlar çünkü saklı yordamlar (QueryDef) hiç döndürülen bir recordset güncelleştiremiyor.
  • Microsoft Oracle OLE DB sağlayıcısı, BLOB sütunu SELECT yan tümcesi sonuna görünmesi gereken sunucu tarafı imleçleri - BLOB verileri için rasgele erişim şu anda desteklemiyor.
ODBC imleç kitaplığı ile bir saklı yordamdan dönen kayıt kümesinde GetChunk veya AppendChunk yöntemi kullanmak olanaklı değildir. BLOB verileri normalde verileri geri kalanıyla bant genişliği kaydetmek için alınan değil olmasıdır. Saklı yordam, bir kayıt oluşturduğunda, imleç sürücüsü BLOB verileri için temel tablo veya kullanmak için anahtar alanlarını belirleyemediğinden sonra bilgi sorgula nasıl belirleyemiyor. Sunucu tarafı imleçleri sorun zahmetinden, ancak bir tek deyimli saklı yordam (SQL Server kısıtlama) başına için sınırlar.

Kullanıcıların kendi BLOB sütunu güncelleştirmek istediğiniz bilgi, bunlar temel tablolarıyla göstermek ve imleci, temel tablodan standart bir select deyimi kullanarak oluşturmak ister. Bu, doğrudan ODBC (değil bir ADO şey) kodlama bile doğru olacaktır.

Referanslar

Ek bilgi için lütfen aşağıdaki Microsoft Knowledge Base'deki makaleleri bakın:
185958  (http://support.microsoft.com/kb/185958/EN-US/ ) ADO GetChunk/AppendChunk Oracle ile BLOB verileri için nasıl kullanılır
189415  (http://support.microsoft.com/kb/189415/EN-US/ ) Dosya: AdoChunk.exe GetChunk ve AppendChunk Visual C++ ile kullanma
Data Access Objects kullanma:
103257  (http://support.microsoft.com/kb/103257/EN-US/ ) ACC: Okuma, depolama & büyük ikili nesne (BLOB'lar) yazılıyor

Bu makaledeki bilginin uygulandığı durum:
  • Microsoft ActiveX Data Objects 1.5
  • Microsoft ActiveX Data Objects 2.0
  • Microsoft ActiveX Data Objects 2.1 Service Pack 2
  • Microsoft ActiveX Data Objects 2.5
  • Microsoft ActiveX Data Objects 2.6
  • Microsoft ActiveX Data Objects 2.7
  • Microsoft Visual Basic 6.0 Professional Edition
  • Microsoft Visual Basic Enterprise Edition for Windows 6.0
Anahtar Kelimeler: 
kbmt kbbug kbdatabase kbhowto KB194975 KbMttr
Otomatik TercümeOtomatik Tercüme
ÖNEMLİ: Bu makale, bir kişi tarafından çevrilmek yerine, Microsoft makine-çevirisi yazılımı ile çevrilmiştir. Microsoft size hem kişiler tarafından çevrilmiş, hem de makine-çevrisi ile çevrilmiş makaleler sunar. Böylelikle, bilgi bankamızdaki tüm makalelere, kendi dilinizde ulaşmış olursunuz. Bununla birlikte, makine tarafından çevrilmiş makaleler mükemmel değildir. Bir yabancının sizin dilinizde konuşurken yapabileceği hatalar gibi, makale; kelime dağarcığı, söz dizim kuralları veya dil bilgisi açısından yanlışlar içerebilir. Microsoft, içeriğin yanlış çevrimi veya onun müşteri tarafından kullanımından doğan; kusur, hata veya zarardan sorumlu değildir. Microsoft ayrıca makine çevirisi yazılımını sıkça güncellemektedir.
Makalenin İngilizcesi aşağıdaki gibidir:194975  (http://support.microsoft.com/kb/194975/en-us/ )