Я пытаюсь запросить SQL Server (Express) через Visual C++ (экспресс) и сохранить полученный набор данных в вектор C++ (массив также был бы большим). С этой целью я исследовал библиотеку ADO и нашел много помощи в MSDN. Короче говоря, ссылайтесь на библиотеку msado15.dll и используйте эти функции (особенно привязку записи ADO, для которой требуется icrsint.h). Короче говоря, я смог запросить базу данных и отобразить значения полей с помощью printf(); но я спотыкаюсь, когда пытаюсь загрузить значения полей в вектор.ADO Recordset Значение поля для вектора/массива C++ (значение указателя захвата)
Первоначально я попытался загрузить значения, выставив все как char * (из-за отчаяния после многих ошибок преобразования типов) только для того, чтобы найти конечный результат был вектор указателей, которые все указали на один и тот же адрес памяти. Далее (и это код, приведенный ниже). Я попытался присвоить значение местоположения памяти, но в итоге я получил вектор первого символа только в памяти. Короче говоря, мне нужна помощь в понимании того, как передать все значение, хранящееся в указателе Fieldset (rs.symbol) указателя (в то время, когда оно передается вектору), а не только первого символа? В этом случае значения, возвращаемые из SQL, являются строками.
#include "stdafx.h"
#import "msado15.dll" no_namespace rename("EOF", "EndOfFile")
#include "iostream"
#include <icrsint.h>
#include <vector>
int j;
_COM_SMARTPTR_TYPEDEF(IADORecordBinding, __uuidof(IADORecordBinding));
inline void TESTHR(HRESULT _hr) { if FAILED(_hr) _com_issue_error(_hr); }
class CCustomRs : public CADORecordBinding {
BEGIN_ADO_BINDING(CCustomRs)
ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, symbol, sizeof(symbol), symbolStatus, false)
END_ADO_BINDING()
public:
CHAR symbol[6];
ULONG symbolStatus;
};
int main() {
::CoInitialize(NULL);
std::vector<char> tickers;
try {
char sym;
_RecordsetPtr pRs("ADODB.Recordset");
CCustomRs rs;
IADORecordBindingPtr picRs(pRs);
pRs->Open(L"SELECT symbol From Test", L"driver={sql server};SERVER=(local);Database=Securities;Trusted_Connection=Yes;",
adOpenForwardOnly, adLockReadOnly, adCmdText);
TESTHR(picRs->BindToRecordset(&rs));
while (!pRs->EndOfFile) {
// Process data in the CCustomRs C++ instance variables.
//Try to load field value into a vector
printf("Name = %s\n",
(rs.symbolStatus == adFldOK ? rs.symbol: "<Error>"));
//This is likely where my mistake is
sym = *rs.symbol;//only seems to store the first character at the pointer's address
// Move to the next row of the Recordset. Fields in the new row will
// automatically be placed in the CCustomRs C++ instance variables.
//Try to load field value into a vector
tickers.push_back (sym); //I can redefine everything as char*, but I end up with an array of a single memory location...
pRs->MoveNext();
}
}
catch (_com_error &e) {
printf("Error:\n");
printf("Code = %08lx\n", e.Error());
printf("Meaning = %s\n", e.ErrorMessage());
printf("Source = %s\n", (LPCSTR)e.Source());
printf("Description = %s\n", (LPCSTR)e.Description());
}
::CoUninitialize();
//This is me running tests to ensure the data passes as expected, which it doesn't
std::cin.get();
std::cout << "the vector contains: " << tickers.size() << '\n';
std::cin.get();
j = 0;
while (j < tickers.size()) {
std::cout << j << ' ' << tickers.size() << ' ' << tickers[j] << '\n';
j++;
}
std::cin.get();
}
Благодарим за любые рекомендации, которые вы можете предоставить.
Могу ли я спросить, почему это было приостановлено? – alain
Hey alain (я не уменьшал это, просто FYI). Я принял ваш совет и переработал вектор тиккеров и push_back, как вы упомянули. Однако, когда у меня есть программа, напечатайте значения в результирующем векторе, используя printf («% s \ n», тикеры [j]); значения, хранящиеся в векторе, кажутся jibberish ... Я пропустил что-то еще здесь? – Shawn802
Вы можете использовать 'cout <<', как в вопросе, или 'printf ("% s \ n ", tickers [j] .c_str());'. Я знаю, что вы не спустили вниз, я думаю, это из-за комментария, который я написал на мета. – alain