Re: ADO
От: Нахлобуч Великобритания https://hglabhq.com
Дата: 22.08.05 12:02
Оценка:
Здравствуйте, 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

Вот. Пользуйтесь. А насчет закрытого рекордсета — . Не должно так быть, ИМХО.
HgLab: Mercurial Server and Repository Management for Windows
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.