Aracılığıyla paylaş


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/CByteArraybağlayın.

  • bir öğesine CLongBinarybağ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_Textiç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) CStringve ikili verileri (SQL_LONGVARBINARY) içine CByteArrayyerleş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 CByteArrayiç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 CStringSQL_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 CByteArrayile ilişkili olduğunda, alanın güncelleştirilmesi, SQL_VARCHAR veya SQL_VARBINARY ile aynı şekilde çalışır. sırasında Editveri 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 CLongBinaryalmayı 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ı CLongBinaryalı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ış HGLOBALiç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 HGLOBALdağı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ı SetFieldDirtyyapmanı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 SQLSetPosODBC 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 SQLExecDirectdöndürür. Bu, çerçeveyi bu sütun için param değerinin aslında adresinin CLongBinaryolduğ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 CRecordsetOpen 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.

Ayrıca bkz.

Sayıya Göre Teknik Notlar
Kategoriye Göre Teknik Notlar