2016-04-04 21 views
1

'MyDB' adlı MS SQL Server veritabanına bağlanmak için SQLDriverConnect numaralı çağrıları yapan bir uygulama oluşturdum. Bazı şeyler yaptıktan sonra SQLDisconnect.But çağırır, ancak SSMS 'MyDB' silmek başarısız olur. Bu, bazı kaynakların düzgün kapatılmadığı anlamına gelir. Sadece işlemden çıktıktan sonra SSMS bunu siler (, yani işletim sistemi bunları serbest bırakır) ve tüm SQLHENV ve SQLHDBC düzgün bir şekilde yayınlanır. Aşağıdaki Kodu:ODBC nesnelerini doğru şekilde nasıl bırakılır?

SMARTHSTMT::~SMARTHSTMT() 
{ 
    if (!m_hstmt) return; 
    SQLFreeStmt(m_hstmt, SQL_CLOSE); 
    SQLFreeStmt(m_hstmt, SQL_UNBIND); 
    SQLFreeStmt(m_hstmt, SQL_RESET_PARAMS); 
    SQLFreeHandle(SQL_HANDLE_STMT, m_hstmt); 
    m_hstmt = nullptr; 
}; 

nasıl serbest bırakılmaz hangi nesne bulabilirim? Almam gereken başka bir husus var mı? herhangi bir fikir veya yardım takdir. Düzenleme: Ayrılma için kod:

void AConnection::uDisconnect() 
{ 
    if (m_hdbc) 
    { 
     SQLDisconnect(m_hdbc); 
     SQLFreeHandle(SQL_HANDLE_DBC, m_hdbc); 
     m_hdbc = nullptr; 
    } 
    if (m_henv) 
    { 
     SQLFreeHandle(SQL_HANDLE_ENV, m_henv); 
     m_henv = nullptr; 
    } 
} 
+0

SQLDisconnect sonucu nedir: Belki .. SQL Server Side araçları o anda tam olarak açık ne olduğu konusunda daha fazla ayrıntı analiz etmek

fazla bilgi için buraya bakınız olsun? Gönderdiğiniz kod yalnızca açıklama-işleyiciyi serbest bırakmak, bağlantı ve çevre işleyişi hakkında ne var? – erg

+0

SQLFreeHandle kullanarak serbest bırakıldılar. Sadece ifadeleri yok etmek için kod yayınladım, çünkü ifadeler yaygın olarak kullanılıyor ve bunları serbest bırakmak oldukça olası. –

+0

Bağlantı tanıtıcısını serbest bırakırsanız, bu bağlantı tanıtıcısından kaynaklanan açık bildirim tutamaçları varsa, SQLERROR değerini dönüş değeri olarak almalısınız, değil mi? – erg

cevap

0

Sen eğer SQLDisconnect() döner SQL_ERROR kontrol edebilirsiniz. Bu durumda, bir ifade hala açık olabilir veya (algılandığınız gibi) bir işlem hala açık olabilir. ODBC Handling

İşlem böyle (basitleştirilmiş) olduğu: Varsayılan olarak

otomatik kesinleştirme etkindir. Her şey yeni bir işlem başlatır ve ifade başarılı olursa, işlem gerçekleştirilir. İşlem modunu değiştirmediyseniz, işlemin hala açık olduğu benim için kafa karıştırıcı.

Otomatik yanıtlamayı devre dışı bıraktıysanız, devam etmekte olan herhangi bir işlemi yapmak veya geri almak için el ile SQLEndTrans(...) numaralı telefonu aramanız gerekir. Bildiğim kadarıyla, herhangi bir işlem hala açıksa, ODBC'de sürücüyü sorgulamanın bir yolu yoktur.

SQLEndTrans() numaralı çağrılardan bahsetmişken, otomatik işlemeyi zaten devre dışı bırakmışsınızdır. Kaynaklarıma baktığımda, bir bağlantı sapını kapatmadan önce her zaman Rollback yaptığımı görüyorum - belki de aynı sorun nedeniyle, tam olarak hatırlamıyorum (eski kodu).

Her neyse, el ile işlem modunu etkinleştirdiyseniz, yalnızca bağlantı tanıtıcısını kapatmadan önce Geri Alma işlemini yapmanız önerilir. https://msdn.microsoft.com/en-us/library/ms131281.aspx

+0

Teşekkürler. Cevabınız çok açık ve kullanışlı. Tahmin ettiğiniz gibi, otomatik taahhütleri devre dışı bırakıyorum ve işlem yapmak veya geri almak için SQLEndTrans'ı çağırıyorum. ve ben de SQLDisconnect için geri dönmeye karar verdim. Bu benim son sorum: SQLColumns, SQLTables, SQLStatistics gibi ifadeler neden bir işlem başlatıyor? –

+0

@MohamadrezaAbdolahzadeh: Katalog işlevlerinin neden bir işlem başlattığı konusunda hiçbir fikrim yok. Bence aynı sorunla uğraştım ve herhangi bir yararlı çözüm bulamadım. Belki de bu, tek başına bir soru olarak eklemeye değer olurdu. – erg

İlgili konular