木感想

常常思索 没有结果 来来去去 依稀记得

导航

用ADO访问存储过程的参数问题

SQL存储过程的调用
ADO访问数据库带参数的存储过程,输入的参数一般没有什么问题,输出的参数经常得不到结果。主要的问题是编写存储过程时,经常使用查询
分析器验证结果,很自然的认为Select变量后,就应该返回该变量的数值。但事实是Select只是返回了数据集,并不是返回参数结果。

例如,有一个存储:
CREATE PROCEDURE [dbo].[ah_todo]
    @pValue varchar(256),
    @pRtn varchar(64) OUT
as
    set @pRtn =  '用户名已经存在'
    select @pRtn
GO

使用Set和Select语句对pRtn作了操作,只有Set语句真正起到了修改参数的作用。而Select语句只是将该参数
送入返回的Recordset中。

下面是访问过程源程序:
DWORD WINAPI CDbHandy::doSomething(DBHandyParam* pParam)
{
    HRESULT hr;
    _ConnectionPtr pConnection;
    _CommandPtr pCmd;

    _variant_t vNULL;
    vNULL.vt = VT_ERROR;
    vNULL.scode = DISP_E_PARAMNOTFOUND;

    CoInitialize(NULL);

    // Get connection
    pConnection.CreateInstance(__uuidof(Connection));
    pCmd.CreateInstance(__uuidof(Command));
 
    try
    {
        hr = pConnection->Open(L"Provider=sqloledb;SERVER=xxx;DATABASE=xx;Integrated Security=SSPI", L"sa", L"00000000", adConnectUnspecified); //连接数据库
        if(FAILED(hr))
        {
            return -1;
        }
    }
    catch(...)
    {
        return -1;
    }
 
    pCmd->ActiveConnection  = pConnection;
    pCmd->CommandText = _bstr_t("ah_todo");
    pCmd->CommandType = adCmdStoredProc;

    pCmd->Parameters->Append(pCmd->CreateParameter(_bstr_t("pValue"), adVarChar, adParamInput, 256, _variant_t(pParam->pszValue)));
    pCmd->Parameters->Append(pCmd->CreateParameter(_bstr_t("pRtn"),   adVarChar, adParamReturnValue, 64,  _variant_t
("result:")));
 
    try
    {
        pCmd->Execute( &vNULL, &vNULL, adCmdStoredProc );
     }
    catch(...)
    {
        pConnection->Close();
        return -1;
    }

    // 分析返回的参数
    _variant_t vIndex;
    vIndex.vt = VT_I2; vIndex.iVal = 1;
    _ParameterPtr pmRtn = pCmd->GetParameters()->Item[vIndex];

    StringCchPrintf(pParam->pszRtn, MAX_PATH, L"%s", (LPCWSTR)_bstr_t(pmRtn->Value));

    pConnection->Close();
    CoUninitialize();
 
    return 0;
}

过程中Append两个参数,他们和编写的存储过程的参数一一对应。
执行Execute调用存储过程后,你所想要得返回结果就保存在Command的参数列表中,通过访问参数列表,即可取得返回结果。

如果使用数据集跟踪Command,那么将会得到Select语句送给你的数据结果,他不是真正的参数返回结果。
_Recordset pRecordset = pCmd->Execute( &vNULL, &vNULL, adCmdStoredProc );
获得存储过程执行结果.这个用法具有很多不确定性,返回的数据集受到各种SQL语句的影响。因此如果你需要查询大量结果的数据集,那么就不需要使用Command执行存储过程,可以直接使用Recordset.Open()进行查询工作。

ADO编写数据库程序因为系统提供的只是功能强大的基本函数,和Socket一样大量的工作还需要我们进行处理。
访问数据时,需要建立访问进程执行操作,同时还需要建立等待进程执行访问状态跟踪,对访问情况进行汇报、事务处理等工作。

 

posted on 2008-03-15 07:56  跌跌撞撞  阅读(1016)  评论(0)    收藏  举报