Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Помогите вернуть из ХП данные через парамеры  [new]
Guest99
Guest
Здравствуйте.

Имеем : w2k + MS SQL Server 2000 - 8.00.194 (Intel X86) + C++(VC 6.0) + ODBC

Не могу получить возвращаемое значение из процедуры (см. пример p_Bik_Select_test6 , параметры 7 и 8).
Процедура отрабатывает и формирует набор данных (Select...From...), но kolzap = 0 и rez = 0.
Очень расчитываю на ваше участие.
Спасибо

/************************************/


declare @kolzap int
declare @rez int
set @kolzap =-9
set @rez = -8
exec p_Bik_Select_test6 3,'','','',7747,1,@kolzap OUT,@rez OUT
select @kolzap,@rez

/*************************************/
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[biktest]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[biktest]
GO

CREATE TABLE [dbo].[biktest] (
[code_bank] [int] IDENTITY (1, 1) NOT NULL ,
[bik] [char] (12) COLLATE Cyrillic_General_CI_AS NULL ,
[bankname] [varchar] (50) COLLATE Cyrillic_General_CI_AS NULL ,
[bankcity] [varchar] (50) COLLATE Cyrillic_General_CI_AS NULL ,
[onum] [smallint] NULL ,
[bankn] [char] (10) COLLATE Cyrillic_General_CI_AS NULL ,
[del] [tinyint] NULL
) ON [PRIMARY]
GO
/*************************************/
/*
begin transaction
go
*/
insert biktest VALUES ('121234345316','ОАО Моссранск-банк','Шалопаевск',7747,'Моссранск',0)
insert biktest VALUES ('747634905693','ЗАО Плутобанк','Колупаевск',7747,'Плуто',0)
insert biktest VALUES ('382717090320','ООО Верхневоровсий','Хапуженск',7747,'Верхневор',0)
insert biktest VALUES ('297054802357','ОПС Озеро','Чубасранск',7747,'ОПС',0)
insert biktest VALUES ('187924462847','КБ Шестирукий','Волобуевск',7747,'Шестирукий',0)
go
select * from biktest
go
/*
rollback
go
*/
/*************************************/
// C++ proc
SQLRETURN sqlreturn, sqlstate ;
SQLCHAR ConnectionStringIn[89] ="DRIVER={SQL Server};SERVER=serv12\\inst1;UID=Log1;PWD=Log12345;DATABASE=SOLD;";
SQLCHAR ConnectionStringOut[250] = "";
SQLSMALLINT StrOutSize = 0;
SQLSMALLINT g_id;
SQLSMALLINT g_count;

SQLHENV g_henv = SQL_NULL_HENV;
SQLHDBC g_hdbc = SQL_NULL_HDBC;
SQLHSTMT g_hstmt = SQL_NULL_HSTMT;

sqlreturn = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&g_henv);
sqlreturn = SQLSetEnvAttr(g_henv,SQL_ATTR_ODBC_VERSION,(void*) SQL_OV_ODBC3,NULL);
sqlreturn = SQLAllocHandle(SQL_HANDLE_DBC, g_henv,&g_hdbc);

sqlreturn = SQLDriverConnect(g_hdbc, GetForegroundWindow(),
ConnectionStringIn, SQL_NTS,
(unsigned char *)"", SQL_NTS, // string OUT no used
&StrOutSize, SQL_DRIVER_NOPROMPT); //no Call GetForegroundWindow()

sqlreturn = SQLAllocHandle(SQL_HANDLE_STMT,g_hdbc,&g_hstmt) ;
//sqlreturn = SQLSetConnectAttr(g_hdbc, SQL_LOGIN_TIMEOUT, (void *)5, 0);

SQLINTEGER codebank = 4;
sqlreturn = SQLBindParameter(g_hstmt,1,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&codebank,0,0);

SQLCHAR szBIK[12+1]="";
SQLINTEGER cbBIK = SQL_NTS;
sqlreturn = SQLBindParameter(g_hstmt,2,SQL_PARAM_INPUT,SQL_C_CHAR, SQL_CHAR,sizeof(szBIK)-1,0,szBIK,sizeof(szBIK)-1,&cbBIK);

SQLCHAR szBankName[50+1]="";
SQLINTEGER cbBankName = SQL_NTS;
sqlreturn = SQLBindParameter(g_hstmt,3,SQL_PARAM_INPUT,SQL_C_CHAR, SQL_CHAR,sizeof(szBankName)-1,0,szBankName,sizeof(szBankName)-1,&cbBankName);

SQLCHAR szBankN[50+1]="";
SQLINTEGER cbBankN = SQL_NTS;
sqlreturn = SQLBindParameter(g_hstmt,4,SQL_PARAM_INPUT,SQL_C_CHAR, SQL_CHAR,sizeof(szBankN)-1,0,szBankN,sizeof(szBankN)-1,&cbBankN);

SQLSMALLINT onum = 7747; // biktest
sqlreturn = SQLBindParameter(g_hstmt,5,SQL_PARAM_INPUT,SQL_C_SHORT,SQL_SMALLINT,0,0,&onum,0,0);

SQLSMALLINT sort = 1;
sqlreturn = SQLBindParameter(g_hstmt,6,SQL_PARAM_INPUT,SQL_C_SHORT,SQL_SMALLINT,0,0,&sort,0,0);

SQLINTEGER kolzap = 0;
sqlreturn = SQLBindParameter(g_hstmt,7,SQL_PARAM_OUTPUT,SQL_C_LONG,SQL_INTEGER,0,0,&kolzap,0,0);

SQLINTEGER rez = 0;
sqlreturn = SQLBindParameter(g_hstmt,8,SQL_PARAM_OUTPUT,SQL_C_LONG,SQL_INTEGER,0,0,&rez,0,0);

// biktest
sqlreturn = SQLExecDirect(g_hstmt,
(unsigned char*)"{call p_Bik_Select_test6(?,?,?,?,?,?,?,?)}", SQL_NTS);

sqlstate = SQLFetch(g_hstmt); //
sqlstate = SQLFetch(g_hstmt); //
sqlstate = SQLFetch(g_hstmt); //
sqlstate = SQLFetch(g_hstmt); //

/*******************************************/
CREATE PROCEDURE p_Bik_Select_test6
@code_bank INT ,
@BIK CHAR(12) ,
@BankName VARCHAR (50) ,
@BankN VARCHAR (50) ,
@onum SMALLINT ,
@Sort TINYINT ,
@KolZap INT OUTPUT ,
@Rez INT = 0 OUTPUT
As
Declare @Errmsg varchar(1000), @ErrCode int, @ret int , @strSQL varchar(4000),
@Str1 varchar(1000)
Declare @spxName varchar(50)
SET NOCOUNT ON

SELECT @spxName = CHAR(13) + '(' + name + ')' from sysobjects(nolock) where id = @@procid
BEGIN
Select @strSQL =
'Select [code_bank], [bankName], [bankN], [bankCity],
[onum], [bik] '
Select @strSQL = @strSQL + ' From biktest (nolock) '

if @Code_bank > 0
Begin
Select @strSQL = @strSQL + ' Where Del = 0 and [code_bank] = ' + CONVERT(VARCHAR, @Code_bank )
if Len( @Onum ) > 0
Begin
Select @strSQL = @strSQL + ' and Onum = ' + CONVERT(VARCHAR, @Onum )
end
end
ELSE
Begin
Select @strSQL = @strSQL + ' Where Del = 0 '
if Len( @Bik ) > 0
Begin
Select @strSQL = @strSQL + ' and [bik] = ' + @Bik
end
if Len( @bankName ) > 0
Begin
Select @strSQL = @strSQL + ' and [bankName] Like ' + '''%' + @bankName + '%'''
end
else
if Len( @bankN ) > 0
Begin
Select @strSQL = @strSQL + ' and [bankN] = ' + @bankN
end
if Len( @Onum ) > 0
Begin
Select @strSQL = @strSQL + ' and Onum = ' + CONVERT(VARCHAR, @Onum )
end
end

if @Sort > 0
Select @strSQL = @strSQL
+
CASE @Sort
WHEN 1 THEN ' Order By [code_bank]'
WHEN 2 THEN ' Order By [bankN]'
ELSE ''
END

exec ( @strSQL )

SET @KolZap = @@rowcount

SET @ErrCode = @@error
IF @ErrCode <> 0
BEGIN
SELECT @spxName = CHAR(13) + '(' + name + ')' from sysobjects(nolock) where id = @@procid
SELECT @ErrMsg = 'Ошибка ' + CONVERT(VARCHAR,@ErrCode) + ': Невозможно выполнить Select ...' + @spxName
GOTO ERROR_EXIT
END

END

NORMA:
SET @Rez = 0
RETURN 0
ERROR_EXIT:
SET @Rez = -1
SELECT @ret = 16 - @@NESTLEVEL
RAISERROR(@ErrMsg, @ret , -1, @ErrCode)
RETURN -1
GO
17 май 11, 21:09    [10667751]     Ответить | Цитировать Сообщить модератору
 Re: Помогите вернуть из ХП данные через парамеры  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Guest99
Очень расчитываю на ваше участие.

Извини, но экстремальный говнокод даже так читать никто не будет:
Guest99
+ тестовые данные
/************************************/


declare @kolzap int
declare @rez int
set @kolzap =-9
set @rez = -8
exec p_Bik_Select_test6 3,'','','',7747,1,@kolzap   OUT,@rez   OUT
select @kolzap,@rez

/*************************************/
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[biktest]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[biktest]
GO
CREATE TABLE [dbo].[biktest] (
	[code_bank] [int] IDENTITY (1, 1) NOT NULL ,
	[bik] [char] (12) COLLATE Cyrillic_General_CI_AS NULL ,
	[bankname] [varchar] (50) COLLATE Cyrillic_General_CI_AS NULL ,
	[bankcity] [varchar] (50) COLLATE Cyrillic_General_CI_AS NULL ,
	[onum] [smallint] NULL ,
	[bankn] [char] (10) COLLATE Cyrillic_General_CI_AS NULL ,
	[del] [tinyint] NULL 
) ON [PRIMARY]
GO
/*************************************/
/*
begin transaction
go
*/
insert biktest VALUES ('121234345316','ОАО Моссранск-банк','Шалопаевск',7747,'Моссранск',0)
insert biktest VALUES ('747634905693','ЗАО Плутобанк','Колупаевск',7747,'Плуто',0)
insert biktest VALUES ('382717090320','ООО Верхневоровсий','Хапуженск',7747,'Верхневор',0)
insert biktest VALUES ('297054802357','ОПС Озеро','Чубасранск',7747,'ОПС',0)
insert biktest VALUES ('187924462847','КБ Шестирукий','Волобуевск',7747,'Шестирукий',0)
go
select * from biktest
go
/*
rollback
go
*/
+ C++
/*************************************/
// C++  proc
SQLRETURN  sqlreturn, sqlstate ;
SQLCHAR ConnectionStringIn[89] ="DRIVER={SQL Server};SERVER=serv12\\inst1;UID=Log1;PWD=Log12345;DATABASE=SOLD;";
SQLCHAR ConnectionStringOut[250] = ""; 
SQLSMALLINT StrOutSize = 0;
SQLSMALLINT g_id;
SQLSMALLINT g_count;

SQLHENV g_henv = SQL_NULL_HENV;
SQLHDBC g_hdbc = SQL_NULL_HDBC;
SQLHSTMT g_hstmt = SQL_NULL_HSTMT;

sqlreturn = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&g_henv);
sqlreturn = SQLSetEnvAttr(g_henv,SQL_ATTR_ODBC_VERSION,(void*) SQL_OV_ODBC3,NULL);
sqlreturn = SQLAllocHandle(SQL_HANDLE_DBC, g_henv,&g_hdbc);

sqlreturn = SQLDriverConnect(g_hdbc, GetForegroundWindow(), 
	ConnectionStringIn, SQL_NTS, 
	(unsigned char *)"", SQL_NTS,	// string OUT no used
	&StrOutSize, SQL_DRIVER_NOPROMPT); //no Call GetForegroundWindow()

sqlreturn = SQLAllocHandle(SQL_HANDLE_STMT,g_hdbc,&g_hstmt) ;
//sqlreturn = SQLSetConnectAttr(g_hdbc, SQL_LOGIN_TIMEOUT, (void *)5, 0);

SQLINTEGER  codebank = 4;
sqlreturn = SQLBindParameter(g_hstmt,1,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&codebank,0,0);

SQLCHAR     szBIK[12+1]="";
SQLINTEGER  cbBIK = SQL_NTS;
sqlreturn = SQLBindParameter(g_hstmt,2,SQL_PARAM_INPUT,SQL_C_CHAR, SQL_CHAR,sizeof(szBIK)-1,0,szBIK,sizeof(szBIK)-1,&cbBIK);

SQLCHAR     szBankName[50+1]="";
SQLINTEGER  cbBankName = SQL_NTS;
sqlreturn = SQLBindParameter(g_hstmt,3,SQL_PARAM_INPUT,SQL_C_CHAR, SQL_CHAR,sizeof(szBankName)-1,0,szBankName,sizeof(szBankName)-1,&cbBankName);

SQLCHAR     szBankN[50+1]="";
SQLINTEGER  cbBankN = SQL_NTS;
sqlreturn = SQLBindParameter(g_hstmt,4,SQL_PARAM_INPUT,SQL_C_CHAR, SQL_CHAR,sizeof(szBankN)-1,0,szBankN,sizeof(szBankN)-1,&cbBankN);

SQLSMALLINT onum = 7747;  // biktest
sqlreturn = SQLBindParameter(g_hstmt,5,SQL_PARAM_INPUT,SQL_C_SHORT,SQL_SMALLINT,0,0,&onum,0,0);

SQLSMALLINT     sort = 1;
sqlreturn = SQLBindParameter(g_hstmt,6,SQL_PARAM_INPUT,SQL_C_SHORT,SQL_SMALLINT,0,0,&sort,0,0);

SQLINTEGER  kolzap = 0;
sqlreturn = SQLBindParameter(g_hstmt,7,SQL_PARAM_OUTPUT,SQL_C_LONG,SQL_INTEGER,0,0,&kolzap,0,0);

SQLINTEGER  rez = 0;
sqlreturn = SQLBindParameter(g_hstmt,8,SQL_PARAM_OUTPUT,SQL_C_LONG,SQL_INTEGER,0,0,&rez,0,0);

  // biktest
sqlreturn = SQLExecDirect(g_hstmt, 
  (unsigned char*)"{call p_Bik_Select_test6(?,?,?,?,?,?,?,?)}", SQL_NTS);

sqlstate = SQLFetch(g_hstmt);	//  
sqlstate = SQLFetch(g_hstmt);	//     
sqlstate = SQLFetch(g_hstmt);	//  
sqlstate = SQLFetch(g_hstmt);	//  

/*******************************************/
+ працэдура
CREATE PROCEDURE p_Bik_Select_test6
	@code_bank	INT			,
	@BIK		CHAR(12) 		, 
	@BankName	VARCHAR (50)		, 
	@BankN	VARCHAR (50) 		, 
	@onum		SMALLINT		, 
	@Sort		TINYINT		,
	@KolZap	INT	OUTPUT	,
	@Rez		INT = 0   OUTPUT 
As
Declare @Errmsg varchar(1000), @ErrCode int,  @ret int , @strSQL varchar(4000), 
	@Str1	varchar(1000)
Declare @spxName	varchar(50)  
SET NOCOUNT ON

SELECT @spxName = CHAR(13) + '(' + name + ')' from sysobjects(nolock) where id = @@procid
BEGIN
Select  @strSQL =  
'Select  [code_bank], [bankName], [bankN],  [bankCity], 
  [onum],  [bik]   '
Select  @strSQL = @strSQL + ' From   biktest  (nolock)  '

if @Code_bank  > 0
Begin	
	Select  @strSQL = @strSQL + ' Where  Del = 0 and  [code_bank]  = ' +  CONVERT(VARCHAR, @Code_bank ) 
	if Len( @Onum ) > 0
	Begin
		Select  @strSQL = @strSQL +  ' and Onum =  '  + CONVERT(VARCHAR,  @Onum  )    
	end
end
ELSE
Begin
	Select  @strSQL = @strSQL + ' Where  Del = 0  '
	if Len( @Bik ) > 0
	Begin
		Select  @strSQL = @strSQL + ' and  [bik] = ' + @Bik
	end
	if Len( @bankName ) > 0
	Begin
		Select  @strSQL = @strSQL + ' and  [bankName]   Like ' +   '''%' + @bankName + '%''' 
	end
	else
		if Len( @bankN  ) > 0
		Begin
			Select  @strSQL = @strSQL + ' and  [bankN] = ' + @bankN
		end
	if Len( @Onum ) > 0
	Begin
		Select  @strSQL = @strSQL +  ' and  Onum =  '  + CONVERT(VARCHAR,  @Onum  )    
	end
end

if @Sort > 0
	Select  @strSQL = @strSQL  
	 + 	
	CASE @Sort 
	WHEN   1 THEN  ' Order By [code_bank]' 
	WHEN   2 THEN  ' Order By [bankN]' 
	ELSE ''
	END

exec ( @strSQL )

SET @KolZap	= @@rowcount

SET @ErrCode = @@error
IF @ErrCode <> 0 
BEGIN
	SELECT @spxName = CHAR(13) + '(' + name + ')' from sysobjects(nolock) where id = @@procid
	SELECT @ErrMsg = 'Ошибка ' + CONVERT(VARCHAR,@ErrCode) + ': Невозможно выполнить Select ...'  + @spxName
	GOTO ERROR_EXIT
END

END

NORMA:
	SET @Rez	= 0
	RETURN 0
ERROR_EXIT:
	SET @Rez	= -1
	SELECT @ret = 16 - @@NESTLEVEL
	RAISERROR(@ErrMsg, @ret , -1, @ErrCode)
  	RETURN -1
GO
Странно, но у меня вместо bik проходит на ум BIC, хотя ...

Убери нафиг динамический запрос, GOTO, параметр @Rez, передачу пустых строк и прочую обкуренную лабуду.
	SELECT	 code_bank
		,bankName
		,bankN
		,bankCity
		,onum
		,bik
	FROM  (		SELECT * FROM dbo.biktest WHERE  code_bank = @code_bank
	UNION ALL	SELECT * FROM dbo.biktest WHERE	@code_bank IS NULL AND  bik = @bik
	UNION ALL	SELECT * FROM dbo.biktest WHERE	@code_bank IS NULL AND @bik IS NULL AND (bankN = @bankN OR @bankN IS NULL) AND bankName LIKE '%' + @bankName + '%'
	) B	WHERE	    Del		= 0
			AND(Onum	= @Onum OR @Onum IS NULL)
	ORDER BY CASE WHEN @Sort = 1 THEN [code_bank]	END
		,CASE WHEN @Sort = 2 THEN [bankN]	END

	SET @kolzap = @@RowCount
END
GO
После этого выкинь процедуру фтопку и напиши нормально табличную (inline) функцию. А количество строк можно на клиенте через SQLRowCount получить.
И навесь индексы (иначе UNION бесполезен, можно было один голый WHERE написать).
		AND(bik		= @bik				OR @bik		IS NULL)
		AND(bankN	= @bankN			OR @bankN	IS NULL)
		AND(bankName	LIKE '%' + @bankName + '%'	OR @bankName	IS NULL)
Т.к. нет никакого смысла указывать хотя бы два параметра, поэтому можно выкидывать взаимную проверку параметров (IS NULL), ну разве для LIKE оставить по пожарке (т.к. FULL SCAN).

И больше никогда, слышишь, никогда не пиши так как было написано в самом начале.
18 май 11, 01:03    [10668611]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить