получение OUTPUT параметры хранимой процедуры
От: Karamat Беларусь  
Дата: 05.10.04 16:30
Оценка:
Проблема следующая:
имеется хранимая процедура (MSSQL2000) и код для ODBC3
Объявление процедуры:

CREATE PROC GetDilerProp_1_04
        @Auction    int,
        @KodDil        char_dil     OUT,
        @SubSchTrader    char( 3)     OUT,
        @NameDil    char(50)     OUT,
        @SubSchCount    int        = 1  OUT,
    @NClient    int        = 1, 
        @MarketMaker    int        = 0  OUT,
    @FirmName    varchar(7) = '' OUT
AS

SET NOCOUNT ON

SET ROWCOUNT     0


Код на C++:

 SQLINTEGER len1 = 0, len2 = 0, len3 = SQL_NTS, 
     len4 = SQL_NTS, len5 = SQL_NTS, len6 = 0, len7 = 0, len8 = 0, len9 = SQL_NTS;
 RETCODE rc;
 HSTMT hStmt;
 rc = ::SQLAllocHandle(SQL_HANDLE_STMT, (HDBC)ConnectToSQLServer, &hStmt );

 rc = ::SQLPrepare( hStmt, (UCHAR*)"{ ?=call GetDilerProp_1_04(?,?,?,?,?,?,?,?)}", SQL_NTS ) ;

 rc = ::SQLBindParameter(hStmt, 1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 10, 0, &lRetCode, sizeof(lRetCode), &len1);
 rc = ::SQLBindParameter(hStmt, 2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 10, 0, &lTypeOfAuction, sizeof(lTypeOfAuction), &len2);
 rc = ::SQLBindParameter(hStmt, 3, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_CHAR, LEN_CODE_DILER,
     0, strDealerCode.GetBuffer(LEN_CODE_DILER), LEN_CODE_DILER+1, &len3);

 rc = ::SQLBindParameter(hStmt, 4, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_CHAR, LEN_CODE_SUBSCH,
     0, strTraderSubSch.GetBuffer(LEN_CODE_SUBSCH), LEN_CODE_SUBSCH+1, &len4);

 rc = ::SQLBindParameter(hStmt, 5, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_CHAR, 50,
     0, strFullDealerName.GetBuffer(50), 50+1, &len5);

 rc = ::SQLBindParameter(hStmt, 6, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 10, 0, &lSubSchCount, sizeof(lSubSchCount), &len6);
 rc = ::SQLBindParameter(hStmt, 7, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 10, 0, &NClient, sizeof(NClient), &len7);
 rc = ::SQLBindParameter(hStmt, 8, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 10, 0, &lMarketMaker, sizeof(lMarketMaker), &len8);

 rc = ::SQLBindParameter(hStmt, 9, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_CHAR, LEN_FIRM_NAME,
     0, strFirmName.GetBuffer(LEN_FIRM_NAME), LEN_FIRM_NAME+1, &len9);

 rc = SQLExecute(hStmt);

Все отрабатывает успешно, rc == SQL_SUCCESS, но значения не возвращаются.

Подскажите, пжл, в какую сторону копать.
Re: получение OUTPUT параметры хранимой процедуры
От: _d_m_  
Дата: 06.10.04 00:50
Оценка:
Здравствуйте, Karamat, Вы писали:

K>Проблема следующая:

K>имеется хранимая процедура (MSSQL2000) и код для ODBC3
K>Объявление процедуры:

K>
K>CREATE PROC GetDilerProp_1_04
K>        @Auction    int,
K>        @KodDil        char_dil     OUT,
K>        @SubSchTrader    char( 3)     OUT,
K>        @NameDil    char(50)     OUT,
K>        @SubSchCount    int        = 1  OUT,
K>    @NClient    int        = 1, 
K>        @MarketMaker    int        = 0  OUT,
K>    @FirmName    varchar(7) = '' OUT
K>AS
begin
K>SET NOCOUNT ON

K>SET ROWCOUNT     0  -- а это еще что?
end
K>


Это что вся процедура?
Re[2]: получение OUTPUT параметры хранимой процедуры
От: Karamat Беларусь  
Дата: 06.10.04 05:33
Оценка:
Здравствуйте, _d_m_, Вы писали:


K>>SET ROWCOUNT 0 -- а это еще что?

Это не влияет на результат, проверил.

___>Это что вся процедура?

Она большая и смысла ее тут приводить всю я не вижу. При вызове из Query Analizer все возвращается, профилером видно что результат тоже есть..
Re: получение OUTPUT параметры хранимой процедуры
От: Karamat Беларусь  
Дата: 06.10.04 09:53
Оценка:
Понял, что дело в возвращении хранимой процедурой rowset-та помимо output параметров.
В этой ситуации output параметры возвращаются только после того как прочитаешь _все_ строки SQLFetch() и закроешь статемент SQLFreeHandle(SQL_HANDLE_STMT, hStmt). При этом "SET NOCOUNT ON" должен быть обязательно (Похоже надо читать вообще все результаты).

Мой тестовый пример.
Хранимая процедура:

CREATE PROCEDURE _Test 
        @MyValue            int,
        @UserInfo          char(50)    OUT
AS
SET NOCOUNT ON
select @UserInfo = USER_NAME()
select top 4 isin from sl_cb (nolock)

return 123
GO


Код вызова:

SQLINTEGER len1 = 0, len2 = 0, len3 = SQL_NTS;

 RETCODE rc;
 HSTMT hStmt;
 rc = ::SQLAllocHandle(SQL_HANDLE_STMT, (HDBC)ConnectToSQLServer, &hStmt );

 rc = ::SQLPrepare( hStmt, (UCHAR*)"{ ?=call _Test(?,?)}", SQL_NTS ) ;
 rc = ::SQLBindParameter(hStmt, 1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 10, 0, &rv, sizeof(rv), &len1);
 rc = ::SQLBindParameter(hStmt, 2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 10, 0, &myVal, sizeof(myVal), &len2);
 rc = ::SQLBindParameter(hStmt, 3, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_CHAR, 50,
     0, strUserInfo.GetBuffer(50), 50+1, &len3);

 rc = SQLExecute(hStmt);

 while (rc == SQL_SUCCESS)
 {
     rc = SQLFetch(hStmt);
 }

 

rc = SQLFreeHandle(SQL_HANDLE_STMT, hStmt);


Если я что-то недопонял, буду благодарен за поправки
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.