Здравствуйте, dilsh, Вы писали:
D>Пытаюсь выполнить хранимую процедуру MSSQL и прочитать возвращаемые ею значения.
Смотрите как у меня сделано.
Есть класс DatabaseObject. Его наследуют все классы Data Access Layer'а
#pragma once
// В ado.h просто #import
#include "../ado.h"
namespace Data
{
//
// DatabaseObject base class
class DatabaseObject
{
// Строка соединения
CString m_strConnectionString;
// Соединение
ADODB::_ConnectionPtr m_adoConnection;
protected:
//
// Защищенный конструктор. Открывает соединение
DatabaseObject(const CString &strConnectionString) :
m_strConnectionString(strConnectionString)
{
m_adoConnection.CreateInstance(__uuidof(ADODB::Connection));
m_adoConnection->Open((LPCTSTR)m_strConnectionString, L"", L"", ADODB::adOptionUnspecified);
}
//
// Деструктор. Закрывает соединение
~DatabaseObject(void)
{
m_adoConnection->Close();
}
//
// Создает новый объект Command
ADODB::_CommandPtr BuildQuery(LPCTSTR lpszStoredProcedureName)
{
//
// Creating Command object
ADODB::_CommandPtr adoCommand(__uuidof(ADODB::Command));
adoCommand->ActiveConnection = m_adoConnection;
adoCommand->CommandType = ADODB::adCmdStoredProc;
adoCommand->CommandText = lpszStoredProcedureName;
adoCommand->NamedParameters = VARIANT_TRUE;
//
// Refreshing
adoCommand->Parameters->Refresh();
return adoCommand;
}
//
// Создает объект Command. Можно использовать для постпроцессинга
ADODB::_CommandPtr BuildCommand(LPCTSTR lpszStoredProcedureName)
{
//
// Building command
return BuildQuery(lpszStoredProcedureName);
}
//
// Подготавливает команду к выполнению
ADODB::_CommandPtr PrepareCommand(LPCTSTR lpszStoredProcedureName)
{
//
// Building command
ADODB::_CommandPtr adoCommand = BuildCommand(lpszStoredProcedureName);
return adoCommand;
}
//
// Выполняет команду.
// Лучше всегоиспользовать для INSERT, UPDATE и DELETE.
// Возвращает код RETURN'а хранимой процедуры
int ExecuteCommand(ADODB::_CommandPtr adoCommand, long &lRowsAffected)
{
//
// Executing
_variant_t vtRowsAffected;
adoCommand->Execute(&vtRowsAffected, &vtMissing,
ADODB::adCmdStoredProc | ADODB::adExecuteNoRecords);
//
// Returning result
int nResult = adoCommand->Parameters->Item[L"@RETURN_VALUE"]->Value;
lRowsAffected = vtRowsAffected;
return nResult;
}
//
// Выполняет команду
// Выполняет команду и возвращает Recordset
ADODB::_RecordsetPtr ExecuteCommand(ADODB::_CommandPtr adoCommand)
{
//
// Executing
_variant_t vtRowsAffected;
ADODB::_RecordsetPtr adoRecordset = adoCommand->Execute(&vtRowsAffected, &vtMissing,
ADODB::adCmdStoredProc);
return adoRecordset;
}
//
// Выполняет команду и возвращает Record
ADODB::_RecordPtr ExecuteCommandEx(ADODB::_CommandPtr adoCommand)
{
//
// Executing
_variant_t vtRowsAffected;
ADODB::_RecordPtr adoRecord = adoCommand->Execute(&vtRowsAffected, &vtMissing,
ADODB::adCmdStoredProc | ADODB::adExecuteRecord);
return adoRecord;
}
};
} // namespace Data
А вот использующий его DAL-класс Supplier (Поставщик)
namespace Data
{
//
// Supplier class - Data Access Layer
class Supplier : public octalforty::WarehouseSystem::Classes::Data::DatabaseObject
{
public:
//
// Public constructor
Supplier(const CString &strConnectionString) :
DatabaseObject(strConnectionString)
{
}
//
// Destructor
~Supplier(void)
{
}
//
// Returns all suppliers
ADODB::_RecordsetPtr GetSuppliers()
{
//
// Executing stored procedure
return ExecuteCommand(PrepareCommand(_T("Suppliers_GetSuppliers")));
}
//
// Returns one Supplier object
ADODB::_RecordsetPtr GetSupplier(long lID)
{
//
// SQL SP parameters
ADODB::_CommandPtr adoCommand = PrepareCommand(_T("Suppliers_GetSupplier"));
adoCommand->Parameters->Item[L"@id"]->Value = lID;
//
// Executing
return ExecuteCommand(adoCommand);
}
//
// Creates one Supplier object. Returns ID of a newly created object
long CreateSupplier(long lCurrencyID, const CString &strSupplier, const CString &strAddress,
const CString &strEMail, const CString &strPhoneNumber, const CString &strSupplementalInformation)
{
//
// SQL SP parameters
ADODB::_CommandPtr adoCommand = PrepareCommand(_T("Suppliers_CreateSupplier"));
adoCommand->Parameters->Item[L"@currencyID"]->Value = lCurrencyID;
adoCommand->Parameters->Item[L"@supplier"]->Value = (LPCTSTR)strSupplier;
adoCommand->Parameters->Item[L"@address"]->Value = (LPCTSTR)strAddress;
adoCommand->Parameters->Item[L"@email"]->Value = (LPCTSTR)strEMail;
adoCommand->Parameters->Item[L"@phoneNumber"]->Value = (LPCTSTR)strPhoneNumber;
adoCommand->Parameters->Item[L"@supplementalInformation"]->Value = (LPCTSTR)strSupplementalInformation;
adoCommand->Parameters->Item[L"@id"]->Value = 0;
//
// Executing
long lRowsAffected;
ExecuteCommand(adoCommand, lRowsAffected);
return (long)adoCommand->Parameters->Item[L"@id"]->Value;
}
//
// Updates Supplier
void UpdateSupplier(long lID, long lCurrencyID, const CString &strSupplier, const CString &strAddress,
const CString &strEMail, const CString &strPhoneNumber, const CString &strSupplementalInformation)
{
//
// SQL SP parameters
ADODB::_CommandPtr adoCommand = PrepareCommand(_T("Suppliers_UpdateSupplier"));
adoCommand->Parameters->Item[L"@id"]->Value = lID;
adoCommand->Parameters->Item[L"@currencyID"]->Value = lCurrencyID;
adoCommand->Parameters->Item[L"@supplier"]->Value = (LPCTSTR)strSupplier;
adoCommand->Parameters->Item[L"@address"]->Value = (LPCTSTR)strAddress;
adoCommand->Parameters->Item[L"@email"]->Value = (LPCTSTR)strEMail;
adoCommand->Parameters->Item[L"@phoneNumber"]->Value = (LPCTSTR)strPhoneNumber;
adoCommand->Parameters->Item[L"@supplementalInformation"]->Value = (LPCTSTR)strSupplementalInformation;
//
// Executing
long lRowsAffected;
ExecuteCommand(adoCommand, lRowsAffected);
}
//
// Deletes Supplier
void DeleteSupplier(long lID)
{
//
// SQL SP parameters
ADODB::_CommandPtr adoCommand = PrepareCommand(_T("Suppliers_DeleteSupplier"));
adoCommand->Parameters->Item[L"@id"]->Value = lID;
//
// Executing
long lRowsAffected;
ExecuteCommand(adoCommand, lRowsAffected);
}
};
То есть то, что у вас записывается как
pprmCmdChange = pCmdChange->CreateParameter("brand", adInteger,adParamInput, sizeof(int), vtCriteria);
pprmCmdChange->Value = vtCriteria;
pCmdChange->Parameters->Append(pprmCmdChange);
У меня выглядит так:
pprmCmdChange->Parameters->Item[L"@brand"]->Value = vtCriteria;
Это, разумеется, при наличии хранимой процедуры с параметрами:
CREATE PROCEDURE dbo.BlogPostCategories_CreateBlogPostCategory
(
@name nvarchar(400),
@description ntext,
@id int output )
AS
-- Inserting
SET ANSI_PADDING OFF
INSERT INTO BlogPostCategories (Name, Description)
VALUES (@name, @description)
SET @id = @@IDENTITY
Вот. Пользуйтесь. А насчет закрытого рекордсета —

. Не должно так быть, ИМХО.