Bagikan melalui


Mendapatkan Data Panjang

DBMS mendefinisikan data panjang sebagai karakter atau data biner apa pun dalam ukuran tertentu, seperti 255 karakter. Data ini mungkin cukup kecil untuk disimpan dalam satu buffer, seperti deskripsi bagian dari beberapa ribu karakter. Namun, mungkin terlalu lama untuk disimpan dalam memori, seperti dokumen teks panjang atau bitmap. Karena data tersebut tidak dapat disimpan dalam satu buffer, data diambil dari driver di bagian dengan SQLGetData setelah data lain dalam baris diambil.

Catatan

Aplikasi benar-benar dapat mengambil semua jenis data dengan SQLGetData, bukan hanya data panjang, meskipun hanya karakter dan data biner yang dapat diambil di beberapa bagian. Namun, jika data cukup kecil agar pas dalam satu buffer, umumnya tidak ada alasan untuk menggunakan SQLGetData. Jauh lebih mudah untuk mengikat buffer ke kolom dan membiarkan driver mengembalikan data di buffer.

Untuk mengambil data panjang dari kolom, aplikasi terlebih dahulu memanggil SQLFetchScroll atau SQLFetch untuk berpindah ke baris dan mengambil data untuk kolom terikat. Aplikasi kemudian memanggil SQLGetData. SQLGetData memiliki argumen yang sama dengan SQLBindCol: handel pernyataan; nomor kolom; tipe data C, alamat, dan panjang byte variabel aplikasi; dan alamat buffer panjang/indikator. Kedua fungsi memiliki argumen yang sama karena pada dasarnya melakukan tugas yang sama: Keduanya menjelaskan variabel aplikasi ke driver dan menentukan bahwa data untuk kolom tertentu harus dikembalikan dalam variabel tersebut. Perbedaan utamanya adalah bahwa SQLGetData dipanggil setelah baris diambil (dan kadang-kadang disebut sebagai pengikatan terlambat karena alasan ini) dan bahwa pengikatan yang ditentukan oleh SQLGetData hanya berlangsung selama durasi panggilan.

Mengenai satu kolom, SQLGetData berulah seperti SQLFetch: Ini mengambil data untuk kolom, mengonversinya ke jenis variabel aplikasi, dan mengembalikannya dalam variabel tersebut. Ini juga mengembalikan panjang byte data dalam buffer panjang/indikator. Untuk informasi selengkapnya tentang cara SQLFetch mengembalikan data, lihat Mengambil Baris Data.

SQLGetData berbeda dari SQLFetch dalam satu hal penting. Jika dipanggil lebih dari sekali berturut-turut untuk kolom yang sama, setiap panggilan mengembalikan bagian berturut-turut dari data. Setiap panggilan kecuali panggilan terakhir mengembalikan SQL_SUCCESS_WITH_INFO dan SQLSTATE 01004 (Data string, terpotong kanan); panggilan terakhir mengembalikan SQL_SUCCESS. Ini adalah cara SQLGetData digunakan untuk mengambil data panjang di beberapa bagian. Ketika tidak ada lagi data yang akan dikembalikan, SQLGetData mengembalikan SQL_NO_DATA. Aplikasi ini bertanggung jawab untuk menggabungkan data panjang, yang mungkin berarti menggabungkan bagian data. Setiap bagian dihentikan null; aplikasi harus menghapus karakter penghentian null jika menggabungkan bagian. Mengambil data dalam beberapa bagian dapat dilakukan untuk bookmark panjang variabel serta untuk data panjang lainnya. Nilai yang dikembalikan dalam buffer panjang/indikator menurun dalam setiap panggilan dengan jumlah byte yang dikembalikan dalam panggilan sebelumnya, meskipun umum bagi driver untuk tidak dapat menemukan jumlah data yang tersedia dan mengembalikan panjang byte SQL_NO_TOTAL. Misalnya:

// Declare a binary buffer to retrieve 5000 bytes of data at a time.  
SQLCHAR       BinaryPtr[5000];  
SQLUINTEGER   PartID;  
SQLINTEGER    PartIDInd, BinaryLenOrInd, NumBytes;  
SQLRETURN     rc;   
SQLHSTMT      hstmt;  
  
// Create a result set containing the ID and picture of each part.  
SQLExecDirect(hstmt, "SELECT PartID, Picture FROM Pictures", SQL_NTS);  
  
// Bind PartID to the PartID column.  
SQLBindCol(hstmt, 1, SQL_C_ULONG, &PartID, 0, &PartIDInd);  
  
// Retrieve and display each row of data.  
while ((rc = SQLFetch(hstmt)) != SQL_NO_DATA) {  
   // Display the part ID and initialize the picture.  
   DisplayID(PartID, PartIDInd);  
   InitPicture();  
  
   // Retrieve the picture data in parts. Send each part and the number   
   // of bytes in each part to a function that displays it. The number   
   // of bytes is always 5000 if there were more than 5000 bytes   
   // available to return (cbBinaryBuffer > 5000). Code to check if   
   // rc equals SQL_ERROR or SQL_SUCCESS_WITH_INFO not shown.  
   while ((rc = SQLGetData(hstmt, 2, SQL_C_BINARY, BinaryPtr, sizeof(BinaryPtr),  
                           &BinaryLenOrInd)) != SQL_NO_DATA) {  
      NumBytes = (BinaryLenOrInd > 5000) || (BinaryLenOrInd == SQL_NO_TOTAL) ?  
                  5000 : BinaryLenOrInd;  
      DisplayNextPictPart(BinaryPtr, NumBytes);  
   }  
}  
  
// Close the cursor.  
SQLCloseCursor(hstmt);  

Ada beberapa batasan dalam menggunakan SQLGetData. Umumnya, kolom yang diakses dengan SQLGetData:

  • Harus diakses dalam urutan penambahan nomor kolom (karena cara kolom kumpulan hasil dibaca dari sumber data). Misalnya, ini adalah kesalahan untuk memanggil SQLGetData untuk kolom 5 lalu memanggilnya untuk kolom 4.

  • Tidak dapat terikat.

  • Harus memiliki nomor kolom yang lebih tinggi dari kolom terikat terakhir. Misalnya, jika kolom terikat terakhir adalah kolom 3, itu adalah kesalahan untuk memanggil SQLGetData untuk kolom 2. Untuk alasan ini, aplikasi harus memastikan untuk menempatkan kolom data panjang di akhir daftar pilihan.

  • Tidak dapat digunakan jika SQLFetch atau SQLFetchScroll dipanggil untuk mengambil lebih dari satu baris. Untuk informasi selengkapnya, lihat Menggunakan Kursor Blok.

Beberapa driver tidak memberlakukan pembatasan ini. Aplikasi yang dapat dioperasikan harus mengasumsikan ada atau menentukan batasan mana yang tidak diberlakukan dengan memanggil SQLGetInfo dengan opsi SQL_GETDATA_EXTENSIONS.

Jika aplikasi tidak memerlukan semua data dalam karakter atau kolom data biner, aplikasi dapat mengurangi lalu lintas jaringan di driver berbasis DBMS dengan mengatur atribut pernyataan SQL_ATTR_MAX_LENGTH sebelum menjalankan pernyataan. Ini membatasi jumlah byte data yang akan dikembalikan untuk setiap karakter atau kolom biner. Misalnya, misalkan kolom berisi dokumen teks panjang. Aplikasi yang menelusuri tabel yang berisi kolom ini mungkin hanya harus menampilkan halaman pertama dari setiap dokumen. Meskipun atribut pernyataan ini dapat disimulasikan dalam driver, tidak ada alasan untuk melakukan ini. Secara khusus, jika aplikasi ingin memotong karakter atau data biner, aplikasi harus mengikat buffer kecil ke kolom dengan SQLBindCol dan membiarkan driver memotong data.