2009-03-17 1 views
1

Вот код.
Несколько заметок об этом. DStr - это строковый класс, который является внутренним для нашей компании. Он функционирует так же, как CString. Я могу подключиться к базе данных и запускать непараметрированные запросы. Также эта вставка отлично работает, если я не использую параметры. Элемент cmd-> Execute генерирует исключение. Здесь я получаю сообщение об ошибке.Почему я продолжаю получать «Должен объявлять переменную Scalar» @ Param1 «» при выполнении параметризованного запроса в C++ с использованием ADO?

void CEmailArchiveDatabase::TestAddUser(DStr username, DStr displayname) 
{ 

    DStr sql = "INSERT INTO [User] (UserName, DisplayName) VALUES (@Param1, @Param2)"; 

    _variant_t vUser; 
    _variant_t vDisp; 

    vUser.vt = VT_BSTR; 
    vUser.bstrVal = username.AllocSysString(); 
    vDisp.vt = VT_BSTR; 
    vDisp.bstrVal = displayname.AllocSysString(); 

    _CommandPtr cmd = NULL; 
    _ConnectionPtr conn = NULL; 
    _ParameterPtr prm = NULL; 

    DStr connStr = "driver={SQL Server};server=DEMETER\\SQLEXPRESS;database=ExtractoMundo"; 

    try 
    { 
     conn.CreateInstance(__uuidof(Connection)); 
     cmd.CreateInstance(__uuidof(Command)); 

     if(!(conn->GetState() & adStateOpen)) 
     { 
      conn->ConnectionString = connStr.AllocSysString(); 
      conn->Open("", "", "", NULL); 
      conn->CursorLocation = adUseClient; 
     } 

     cmd->ActiveConnection = conn; 
     cmd->CommandText = sql.AllocSysString(); 
     cmd->CommandType = adCmdText; 

     prm = cmd->CreateParameter("@Param1", adLongVarChar, adParamInput, -1, vUser); 
     cmd->Parameters->Append(prm); 
     prm = cmd->CreateParameter("@Param2", adLongVarChar, adParamInput, -1, vDisp); 
     cmd->Parameters->Append(prm); 

     _variant_t recAff; 

     cmd->Execute(&recAff, NULL, adExecuteNoRecords); 

    } 
    catch(_com_error &ex) 
    { 
     //ClearParameters(); 
     DStr err; 
     err += PrintProviderError(conn); 
     err += PrintComError(ex); 
    } 

    SysFreeString(vUser.bstrVal); 
    SysFreeString(vDisp.bstrVal); 
    SysFreeString(cmd->CommandText); 
    SysFreeString(conn->ConnectionString); 

} 

ответ

3

ADO отказывается работать с именованными параметрами в динамических запросах. Вам необходимо либо преобразовать именованные параметры в заполнители параметров:

DStr sql = "INSERT INTO [User] (UserName, DisplayName) VALUES (?, ?)"; 

или использовать вместо этого хранимую процедуру. Создать процедуру:

CREATE PROCEDURE spUserInsert 
    @Param1 nvarchar(50), 
    @Param2 nvarchar(50) 
AS 
    SET NOCOUNT ON; 
    INSERT INTO [User] (UserName, DisplayName) VALUES (@Param1, @Param2) 
GO 

и изменить код, чтобы назвать его:

DStr sql = "spUserInsert"; 
... 
cmd->CommandType = adCmdStoredProcedure; 
0

Возможно, cmd->CreateParameter(_bstr_t("Param1"), ...)?

«@» - это конкретный оператор SQL Server, он может быть запутан с вами.

+0

Я попробовал оба предложения, но ни радости –

+0

я не думаю, что я вижу это сейчас. Попробуйте использовать adCmdStoredProc вместо adCmdText – slf

-1

Вы пытались использовать adCmdStoredProc вместо adCmdText?

+0

Это неправильно, потому что OP явно не использует хранимую процедуру. –