OLEDB 호출 저장 프로세스

5853 단어
title: OLEDB 호출 저장 프로세스 tags: [OLEDB, 데이터베이스 프로그래밍, VC++, 데이터베이스] date: 2018-03-31 14:09:35 categories: 윈도우즈 데이터베이스 프로그래밍 keywords: OLEDB, 데이터베이스 프로그래밍, VC++, 저장 프로세스, 입력 출력 매개 변수
일반적인 sql 문장 호출과 간단한 삽입 삭제 작업을 제외하고OLEDB는 저장 프로세스를 호출하는 기능을 제공했다. 저장 프로세스는 마치 SQL 문장으로 쓴 함수처럼 매개 변수와 반환 값이 있을 수 있다.저장 프로세스는 일반 함수처럼 일반 값을 되돌려주는 것 이외에 결과 집합도 되돌려줄 수 있다. 되돌려주는 내용은 출력 매개 변수로 얻을 수 있지만 만약 되돌려주는 것이 결과 집합이라면 출력 매개 변수로 얻는 것을 추천하지 않고 다중 결과 집합으로 수신한다.또한 입력 매개 변수는 일반적으로 매개 변수화 조회 방식으로 진행되기 때문에 매개 변수화 조회와 유사하지만 매개 변수화 조회에 비해 좀 복잡하다.
저장 프로세스의 사용
출력 매개 변수에 대해 DBBINDING 구조를 바인딩할 때 구조의 eParamiO를 DBPARAMIO로 지정합니다OUTPUT, 메모리 프로세스를 호출할 때 다음과 같은 형식을 사용할 수 있습니다
{? = call myProc(?, ?)}

이 양식 중 두 개의 큰 괄호는 필수적인데, 그중에?대표적인 입력과 출력 매개 변수,call은 저장 프로세스를 호출하는 것도 필수적이다.일반적으로 저장 프로세스의 매개 변수 위치는 입력만 받고 출력 매개 변수가 되지 않으며 저장 프로세스의 반환값 위치는 출력만 하고 입력이 아니다.또한 가장 주의해야 할 점은 저장 프로세스가 결과 집합을 되돌릴 때 되돌려주는 결과 집합 바늘이 방출되지 않으면 출력 매개 변수의 버퍼는 새로 고침되지 않고 출력 매개 변수를 받지 못한다는 것이다.이것은 데이터 공급자가 이 데이터를 되돌릴 때 흐르는 방식에 따라 하기 때문이다.결과 집합의 흐름은 출력 매개 변수와 반환 값의 흐름 앞에 있기 때문에 결과 집합이 방출되기 전에 응용 프로그램은 출력 매개 변수를 받아들일 수 없다.그의 이러한 특성에 대해 우리는 일반적으로 저장 프로세스가 되돌아오는 결과 집합을 사용한 다음에 결과 집합과 관련된 지침을 방출한 다음에 출력 매개 변수의 버퍼에서 데이터를 꺼내고 마지막에 이러한 버퍼를 방출한다.
메모리 프로세스 사용 예
BOOL ExecUsp(IOpenRowset *pIOpenRowset)
{
    IAccessor *pParamAccessor = NULL;

    LPOLESTR pSQL = OLESTR("{? = call Usp_InputOutput(?,?)}");
    DB_UPARAMS cParams = 0;
    DBPARAMINFO* rgParamInfo = NULL;
    DBBINDING* rgParamBind = NULL;
    LPOLESTR pParamNames = NULL;
    DWORD dwOffset = 0;
    HACCESSOR hAccessor = NULL;
    TCHAR szInputBuffer[11] = _T("");
    DBPARAMS dbParams = {0};
    BOOL bRet = FALSE;

    HRESULT hRes = pIOpenRowset->QueryInterface(IID_IDBCreateCommand, (void**)&pIDBCreateCommand);
    hRes = pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText, (IUnknown**)&pICommandText);

    hRes = pICommandText->SetCommandText(DBGUID_DEFAULT, pSQL);
    hRes = pICommandText->QueryInterface(IID_ICommandPrepare, (void**)&pICommandPrepare);
    hRes = pICommandPrepare->Prepare(0);

    hRes = pICommandText->QueryInterface(IID_ICommandWithParameters, (void**)&pICommandWithParameters);
    hRes = pICommandWithParameters->GetParameterInfo(&cParams, &rgParamInfo, &pParamNames);

    //    
    rgParamBind = (DBBINDING*)MALLOC(sizeof(DBBINDING) * cParams);
    for (int i = 0; i < cParams; i++)
    {
        rgParamBind[i].bPrecision = 11;
        rgParamBind[i].bScale = rgParamInfo[i].bScale;
        rgParamBind[i].cbMaxLen = rgParamInfo[i].ulParamSize; //    int ,               
        rgParamBind[i].iOrdinal = rgParamInfo[i].iOrdinal;
        rgParamBind[i].dwPart = DBPART_VALUE;
    //             , eParamIO           ,
        if (rgParamInfo[i].dwFlags & DBPARAMFLAGS_ISINPUT)
        {
            rgParamBind[i].eParamIO |= DBPARAMIO_INPUT;
        }

    //  
        if (rgParamInfo[i].dwFlags & DBPARAMFLAGS_ISOUTPUT)
        {
            rgParamBind[i].eParamIO |= DBPARAMIO_OUTPUT;
        }

        rgParamBind[i].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
        rgParamBind[i].obLength = 0;
        rgParamBind[i].obStatus = 0;
        rgParamBind[i].obValue = dwOffset;
        dwOffset = rgParamBind[i].obValue + rgParamBind[i].cbMaxLen;
        rgParamBind[i].wType = rgParamInfo[i].wType; //      int 
    }

    //        
    hRes = pICommandText->QueryInterface(IID_IAccessor, (void**)&pParamAccessor);
    COM_SUCCESS(hRes, _T("    pParamAccessor  ,    :%08x
"), hRes); hRes = pParamAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA, cParams, rgParamBind, dwOffset, &hAccessor, NULL); COM_SUCCESS(hRes, _T(" , :%08x
"), hRes); // dbParams.pData = MALLOC(dwOffset); ZeroMemory(dbParams.pData , dwOffset); dbParams.cParamSets = cParams; dbParams.hAccessor = hAccessor; for (int i = 0; i < cParams; i++) { if (rgParamBind[i].eParamIO & DBPARAMIO_INPUT) { COM_PRINT(_T(" %d [%s]:"), i + 1, rgParamInfo[i].pwszName); while (S_OK != StringCchGets(szInputBuffer, 11)); *(int*)((BYTE*)dbParams.pData + rgParamBind[i].obValue) = _ttoi(szInputBuffer); ZeroMemory(szInputBuffer, 11 * sizeof(TCHAR)); } } hRes = pICommandText->Execute(NULL, IID_IMultipleResults, &dbParams, NULL, (IUnknown**)&pIMultipleResults); // ReadRowset(pIMultipleResults); COM_PRINT(_T(" :%d
"), *(int*)dbParams.pData) bRet = TRUE; __CLEAR_UP: CoTaskMemFree(rgParamInfo); FREE(rgParamBind); CoTaskMemFree(pParamNames); FREE(dbParams.pData); SAFE_RELEASE(pIDBCreateCommand); SAFE_RELEASE(pICommandText); SAFE_RELEASE(pICommandPrepare); SAFE_RELEASE(pICommandWithParameters); SAFE_RELEASE(pParamAccessor); SAFE_RELEASE(pIMultipleResults); return bRet; }

위 코드에서 호출된 저장 프로세스는 다음과 같습니다.
ALTER PROCEDURE [dbo].[Usp_InputOutput]
    @input int,
    @output int Output

AS
BEGIN
    select @input, @output
    set @output = 2
    return 7
END

이 저장 프로세스는 두 개의 매개 변수를 입력하고 select를 통해 이 두 개의 매개 변수로 구성된 결과 집합을 되돌려줍니다.저장 프로세스의 출력 매개 변수는 7.상기 코드에서 저장 프로세스를 호출하는 sql 문구를 정의한 다음에 ICommandText 대상에 이 저장 프로세스를 설정한 다음에 파라미터와 관련된 정보를 얻은 다음에 파라미터를 연결하여 출력, 출력 파라미터의 버퍼를 제공한 다음에 저장 프로세스를 실행하여 결과 집합을 얻는다.이어서 결과 집합을 읽습니다.마지막으로 되돌아오는 값을 읽습니다.위에서 말한 바와 같이 되돌아오는 결과 집합의 바늘을 놓지 않으면 되돌아오는 값을 받지 못한다. 그러나 이 코드에서 되돌아오는 값을 읽기 전에 되돌아오는 IMultiple Results 바늘을 놓지 않은 것처럼 보이지만 결과 집합을 찾을 수 있다. 왜 그런가?사실 이전에 말한 것은 되돌아온 결과집이지만 다행 결과집이라고는 하지 않았고 여기서 방출된 것은 주로 결과집이다.다행 결과 집합에 대해 우리는 그 안에 포함된 모든 결과 집합의 대상을 방출하기만 하면 된다.결과 집합을 방출하는 코드는 함수 ReadRowset에 있습니다. 여기에 열거되지 않았습니다.
마지막: 완전한 코드: 여기를 클릭하여 보십시오

좋은 웹페이지 즐겨찾기