CDynamicAccessor sınıfı almak veya bir Unicode dize sütunu (örneğin, bir SQL Server 7.0 nchar alanı), birkaç olası hata değerlerini ayarlamak için veya kullandığınızda aşağıdaki belirtilerden oluşabilir:
SetData ' i ça??rd???n?zda, DB_E_ERRORSOCCURED döndürülür.
Uygulama (Bu bağlantı, bir kısmı veya tamamı ingilizce olan içeriğe işaret edebilir.) yanıt vermiyor.
CDynamicAccessor dize tutmak için yeterli depolama alanı oluşturmaz. Arabellek için gereken uzunluğu almak için sütun bilgileri ulColumnSize üyesi CDynamicAccessor kullanır. Ancak, bu yöntem için alanın bayt sayısını değil karakter sayısını verir. Unicode dizesi tutmak için gerekli olan bayt sayısını elde etmek için 2 ile [sizeof(WCHAR)] çarpımı (alan için karakter sayısı), bu değer gerekir.
Ayrıca, aşağıdaki işlevleri doğru parçaları için (uzunluğu ve durumu) mahsup hesapla değil:
Bu soruna geçici bir çözüm bulmak için <a0></a0>, CDynamicAccessor yeni bir sınıf türetme yapıp yapmayacağınızı ve gerekli işlevleri DBTYPE_WSTR sütun karşılaştı her ulColumnSize 2 ile çarpılarak düzeltin.
Aşağıdaki örnek kod, sınıfın nasıl ortaya çıkabilecek bir örnektir:
class CDynAccessor: public CDynamicAccessor
{
public:
bool GetStatus(ULONG nColumn, DBSTATUS* pStatus) const
{
ATLASSERT(pStatus != NULL);
if (TranslateColumnNo(nColumn))
{
if (DBTYPE_WSTR == m_pColumnInfo[nColumn].wType)
*pStatus = *(ULONG*)(AddOffset(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize*sizeof(WCHAR)), sizeof(ULONG)));
else
*pStatus = *(ULONG*)(AddOffset(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize), sizeof(ULONG)));
return true;
}
else
return false;
}
bool GetStatus(TCHAR* pColumnName, DBSTATUS* pStatus) const
{
ATLASSERT(pColumnName != NULL);
ATLASSERT(pStatus != NULL);
ULONG nColumn;
if (GetInternalColumnNo(pColumnName, &nColumn))
{
if (DBTYPE_WSTR == m_pColumnInfo[nColumn].wType)
*pStatus = *(ULONG*)(AddOffset(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize*sizeof(WCHAR)), sizeof(ULONG)));
else
*pStatus = *(ULONG*)(AddOffset(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize), sizeof(ULONG)));
return true;
}
else
return false;
}
bool SetStatus(ULONG nColumn, DBSTATUS status)
{
if (TranslateColumnNo(nColumn))
{
if (DBTYPE_WSTR == m_pColumnInfo[nColumn].wType)
*(ULONG*)(AddOffset(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize*sizeof(WCHAR)), sizeof(ULONG))) = status;
else
*(ULONG*)(AddOffset(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize), sizeof(ULONG))) = status;
return true;
}
else
return false;
}
bool SetStatus(TCHAR* pColumnName, DBSTATUS status)
{
ATLASSERT(pColumnName != NULL);
ULONG nColumn;
if (GetInternalColumnNo(pColumnName, &nColumn))
{
if (DBTYPE_WSTR == m_pColumnInfo[nColumn].wType)
*(ULONG*)(AddOffset(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize*sizeof(WCHAR)), sizeof(ULONG))) = status;
else
*(ULONG*)(AddOffset(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize), sizeof(ULONG))) = status;
return true;
}
else
return false;
}
bool GetLength(ULONG nColumn, ULONG* pLength) const
{
ATLASSERT(pLength != NULL);
if (TranslateColumnNo(nColumn))
{
if (DBTYPE_WSTR == m_pColumnInfo[nColumn].wType)
*pLength = *(ULONG*)(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize*sizeof(WCHAR)));
else
*pLength = *(ULONG*)(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize));
return true;
}
else
return false;
}
bool GetLength(TCHAR* pColumnName, ULONG* pLength) const
{
ATLASSERT(pColumnName != NULL);
ATLASSERT(pLength != NULL);
ULONG nColumn;
if (GetInternalColumnNo(pColumnName, &nColumn))
{
if (DBTYPE_WSTR == m_pColumnInfo[nColumn].wType)
*pLength = *(ULONG*)(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize*sizeof(WCHAR)));
else
*pLength = *(ULONG*)(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize));
return true;
}
else
return false;
}
bool SetLength(ULONG nColumn, ULONG nLength)
{
if (TranslateColumnNo(nColumn))
{
if (DBTYPE_WSTR == m_pColumnInfo[nColumn].wType)
*(ULONG*)(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize*sizeof(WCHAR))) = nLength;
else
*(ULONG*)(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize)) = nLength;
return true;
}
else
return false;
}
bool SetLength(TCHAR* pColumnName, ULONG nLength)
{
ATLASSERT(pColumnName != NULL);
ULONG nColumn;
if (GetInternalColumnNo(pColumnName, &nColumn))
{
if (DBTYPE_WSTR == m_pColumnInfo[nColumn].wType)
*(ULONG*)(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize*sizeof(WCHAR))) = nLength;
else
*(ULONG*)(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize)) = nLength;
return true;
}
else
return false;
}
HRESULT BindColumns(IUnknown* pUnk)
{
ATLASSERT(pUnk != NULL);
CComPtr<IAccessor> spAccessor;
HRESULT hr = pUnk->QueryInterface(&spAccessor);
if (FAILED(hr))
return hr;
ULONG i;
ULONG nOffset = 0, nLengthOffset, nStatusOffset;
// If the user hasn't specifed the column information to bind by calling AddBindEntry then
// we get it ourselves.
if (m_pColumnInfo == NULL)
{
CComPtr<IColumnsInfo> spColumnsInfo;
hr = pUnk->QueryInterface(&spColumnsInfo);
if (FAILED(hr))
return hr;
hr = spColumnsInfo->GetColumnInfo(&m_nColumns, &m_pColumnInfo, &m_pStringsBuffer);
if (FAILED(hr))
return hr;
m_bOverride = false;
}
else
m_bOverride = true;
DBBINDING* pBinding = NULL;
ATLTRY(pBinding= new DBBINDING[m_nColumns]);
if (pBinding == NULL)
return E_OUTOFMEMORY;
DBBINDING* pCurrent = pBinding;
DBOBJECT* pObject;
for (i = 0; i < m_nColumns; i++)
{
// If it's a BLOB or the column size is large enough for us to treat it as
// a BLOB then we also need to set up the DBOBJECT structure.
if (m_pColumnInfo[i].ulColumnSize > 1024 || m_pColumnInfo[i].wType == DBTYPE_IUNKNOWN)
{
pObject = NULL;
ATLTRY(pObject = new DBOBJECT);
if (pObject == NULL)
return E_OUTOFMEMORY;
pObject->dwFlags = STGM_READ;
pObject->iid = IID_ISequentialStream;
m_pColumnInfo[i].wType = DBTYPE_IUNKNOWN;
m_pColumnInfo[i].ulColumnSize = sizeof(IUnknown*);
}
else
pObject = NULL;
// If column is of type STR or WSTR increase length by 1
// to accommodate the NULL terminator.
if (m_pColumnInfo[i].wType == DBTYPE_STR ||
m_pColumnInfo[i].wType == DBTYPE_WSTR)
m_pColumnInfo[i].ulColumnSize += 1;
if (m_pColumnInfo[i].wType == DBTYPE_WSTR)
nLengthOffset = AddOffset(nOffset, m_pColumnInfo[i].ulColumnSize*sizeof(WCHAR));
else
nLengthOffset = AddOffset(nOffset, m_pColumnInfo[i].ulColumnSize);
nStatusOffset = AddOffset(nLengthOffset, sizeof(ULONG));
ULONG cbMaxLen;
if (m_pColumnInfo[i].wType == DBTYPE_WSTR)
cbMaxLen = m_pColumnInfo[i].ulColumnSize*sizeof(WCHAR);
else
cbMaxLen = m_pColumnInfo[i].ulColumnSize;
CAccessorBase::Bind(pCurrent, m_pColumnInfo[i].iOrdinal, m_pColumnInfo[i].wType,
cbMaxLen, m_pColumnInfo[i].bPrecision, m_pColumnInfo[i].bScale,
DBPARAMIO_NOTPARAM, nOffset,
nLengthOffset, nStatusOffset, pObject);
pCurrent++;
// Note that, because we're not using this for anything else, we're using the
// pTypeInfo element to store the offset to our data.
m_pColumnInfo[i].pTypeInfo = (ITypeInfo*)nOffset;
nOffset = AddOffset(nStatusOffset, sizeof(DBSTATUS));
}
// Allocate the accessor memory if we haven't done so yet.
if (m_pAccessorInfo == NULL)
{
hr = AllocateAccessorMemory(1); // We only have one accessor.
if (FAILED(hr))
{
delete [] pBinding;
return hr;
}
m_pAccessorInfo->bAutoAccessor = TRUE;
}
// Allocate enough memory for the data buffer and tell the rowset.
// Note that the rowset will free the memory in its destructor.
m_pBuffer = NULL;
ATLTRY(m_pBuffer = new BYTE[nOffset]);
if (m_pBuffer == NULL)
{
delete [] pBinding;
return E_OUTOFMEMORY;
}
hr = BindEntries(pBinding, m_nColumns, &m_pAccessorInfo->hAccessor,
nOffset, spAccessor);
delete [] pBinding;
return hr;
}
};
Aşağıdaki örnek kod 18 karakterlik bir Unicode dizesi ile 20 karakter geniş Unicode metin sütununun (nvarchar) bir SQL tablosu eklerken, başarısız olan:
CDataSource ds;
CSession sn;
HRESULT hr;
CDBPropSet dbinit(DBPROPSET_DBINIT);
dbinit.AddProperty(DBPROP_AUTH_USERID, OLESTR("sa"));
dbinit.AddProperty(DBPROP_INIT_CATALOG, OLESTR("pubs"));
dbinit.AddProperty(DBPROP_INIT_DATASOURCE, OLESTR("myserver"));
dbinit.AddProperty(DBPROP_INIT_LCID, (long)1033);
dbinit.AddProperty(DBPROP_INIT_PROMPT, (short)4);
hr = ds.Open(_T("SQLOLEDB"), &dbinit);
ATLASSERT(SUCCEEDED(hr)); //Is the Datasource name and the table name correct, above?
sn.Open(ds);
CCommand< CDynamicAccessor> cmd;
// To fix the problem, remark the above line that uses CDynamicAccessor
// and uncomment the line below that uses the new CDynamicAccessor-derived class.
// CCommand< CDynAccessor> cmd;
cmd.Create(sn, "Select * from TestTable");
CDBPropSet propset(DBPROPSET_ROWSET);
propset.AddProperty(DBPROP_IRowsetChange, true);
propset.AddProperty(DBPROP_UPDATABILITY, DBPROPVAL_UP_CHANGE | DBPROPVAL_UP_INSERT | DBPROPVAL_UP_DELETE);
hr = cmd.Open(&propset);
hr = cmd.MoveNext();
ULONG ul;
DBSTATUS stat;
cmd.GetLength(1, &ul); // This is probably not correct.
cmd.GetStatus(1, &stat); // This is probably not correct.
wchar_t * pszValue = (wchar_t *)cmd.GetValue(1);
wcscpy(pszValue, L"12345678901234567");
int len = wcslen(pszValue);
cmd.SetLength(1, len*2 );
cmd.SetStatus(1, DBSTATUS_S_OK);
hr = cmd.Insert();
cmd.GetStatus(1, &stat);
ÖNEMLİ: Bu makale, bir kişi tarafından çevrilmek yerine, Microsoft makine-çevirisi yazılımı ile çevrilmiştir. Microsoft size hem kişiler tarafından çevrilmiş, hem de makine-çevrisi ile çevrilmiş makaleler sunar. Böylelikle, bilgi bankamızdaki tüm makalelere, kendi dilinizde ulaşmış olursunuz. Bununla birlikte, makine tarafından çevrilmiş makaleler mükemmel değildir. Bir yabancının sizin dilinizde konuşurken yapabileceği hatalar gibi, makale; kelime dağarcığı, söz dizim kuralları veya dil bilgisi açısından yanlışlar içerebilir. Microsoft, içeriğin yanlış çevrimi veya onun müşteri tarafından kullanımından doğan; kusur, hata veya zarardan sorumlu değildir. Microsoft ayrıca makine çevirisi yazılımını sıkça güncellemektedir.
Makalenin İngilizcesi aşağıdaki gibidir:238539
(http://support.microsoft.com/kb/238539/en-us/
)
Bu makaleyi kullanmak için ne kadar kişisel çaba harcadınız?
Çok az
Az
Orta
Fazla
Çok fazla
Bu bilgiyi geliştirmemiz için nedenleri ve bu konuda neler yapabileceğimizi paylaşın
Teşekkürler! Görüşleriniz, destek içeriğimizi geliştirmemize yardımcı olmak için kullanılmaktadır. Diğer yardım seçenekleri için, lütfen Yardım ve Destek Giriş Sayfasını ziyaret edin.