Проблема следующая:
имеется хранимая процедура (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, но значения не возвращаются.
Подскажите, пжл, в какую сторону копать.
Здравствуйте, 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>
Это что вся процедура?
Понял, что дело в возвращении хранимой процедурой 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);
Если я что-то недопонял, буду благодарен за поправки