TN045: Uzun Varchar/Varbinary için MFC/Veritabanı Desteği
Dekont
Aşağıdaki teknik not, çevrimiçi belgelere ilk kez eklendiğinden beri güncelleştirilmemiştir. Sonuç olarak, bazı yordamlar ve konular güncel olmayabilir veya yanlış olabilir. En son bilgiler için, çevrimiçi belge dizininde ilgilendiğiniz konuyu aramanız önerilir.
Bu not, MFC veritabanı sınıflarını kullanarak ODBC SQL_LONGVARCHAR ve SQL_LONGVARBINARY veri türlerini alma ve göndermeyi açıklar.
Uzun Varchar/Varbinary Desteğine Genel Bakış
ODBC SQL_LONG_VARCHAR ve SQL_LONGBINARY veri türleri (burada uzun veri sütunları olarak adlandırılır) çok büyük miktarda veri barındırabilir. Bu verileri işlemenin 3 yolu vardır:
bir öğesine
CString
/CByteArray
bağlayın.bir öğesine
CLongBinary
bağlayın.Hiç bağlamayın ve veritabanı sınıflarından bağımsız olarak uzun veri değerini el ile alıp göndermeyin.
Üç yöntemin her birinin avantajları ve dezavantajları vardır.
Uzun veri sütunları sorgu parametreleri için desteklenmez. Bunlar yalnızca outputColumns için desteklenir.
Uzun Veri Sütununu CString/CByteArray'ye Bağlama
Avantajlar:
Bu yaklaşımı anlamak kolaydır ve tanıdık sınıflarla çalışırsınız. Çerçeve ile DDX_Text
için CString
destek sağlarCFormView
. ve CByteArray
sınıflarıyla CString
birçok genel dize veya koleksiyon işlevine sahipsiniz ve veri değerini tutmak için yerel olarak ayrılan bellek miktarını denetleyebilirsiniz. Çerçeve, veya AddNew
işlev çağrıları sırasında Edit
alan verilerinin eski bir kopyasını tutar ve çerçeve sizin için verilerdeki değişiklikleri otomatik olarak algılayabilir.
Dekont
Karakter verileri üzerinde çalışmak ve CByteArray
ikili veriler üzerinde çalışmak için tasarlandığındanCString
, içine karakter verilerini (SQL_LONGVARCHAR) CString
ve ikili verileri (SQL_LONGVARBINARY) içine CByteArray
yerleştirmeniz önerilir.
ve için CString
CByteArray
RFX işlevleri, veri sütunu için alınan değeri tutmak üzere ayrılmış belleğin varsayılan boyutunu geçersiz kılmanıza olanak tanıyan ek bir bağımsız değişkene sahiptir. Aşağıdaki işlev bildirimlerinde nMaxLength bağımsız değişkenine dikkat edin:
void AFXAPI RFX_Text(CFieldExchange* pFX,
const char *szName,
CString& value,
int nMaxLength = 255,
int nColumnType =
SQL_VARCHAR);
void AFXAPI RFX_Binary(CFieldExchange* pFX,
const char *szName,
CByteArray& value,
int nMaxLength = 255);
veya CByteArray
içine uzun bir veri sütunu CString
alırsanız, döndürülen maksimum veri miktarı varsayılan olarak 255 bayttır. Bunun ötesindeki her şey yoksayılır. Bu durumda, çerçeve özel durum AFX_SQL_ERROR_DATA_TRUNCATED oluşturur. Neyse ki, nMaxLength değerini maxint değerine kadar daha büyük değerlere açıkça artırabilirsiniz.
Dekont
nMaxLength değeri MFC tarafından işlevin yerel arabelleğinin SQLBindColumn
ayarlanması için kullanılır. Bu, verilerin depolanması için yerel arabellektir ve ODBC sürücüsü tarafından döndürülen veri miktarını etkilemez. RFX_Text
ve RFX_Binary
arka uç veritabanından verileri almak için kullanarak SQLFetch
yalnızca bir çağrı yapın. Her ODBC sürücüsünün tek bir getirmede döndürebilecekleri veri miktarıyla ilgili farklı sınırlamaları vardır. Bu sınır nMaxLength'te ayarlanan değerden çok daha küçük olabilir ve bu durumda özel durum AFX_SQL_ERROR_DATA_TRUNCATED oluşturulur. Bu koşullar altında, tüm verilerin alınabilmesi için veya RFX_Binary
yerine RFX_Text
kullanmaya RFX_LongBinary
geçin.
ClassWizard sizin için bir SQL_LONGVARCHAR veya bir CString
SQL_LONGVARBINARY CByteArray
bağlar. Uzun veri sütununuzu aldığınız 255 bayttan fazlasını ayırmak istiyorsanız, nMaxLength için açık bir değer sağlayabilirsiniz.
Uzun bir veri sütunu veya CString
CByteArray
ile ilişkili olduğunda, alanın güncelleştirilmesi, SQL_VARCHAR veya SQL_VARBINARY ile aynı şekilde çalışır. sırasında Edit
veri değeri, veri değerindeki değişiklikleri algılamak ve sütun için Kirli ve Null değerlerini uygun şekilde ayarlamak üzere çağrıldığında Update
önbelleğe alınır ve daha sonra karşılaştırılır.
Uzun Veri Sütununu CLongBinary'ye Bağlama
Uzun veri sütununuz daha fazla MAXINT bayt verisi içeriyorsa, büyük olasılıkla içine CLongBinary
almayı düşünmelisiniz.
Avantajlar:
Bu, kullanılabilir belleğe kadar tüm uzun veri sütununu alır.
Dezavantajlar:
Veriler bellekte tutulur. Bu yaklaşım, çok büyük miktarlardaki veriler için de çok pahalıdır. Alanın bir Update
işleme dahil olduğundan emin olmak için ilişkili veri üyesini çağırmalısınızSetFieldDirty
.
içine uzun veri sütunları CLongBinary
alırsanız, veritabanı sınıfları uzun veri sütununun toplam boyutunu denetler ve ardından tüm veri değerini tutacak kadar büyük bir HGLOBAL
bellek kesimi ayırır. Veritabanı sınıfları daha sonra veri değerinin tamamını ayrılmış HGLOBAL
içine alır.
Veri kaynağı uzun veri sütununun beklenen boyutunu döndüremezse çerçeve özel durum AFX_SQL_ERROR_SQL_NO_TOTAL oluşturur. ayırma HGLOBAL
girişimi başarısız olursa, standart bir bellek özel durumu oluşturulur.
ClassWizard sizin için bir SQL_LONGVARCHAR veya SQL_LONGVARBINARY CLongBinary
bağlar. Üye Değişkeni Ekle iletişim kutusunda Değişken Türü olarak seçin CLongBinary
. ClassWizard daha sonra çağrınıza DoFieldExchange
bir RFX_LongBinary
çağrı ekler ve toplam ilişkili alan sayısını artırır.
Uzun veri sütunu değerlerini güncelleştirmek için, önce öğesinin m_hData üyesinde CLongBinary
::GlobalSize çağrısı yaparak ayrılanın HGLOBAL
yeni verilerinizi barındıracak kadar büyük olduğundan emin olun. Çok küçükse, serbest bırakın HGLOBAL
ve uygun boyutta bir tane ayırın. Ardından m_dwDataLength yeni boyutu yansıtacak şekilde ayarlayın.
Aksi takdirde, m_dwDataLength değiştirdiğiniz verilerin boyutundan büyükse, serbest bırakabilir ve yeniden HGLOBAL
dağıtabilir veya ayrılmış olarak bırakabilirsiniz. m_dwDataLength gerçekte kullanılan bayt sayısını belirttiğinizden emin olun.
CLongBinary Güncelleştirme Nasıl Çalışır?
Bir güncelleştirmenin CLongBinary
nasıl çalıştığını anlamak gerekmez, ancak aşağıda açıklanan bu üçüncü yöntemi seçerseniz, bir veri kaynağına uzun veri değerlerinin nasıl gönderileceğine ilişkin bir örnek olarak yararlı olabilir.
Dekont
Bir alanın güncelleştirmeye CLongBinary
dahil edilmesi için, alanı açıkça çağırmanız SetFieldDirty
gerekir. Bir alanda Null olarak ayarlamak da dahil olmak üzere herhangi bir değişiklik yaparsanız çağrısı SetFieldDirty
yapmanız gerekir. Ayrıca, alanı bir değere sahip olarak işaretlemek için ikinci parametre YANLIŞ olarak çağırmalısınızSetFieldNull
.
Bir CLongBinary
alanı güncelleştirirken veritabanı sınıfları ODBC'nin DATA_AT_EXEC mekanizmasını kullanır ('nin rgbValue bağımsız değişkeniyle ilgili SQLSetPos
ODBC belgelerine bakın). Çerçeve, verileri içerene işaret etmek HGLOBAL
yerine insert veya update deyimini hazırladığında, öğesinin CLongBinary
adresi sütunun değeri olarak, uzunluk göstergesi ise SQL_DATA_AT_EXEC olarak ayarlanır. Daha sonra, güncelleştirme deyimi veri kaynağına gönderildiğinde SQL_NEED_DATA SQLExecDirect
döndürür. Bu, çerçeveyi bu sütun için param değerinin aslında adresinin CLongBinary
olduğu konusunda uyarır. Çerçeve küçük bir arabellekle bir kez çağrılar SQLGetData
ve sürücünün verilerin gerçek uzunluğunu döndürmesini bekler. Sürücü ikili büyük nesnenin (BLOB) gerçek uzunluğunu döndürürse, MFC BLOB'u getirmek için gereken kadar alanı yeniden ayırır. Veri kaynağı blobun boyutunu belirleyemediğini belirten SQL_NO_TOTAL döndürürse, MFC daha küçük bloklar oluşturur. Varsayılan başlangıç boyutu 64K'dır ve sonraki bloklar boyutun iki katı olur; örneğin, ikinci 128K, üçüncü 256K vb. olur. İlk boyut yapılandırılabilir.
Bağlama Değil: SQLGetData ile Doğrudan ODBC'den Veri Alma/Gönderme
Bu yöntemle veritabanı sınıflarını tamamen atlar ve uzun veri sütunuyla kendiniz ilgilenirsiniz.
Avantajlar:
Gerekirse verileri diskte önbelleğe alabilir veya ne kadar veri alınabileceğine dinamik olarak karar vekleyebilirsiniz.
Dezavantajlar:
Çerçevenin Edit
veya AddNew
desteğin alınmaz ve temel işlevleri gerçekleştirmek için kendiniz kod yazmanız gerekir (Delete
sütun düzeyinde bir işlem olmadığından çalışır).
Bu durumda, uzun veri sütunu kayıt kümesinin seçme listesinde olmalıdır, ancak çerçeveye bağlı olmamalıdır. Bunu gerçekleştirmenin bir yolu, işlevine lpszSQL bağımsız değişkeni CRecordset
Open
olarak veya aracılığıyla GetDefaultSQL
kendi SQL deyiminizi sağlamak ve fazladan sütunu bir RFX_ işlev çağrısıyla bağlamamaktır. ODBC, ilişkili alanların sağındaki ilişkisiz alanların gösterilmesini gerektirir, bu nedenle ilişkisiz sütununuzu veya sütunlarınızı seçim listesinin sonuna ekleyin.
Dekont
Uzun veri sütununuz çerçeveye bağlı olmadığından, bu sütunda yapılan değişiklikler çağrılarla CRecordset::Update
işlenmez. Gerekli SQL INSERT ve UPDATE deyimlerini kendiniz oluşturup göndermeniz gerekir.