หมายเหตุนี้อธิบายถึงวิธีการรับ และส่งชนิดข้อมูล ODBC SQL_LONGVARCHARและSQL_LONGVARBINARYที่ใช้เรียนในฐานข้อมูล MFC?
ภาพรวมของความยาว Varchar/Varbinary สนับสนุน
ชนิดข้อมูล ODBC SQL_LONG_VARCHARและSQL_LONGBINARYที่ (เรียกที่นี่ว่าคอลัมน์ข้อมูลนาน) สามารถเก็บข้อมูลขนาดใหญ่จำนวน มี 3 วิธีที่คุณสามารถจัดการกับข้อมูลนี้:
คอลัมน์ข้อมูลยาวไม่ได้รับการสนับสนุนสำหรับพารามิเตอร์ในแบบสอบถาม พวกเขาจะสนับสนุนสำหรับ outputColumns?
ผูกคอลัมน์ข้อมูลยาวกับ CString/CByteArray
ข้อดี:
วิธีนี้คือง่ายต่อการเข้าใจ และทำงานกับการเรียนที่คุ้นเคย กรอบแสดงการสนับสนุนCFormView CStringกับDDX_Text คุณมีหลายสายทั่วไปหรือฟังก์ชันการทำงานรวบรวม ด้วยCStringและCByteArrayชั้น และคุณสามารถควบคุมจำนวนของหน่วยความจำในการปันส่วนการเก็บค่าข้อมูลภายในเครื่อง กรอบเก็บสำเนาเก่าของข้อมูลของเขตข้อมูลในระหว่างแก้ไขหรือการเรียกฟังก์ชันAddNewและกรอบสามารถตรวจสอบการเปลี่ยนแปลงข้อมูลสำหรับคุณ?
หมายเหตุnbsp เนื่องจากการออกแบบมาสำหรับการทำงานบนอักขระข้อมูล และCByteArrayสำหรับทำงานกับข้อมูลไบนารีCStringขอแนะนำว่า คุณใส่อักขระข้อมูล (SQL_LONGVARCHAR) CStringและข้อมูลฐานสอง (SQL_LONGVARBINARY) ในCByteArray(&N)?
ฟังก์ชัน RFX การCStringและCByteArrayมีอาร์กิวเมนต์เพิ่มเติมซึ่งช่วยให้คุณสามารถแทนที่ค่าเริ่มต้นขนาดของหน่วยความจำที่จัดสรรไว้เพื่อเก็บค่าสำหรับคอลัมน์ข้อมูลดึงข้อมูล หมายเหตุอาร์กิวเมนต์ nMaxLength ในการประกาศฟังก์ชันต่อไปนี้:
โมฆะ AFXAPI RFX_Text(CFieldExchange* pFX, const char *szName,
nbsp CString & ค่า int nMaxLength = 255, int nColumnType =
SQL_VARCHAR);
โมฆะ AFXAPI RFX_Binary(CFieldExchange* pFX, const char *szName, CByteArray& value,int nMaxLength = 255)
ถ้าคุณเรียกใช้คอลัมน์ข้อมูลยาวลงในCStringหรือCByteArrayสูงสุดส่งกลับจำนวนของข้อมูลเป็น ตามค่าเริ่มต้น 255 ไบต์ อะไรที่นอกเหนือจากนี้จะถูกละเว้น ในกรณีนี้ กรอบจะโยนข้อยกเว้นAFX_SQL_ERROR_DATA_TRUNCATED โชคดี คุณสามารถอย่างชัดเจนเพิ่ม nMaxLength มากกว่าค่า ถึงMAXINT?
ClassWizard จะผูกกับSQL_LONGVARCHARกับCStringหรือSQL_LONGVARBINARYไปCByteArrayสำหรับคุณ ถ้าคุณต้องการปันส่วนมากกว่า 255 ไบต์ที่คุณดึงข้อมูลคอลัมน์ความยาวข้อมูลของคุณ คุณสามารถแล้วใส่ค่าชัดเจนสำหรับ nMaxLength?
เมื่อคอลัมน์ข้อมูลยาวผูกไว้ไปยังCStringหรือCByteArrayปรับปรุงเขตข้อมูลงานเดียวเพียงกันเป็นเมื่อนั้นถูกผูกไว้กับ SQL_VARCHARหรือ SQL_VARBINARY ระหว่างแก้ไขค่าข้อมูลเก็บแค และเปรียบเทียบในภายหลังเมื่อมีการปรับปรุงจะเรียกว่าการตรวจพบการเปลี่ยนแปลงค่าข้อมูล และตั้งค่าสำหรับคอลัมน์ที่สกปรกและ Null อย่างเหมาะสม?
ผูกคอลัมน์ข้อมูลยาวไป CLongBinary
ถ้าคอลัมน์ข้อมูลที่ยาวนานของคุณอาจประกอบด้วยเพิ่มเติมMAXINTไบต์ของข้อมูล คุณคงควรพิจารณาการเรียกไปยังCLongBinary?
ข้อดี:
นี้ดึงข้อมูลยาวทั้งคอลัมน์ที่มี - ถึงหน่วยความจำที่มีอยู่?
ข้อเสีย:
ข้อมูลถูกเก็บไว้ในหน่วยความจำ นอกจากนี้วิธีการนี้ยังเป็น prohibitively แพงสำหรับจำนวนข้อมูลที่มีขนาดใหญ่มาก คุณต้องเรียกใช้SetFieldDirtyสำหรับสมาชิกถูกผูกไว้ข้อมูลเพื่อให้แน่ใจว่า เขตข้อมูลรวมอยู่ในการดำเนินการปรับปรุง?
ถ้าคุณเรียกใช้คอลัมน์ข้อมูลยาวเป็นแบบCLongBinaryคลาสที่ฐานข้อมูลจะตรวจสอบขนาดทั้งหมดของคอลัมน์ข้อมูลยาว แล้วจัดสรรส่วนหน่วยความจำHGLOBALมีขนาดใหญ่พอที่จะเก็บค่าข้อมูลทั้งหมด คลาสที่ฐานข้อมูลแล้วเรียกค่าข้อมูลทั้งหมดลงในการจัดสรรHGLOBAL?
ถ้าแหล่งข้อมูลไม่สามารถส่งกลับที่คาดว่าขนาดของคอลัมน์ข้อมูลยาว กรอบจะโยนข้อยกเว้นAFX_SQL_ERROR_SQL_NO_TOTAL หากความพยายามในการจัดสรรHGLOBALล้มเหลว มีข้อยกเว้นของหน่วยความจำมาตรฐานถูกส่งออกไป?
ClassWizard จะผูกSQL_LONGVARCHARหรือSQL_LONGVARBINARYเป็นCLongBinaryสำหรับคุณ เลือกCLongBinaryเป็นชนิดตัวแปรในกล่องโต้ตอบเพิ่มสมาชิกตัวแปร ClassWizard จะเพิ่มการเรียกRFX_LongBinaryในการเรียกDoFieldExchangeของคุณ และเพิ่มจำนวนของเขตข้อมูลที่ถูกผูกไว้แล้ว?
การปรับปรุงค่าค่าคอลัมน์ข้อมูลนาน ตรวจสอบว่า ปันส่วนHGLOBALมีขนาดใหญ่พอที่จะเก็บข้อมูลใหม่ของคุณได้ โดยการเรียก:: GlobalSizeบนสมาชิกm_hDataของการCLongBinary ถ้ามีขนาดเล็กเกินไป ปล่อยHGLOBALและปันส่วนหนึ่งในขนาดเหมาะสม แล้ว ตั้งค่าm_dwDataLengthเพื่อแสดงขนาดใหม่?
มิฉะนั้น ถ้าm_dwDataLengthจะใหญ่กว่าขนาดของข้อมูลคุณกำลังแทน คุณสามารถฟรี และปันส่วนใหม่HGLOBALหรือทิ้งไว้จัดสรร ทำให้แน่ใจว่าได้ระบุจำนวนของไบต์ที่ใช้จริง ในm_dwDataLength?
CLongBinary เป็นการปรับปรุงวิธีทำงาน
คุณไม่จำเป็นต้องเข้าใจวิธีการปรับปรุงการCLongBinaryงาน แต่มันอาจเป็นประโยชน์เป็นตัวอย่างวิธีการส่งค่าความยาวของข้อมูลไปยังแหล่งข้อมูล ถ้าคุณเลือกวิธีนี้สาม อธิบายไว้ด้านล่าง?
หมายเหตุnbsp ในใบสั่งสำหรับเขตข้อมูลที่จะรวมในการปรับปรุงCLongBinaryคุณอย่างชัดเจนต้องเรียกSetFieldDirtyสำหรับเขตข้อมูล ถ้าคุณทำการเปลี่ยนแปลงใด ๆ ไปยังเขตข้อมูล รวมถึงการตั้งค่า Null คุณต้องเรียกใช้SetFieldDirty(&N)?
เมื่อต้องการปรับปรุงเขตข้อมูลCLongBinaryฐานข้อมูลคลาสที่ใช้กลไกการDATA_AT_EXECของ ODBC (โปรดดูเอกสารประกอบของ ODBC ในอาร์กิวเมนต์ rgbValue SQLSetPosของ) เมื่อกรอบงานเตรียมการแทรก หรือปรับปรุงงบ แทนที่จะชี้ไปที่HGLOBALที่ประกอบด้วยข้อมูลอยู่ของCLongBinaryถูกตั้งค่าเป็นค่าของคอลัมน์แทน และตัวบ่งชี้ความยาวตั้งSQL_DATA_AT_EXEC ภายหลัง เมื่องบการปรับปรุงถูกส่งไปยังแหล่งข้อมูลSQLExecDirectจะกลับSQL_NEED_DATA เตือนนี้ถึงกรอบค่าของพารามิเตอร์สำหรับคอลัมน์นี้ว่าจริง ๆ แล้วอยู่CLongBinary กรอบเรียกSQLGetDataครั้งเดียวกับบัฟเฟอร์ขนาดเล็ก ต้องการโปรแกรมควบคุมที่จะส่งกลับค่าความยาวของข้อมูลแท้จริง ถ้าโปรแกรมควบคุมที่ส่งกลับค่าความยาวที่แท้จริงของวัตถุขนาดใหญ่แบบไบนารี (BLOB), MFC reallocates เนื้อที่มากตามความจำเป็นในการดึงตัว BLOB ถ้าแหล่งข้อมูลส่งกลับSQL_NO_TOTALระบุว่า ไม่สามารถระบุขนาดของ BLOB, MFC จะสร้างบล็อกที่มีขนาดเล็กลง ขนาดเริ่มต้นค่าเริ่มต้น 64 K และบล็อกที่ตามมาจะเป็นคู่ขนาด ตัวอย่างเช่น ที่สองจะเป็น 128 K ที่สามเป็น 256 K และอื่น ๆ ขนาดเริ่มต้นจะสามารถกำหนดค่า?
ไม่ผูก: รับ/ส่งข้อมูลโดยตรงจาก ODBC กับ SQLGetData
ด้วยวิธีนี้ คุณสมบูรณ์ข้ามคลาสที่ฐานข้อมูล และจัดการกับคอลัมน์ข้อมูลยาวด้วยตัวคุณเอง?
ข้อดี:
คุณสามารถใช้แคชกับข้อมูลดิสก์ถ้าจำเป็น หรือตัดสินใจว่า ข้อมูลแบบไดนามิกเท่าใดในการเรียก?
ข้อเสีย:
คุณไม่ได้รับของกรอบการแก้ไขหรือการสนับสนุนAddNewและคุณต้องเขียนโค้ดเองเพื่อดำเนินการฟังก์ชันพื้นฐาน (ลบทำงานแม้ว่า เนื่องจากไม่ใช่การดำเนินการระดับคอลัมน์)?
ในกรณีนี้ คอลัมน์ข้อมูลยาวต้องอยู่ในรายการเลือกของชุดระเบียน แต่จะไม่สามารถผูกเข้ากับโดยกรอบ วิธีหนึ่งในการทำเช่นนี้คือการ ใส่คำสั่ง SQL ของคุณเองผ่านทางGetDefaultSQLหรือ เป็นอาร์กิวเมนต์ lpszSQL CRecordsetของเปิดฟังก์ชัน และผูกคอลัมน์พิเศษ ด้วยการเรียกฟังก์ชัน RFX_ ไม่ ODBC ต้องการให้เขตข้อมูลที่ไม่ถูกผูกไว้ปรากฏทางด้านขวาของเขตข้อมูลที่ถูกผูกไว้ เพื่อ เพิ่มคอลัมน์ของคุณไม่ถูกผูกไว้ส่วนท้ายของรายการเลือก?
คำเตือนnbsp เนื่องจากคอลัมน์ความยาวข้อมูลของคุณไม่ถูกผูกไว้ตามกรอบ การเปลี่ยนแปลงดังกล่าวจะไม่ถูกจัดการกับสายCRecordset::Update คุณต้องสร้าง และส่งคำสั่ง SQL ที่แทรกและการปรับปรุงที่จำเป็นด้วยตัวคุณเอง(&N)?
หมายเหตุด้านเทคนิคตามหมายเลข|nbsp หมายเหตุด้านเทคนิคตามประเภท(&N)