Tips SistemThis article applies to a different operating system than the one you are using. Article content that may not be relevant to you is disabled.
Untuk Microsoft Visual Basic.NET versi artikel ini, lihat 317034
(http://support.microsoft.com/kb/317034/EN-US/
)
.
Untuk Microsoft Visual Basic.NET versi artikel ini, lihat 316887
(http://support.microsoft.com/kb/316887/EN-US/
)
.
Artikel ini menjelaskan cara untuk membaca dan menulis objek-objek besar biner (BLOBs)
menggunakan metode GetChunk dan AppendChunk terhadap bidang dalam ADO. Itu juga
termasuk kode contoh menggunakan database contoh NWIND.
GetChunk dan AppendChunk metode yang bekerja dengan LongVarChar, LongVarWChar, dan
LongVarBinary kolom jenis, juga dikenal sebagai kolom teks, NTEXT, dan gambar, Microsoft SQL Server, dan sebagai bidang MEMO dan OLE di Microsoft Jet
database. Anda dapat mengidentifikasi ini kolom dalam ADO dengan menguji jenis
properti medan untuk nilai-nilai adLongVarChar, adLongVarWChar, dan adLongVarBinary. Anda juga bisa menguji properti atribut lapangan untuk bendera adFldLong:
If fld.Attributes And adFldLong Then
' You can use GetChunk/AppendChunk
Panjang kolom yang biasanya disebut sebagai gumpalan (biner besar OBjects) bahkan
Meskipun mereka mungkin berisi data teks. Contoh kode di bawah ini menyediakan dua
rutinitas, BlobToFile dan FileToBlob.
BlobToFile menentukan tipe data lapangan dan yang tiga metode
digunakan untuk menulis BLOB data ke disk file. Jika BLOB data kecil
cukup, itu akan referensi nilai bidang ini secara keseluruhan tanpa panggilan
GetChunk. Jika ukuran GUMPALAN tidak diketahui, itu akan memanggil WriteFromUnsizedBinary
atau WriteFromUnsizedText untuk menulis data. Ini kurang efisien dalam istilah
membuat salinan tambahan data di memori lokal daripada WriteFromBinary
dan WriteFromText rutinitas yang digunakan ketika ukuran BLOB data
dikenal:
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 menentukan apakah akan menggunakan AppendChunk atau langsung menetapkan
data untuk bidang GUMPALAN yang didasarkan pada ukuran file. Karena ukuran
file dapat selalu ditentukan, ada rutinitas "Unsized" tidak ada
berada dalam kode contoh BlobToFile:
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
Contoh kode untuk BlobToFile dan FileToBlob disimpan dalam modul, sementara
tes kode adalah di belakang bentuk standar. Tes kode menggunakan masing-masing
tiga metode untuk menyimpan ke disk foto (gambar/OLE/LongVarBinary) dan catatan
Bidang (teks/MEMO/LongVarChar/LongVarWChar) untuk Andrew Fuller dari tabel karyawan
database NWIND. Kemudian membaca file kembali dan menciptakan enam baru
Catatan, membaca masing-masing dari tiga set file melalui dua berbeda membaca
metode.CATATAN: Menggunakan ADO 2,1 dan belakangan, Anda mungkin melihat kesalahan berikut pada baris kode:
Data = fld.GetChunk(BLOCK_SIZE) :
Run-time error '94':
Invalid use of Null
ADO 2,1 dan kemudian mungkin laporan ActualSize properti dari lapangan GUMPALAN jenis teks sebagai dua kali jumlah karakter. Ini benar jika bidang GUMPALAN berisi Unicode
teks, karena menggunakan Unicode byte 2 per karakter. Ini salah jika bidang GUMPALAN
berisi teks ANSI, yang menggunakan 1-byte per karakter. Jika ActualSize adalah dua kali
panjang medan ANSI, kemudian GetChunk akhirnya mencoba untuk melewati
akhir bidang.
Anda dapat melihat perilaku ini dalam skenario berikut, dan mungkin melihatnya dalam skenario lain:
Skenario 1:
Dengan SQL Server 7 NTEXT lapangan (ANSI teks), menggunakan baik OLE DB penyedia untuk SQL Server atau penyedia ODBC dengan SQL Server ODBC driver.
Perhatikan bahwa menggunakan SQL Server teks lapangan (Unicode) bekerja dengan kedua penyedia.
Skenario 2:
Dengan akses 97 MEMO bidang dan dengan akses 2000 MEMO bidang dengan atau tanpa kompresi Unicode, menggunakan baik OLE DB penyedia untuk Jet 4.0 atau penyedia ODBC dengan pengandar Jet ODBC 4.0, ODBCJT32.DLL.
Perhatikan bahwa, dengan akses 97 MEMO bidang, baik OLE DB penyedia untuk Jet 3.51
dan penyedia ODBC dengan pengandar Jet ODBC 3.51 bekerja dengan benar.
Ada beberapa kemungkinan workarounds untuk galat Run-time '94':
Menggunakan rs.FieldName.ActualSize \ 2 bukannya rs.FieldName.ActualSize.
Ini memecahkan masing-masing skenario tertentu yang tercantum di atas.
Menggunakan metode 2 atau 3 di bawah ini, yang tidak bergantung pada ActualSize properti.
Membuat proyek Visual Basic baru dari proyek menu, pilih referensi dan pilih perpustakaan objek Data ActiveX Microsoft atau perpustakaan objek Data ActiveX Microsoft.
Menambahkan dua CommandButtons (cmdSave dan cmdLoad) untuk default form(Form1).
Tambahkan kode berikut. Anda akan memiliki untuk mengubah connect string
disediakan pada "cn.Buka"jalur:
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
Menambahkan modul baru untuk proyek (Module1) dengan kode berikut:
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
Menjalankan proyek dan klik tombol cmdSave.
Dalam c: \ direktori, Anda harus menemukan berkas berikut:
notes1.txt notes2.txt notes3.txt
photo1.dat photo2.dat photo3.dat
Tiga "foto" file harus ukuran yang sama dengan satu sama lain. Tiga "catatan" file harus ukuran yang sama dengan satu sama lain.
Klik tombol cmdLoad.
Buka database yang menggunakan akses dan Anda akan melihat enam tambahan
karyawan dengan foto dan catatan dimuat kembali dengan benar.
Berikut adalah beberapa saran untuk menggunakan BLOBs dengan ADO. Ini paralel
banyak saran di artikel Basis Pengetahuan Microsoft berikut:
153238
(http://support.microsoft.com/kb/153238/EN-US/
)
Cara menggunakan GetChunk dan metode AppendChunk RDO objek
Lebih efisien dari segi pengambilan data BLOB untuk hanya menyimpan
data dalam file pada server dengan pointer dalam catatan utama (atau
Anda dapat menggunakan beberapa jenis pemberian terstruktur direktori/nama file sistem berbasis
pada nilai kunci primer). Ini memiliki keuntungan menghilangkan ()
Server overhead, (b) memungkinkan file yang akan disimpan di server kedua,
(c) memungkinkan atribut keamanan jaringan diatur pada file individu,
dan (d) memungkinkan pengambilan file bahkan ketika server sedang down. Ini
terutama benar jika file semacam jenis dokumen, seperti
bitmaps (.bmp), pengolah kata file (.doc), atau spreadsheet (.xls)
di mana Anda dapat menunjukkan aplikasi host langsung ke file
server.
Ketika menggunakan penyedia tertentu, terutama ODBC SQL Server dan lainnya
database, Anda mungkin harus berhati-hati dalam mengambil BLOB data,
seperti menempatkan GUMPALAN kolom di akhir daftar bidang dan
referensi semua bidang non-GUMPALAN sebelum akses GUMPALAN kolom. Ini akan
tergantung pada beberapa faktor, seperti:
Penyedia (biasanya ODBC)
Back-end server
Kursor lokasi (biasanya klien)
Jenis kursor
Apakah Anda memilih dari pandangan atau mendapatkan catatan kembali dari
prosedur yang tersimpan.
Karena hal ini tergantung pada berbagai faktor, di bawah ini adalah panduan jika Anda
mengalami masalah dengan GUMPALAN kolom:
Mencoba penyedia OLE DB asli bukan penyedia ODBC.
Menggunakan Server-side kursor (seperti adOpenKeyset).
Pilih Primary Key column(s) Selain untuk kolom lain.
Pilih kolom GUMPALAN terakhir. Pilih setiap bidang, tidak "*".
Mengakses semua non-GUMPALAN kolom pertama (menyimpannya jika diperlukan).
Akses GUMPALAN kolom dalam urutan yang ditentukan. Anda mungkin hanya dapat
referensi sekali sebelum kursor kehilangan nilainya.
Sewaktu mengedit kolom GUMPALAN yang menggunakan AppendChunk metode, yang mungkin Anda miliki
untuk mengedit setidaknya satu non-GUMPALAN kolom dalam recordset Anda juga. Gumpalan
biasanya tidak updateable dengan statis atau hanya maju kursor pada
ODBC datasources.
Jika Anda menggunakan ODBC untuk Jet, Anda tidak dapat memperbarui recordset kembali oleh
disimpan prosedur (QueryDef) sama sekali karena pengandar memaksa mereka untuk
menjadi hanya-baca.
Microsoft Oracle OLE DB penyedia tidak saat ini mendukung acak
Akses ke data BLOB dengan sisi server kursor - GUMPALAN kolom harus
tampaknya akhir klausa pilih.
Dengan perpustakaan kursor ODBC, tidak mungkin untuk menggunakan GetChunk atau
AppendChunk metode pada recordset kembali dari prosedur yang disimpan. Ini
karena BLOB data tidak biasanya diperoleh dengan sisa
data untuk menghemat bandwidth. Ketika prosedur yang disimpan menciptakan
Recordset, pengandar kursor tidak bisa menentukan cara untuk query untuk GUMPALAN
data setelah fakta karena tidak dapat menentukan basis tabel atau kunci
Field untuk menggunakan. Server-side kursor mengurangi masalah ini tetapi membatasi Anda untuk
pernyataan satu per disimpan prosedur (SQL Server pembatasan).
Fakta bahwa pengguna ingin memperbarui kolom GUMPALAN mereka menuntut bahwa mereka
mengekspos meja dasar mereka dan membuat kursor dengan menggunakan standar pilih
pernyataan dari meja dasar. Ini akan menjadi benar bahkan jika Anda coding
langsung ke ODBC (bukan hal ADO).
PENTING: Artikel ini diterjemahkan menggunakan perangkat lunak mesin penerjemah Microsoft dan bukan oleh seorang penerjemah. Microsoft menawarkan artikel yang diterjemahkan oleh seorang penerjemah maupun artikel yang diterjemahkan menggunakan mesin sehingga Anda akan memiliki akses ke seluruh artikel baru yang diterbitkan di Pangkalan Pengetahuan (Knowledge Base) dalam bahasa yang Anda gunakan. Namun, artikel yang diterjemahkan menggunakan mesin tidak selalu sempurna. Artikel tersebut mungkin memiliki kesalahan kosa kata, sintaksis, atau tata bahasa, hampir sama seperti orang asing yang berbicara dalam bahasa Anda. Microsoft tidak bertanggung jawab terhadap akurasi, kesalahan atau kerusakan yang disebabkan karena kesalahan penerjemahan konten atau penggunaannya oleh para pelanggan. Microsoft juga sering memperbarui perangkat lunak mesin penerjemah.
Klik disini untuk melihat versi Inggris dari artikel ini:194975
(http://support.microsoft.com/kb/194975/en-us/
)
Seberapa besar upaya Anda untuk menggunakan artikel ini?
Sangat sedikit
Sedikit
Sedang
Besar
Sangat besar
Berikan saran tentang apa yang dapat kami lakukan untuk menyempurnakan informasi ini
Terima kasih! Masukan Anda akan digunakan untuk membantu kami meningkatkan konten dukungan. Untuk opsi bantuan lainnya, kunjungi Halaman Beranda Bantuan dan Dukungan.