Publish date: 2003-01-17
Stored procedure. IN-OUT parameters (VB, C++)
'SAMPLE OF WORK WITH EXECUTED STORED PROCEDURES
'
'CREATE PROCEDURE SP_EXEC_1 (ARG_INT INTEGER,
' ARG_DATE DATE,
' ARG_STR VARCHAR(32))
'RETURNS (OUT_INT_1 INTEGER,
' OUT_INT_2 INTEGER,
' OUT_DATE DATE,
' OUT_STR VARCHAR(32))
'AS
'BEGIN
' OUT_INT_1=-ARG_INT;
' OUT_INT_2=2*ARG_INT;
'
' OUT_DATE =OUT_DATE+1;
'
' OUT_STR =UPPER(ARG_STR);
'END
'check SP result
Sub sample_8_1_check_out_parametrs(params As ADODB.Parameters)
If (params("out_int_1") <> -params("int")) Then Err.Raise -1, , "incorrect OUT_INT_1"
If (params("out_int_2") <> 2 * params("int")) Then Err.Raise -1, , "incorrect OUT_INT_2"
If (params("out_date") <> params("date") + 1) Then Err.Raise -1, , "incorrect OUT_DATE"
If (params("out_str") <> UCase(params("str"))) Then Err.Raise -1, , "incorrect OUT_STR"
End Sub
Sub sample_8_1()
Dim cn As New ADODB.Connection
cn.Provider = "LCPI.IBProvider"
cn.Open "data source=main:e:\database\ibp_test.gdb;ctype=win1251", "gamer", "vermut"
cn.BeginTrans
Dim cmd As New ADODB.Command
cmd.ActiveConnection = cn
cmd.CommandText = "execute procedure sp_exec_1(:int,:date,:str)"
'automating defining of parameters ----------------------------------------------
cmd.Parameters.Refresh
cmd("int") = 2
cmd("date") = Date
cmd("str") = "lower chars"
cmd.Execute
'check SP result
Call sample_8_1_check_out_parametrs(cmd.Parameters)
'user defining of UNNAMED parameters --------------------------------------------
cmd.CommandText = "execute procedure sp_exec_1(?,?,?)"
While cmd.Parameters.Count
cmd.Parameters.Delete (0)
Wend
'IN-parameters
cmd.Parameters.Append cmd.CreateParameter("int", adInteger, adParamInput, , 2)
cmd.Parameters.Append cmd.CreateParameter("date", adDate, adParamInput, , Date)
cmd.Parameters.Append cmd.CreateParameter("str", adBSTR, adParamInput, , "small chars")
'OUT-parameters
cmd.Parameters.Append cmd.CreateParameter("out_int_1", adInteger, adParamOutput)
cmd.Parameters.Append cmd.CreateParameter("out_int_2", adInteger, adParamOutput)
cmd.Parameters.Append cmd.CreateParameter("out_date", adDate, adParamOutput)
cmd.Parameters.Append cmd.CreateParameter("out_str", adBSTR, adParamOutput)
cmd.Execute
'check SP result
Call sample_8_1_check_out_parametrs(cmd.Parameters)
'user defining of NAMED parameters (support only in ADO 2.6 and next) ------------
cmd.CommandText = "execute procedure sp_exec_1(:int,:date,:str)"
While cmd.Parameters.Count
cmd.Parameters.Delete (0)
Wend
'IN-parameters
cmd.Parameters.Append cmd.CreateParameter("int", adInteger, adParamInput, , 3)
cmd.Parameters.Append cmd.CreateParameter("date", adDate, adParamInput, , Date - 10)
cmd.Parameters.Append cmd.CreateParameter("str", adBSTR, adParamInput, , "small chars 2")
'OUT-parameters
cmd.Parameters.Append cmd.CreateParameter("out_int_1", adInteger, adParamOutput)
cmd.Parameters.Append cmd.CreateParameter("out_int_2", adInteger, adParamOutput)
cmd.Parameters.Append cmd.CreateParameter("out_date", adDate, adParamOutput)
cmd.Parameters.Append cmd.CreateParameter("out_str", adBSTR, adParamOutput)
cmd.NamedParameters = True 'support only ADO 2.6 and next
cmd.Execute
'check SP result
Call sample_8_1_check_out_parametrs(cmd.Parameters)
'Selective reception OUT-parameters - only 'out_int_2' and 'out_str'
cmd.Parameters.Delete ("out_int_1")
cmd.Parameters.Delete ("out_date")
'init out-parameters
cmd("out_int_2") = Empty
cmd("out_str") = Empty
cmd.Execute
'print of 2 and 4 OUT-parameters
Debug.Print "out_int_2=" & CStr(cmd("out_int_2"))
Debug.Print "out_str=" & cmd("out_str")
cn.CommitTrans
End Sub 'sample_8_1
#define _TRACE(obj,func) \
{ \
cout<<#obj<<"."<<#func<<endl; \
\
_THROW_OLEDB_FAILED(obj,func) \
}
////////////////////////////////////////////////////////////////////////////////
//class TSampleCode8_1
void TSampleCode8_1::test_value(t_db_base_row& params,LPCSTR param_name,LPCSTR value)
{
using structure::str_formatter;
const t_db_base_row::size_type x=params.get_index(param_name);
if(x==t_db_base_row::npos)
{
throw runtime_error(str_formatter("param \"%1\" not found")<<param_name);
}
if(params[x].as_string!=value)
{
str_formatter fmsg("incorrect value of %1\n"
"need [%2]. get from SP [%3].");
throw runtime_error(fmsg<<param_name<<value<<params[x].as_string);
}
cout<<param_name<<":"<<params[x].as_string<<endl;
}//test_value
//------------------------------------------------------------------------
void TSampleCode8_1::sample_8_1_check_out_parametrs(t_db_base_row& params)
{
cout<<" #sample_8_1_check_out_parametrs"<<endl;
test_value(params,"out_int_1","-2");
test_value(params,"out_int_2","4");
test_value(params,"out_date","02.11.2004");
test_value(params,"out_str","LOWER CHARS");
}//sample_8_1_check_out_parametrs
//------------------------------------------------------------------------
void TSampleCode8_1::execute()
{
using namespace oledb_lib;
cout<<"Sample #8.1"<<endl;
try
{
t_db_data_source data_source;
t_db_session session;
t_db_command cmd;
_TRACE(data_source,attach("file name=ibp_test.ibp"))
_TRACE(session,create(data_source))
_TRACE(session,start_transaction())
t_db_auto_commit const __auto_commit(session);
_TRACE(cmd,create(session))
_TRACE(cmd,prepare("execute procedure sp_exec_1(:int,:date,:str)",NULL))
//Automating defining of parameters ------------------------------------
cout<<endl
<<"test #1 [provider return param descriptions]"<<endl;
t_db_row params;
_TRACE(cmd,describe_params(params))
params["int"] =2;
params["date"] ="01.11.2004";
params["str"] ="lower chars";
_TRACE(cmd,execute(¶ms,false))
sample_8_1_check_out_parametrs(params);
//user defining of parameters ------------------------------------------
cout<<endl
<<"test #2 [user build param descriptions]"<<endl;
params.init();
params.create_param("int") =2;
params.create_param("date") ="01.11.2004";
params.create_param("str") ="lower chars";
params.create_param("out_int_1",adInteger ,DBPARAMFLAGS_ISOUTPUT);
params.create_param("out_int_2",adInteger ,DBPARAMFLAGS_ISOUTPUT);
params.create_param("out_date" ,adDate ,DBPARAMFLAGS_ISOUTPUT);
params.create_param("out_str" ,adVarChar ,DBPARAMFLAGS_ISOUTPUT);
_TRACE(cmd,execute(¶ms,false))
sample_8_1_check_out_parametrs(params);
//select 'out_int_2' and 'out_str' parameters --------------------------
cout<<endl
<<"test #2 [select 'out_int_2' and 'out_str' parameters]"<<endl;
params.init();
//use alternative method of assign parameters descriptions
params.set_param(0,"int") =123;
params.set_param(1,"date") ="03.11.2004";
params.set_param(2,"str") ="qwerty";
params.set_param(3,"out_int_2",adInteger,DBPARAMFLAGS_ISOUTPUT);
params.set_param(4,"out_str" ,adBSTR ,DBPARAMFLAGS_ISOUTPUT);
params.count=5;
_TRACE(cmd,execute(¶ms,false))
cout<<"out_int_2:"<<params["out_int_2"].as_string<<endl;
cout<<"out_str:"<<params["out_str"].as_string<<endl;
}
catch(const exception& exc)
{
cout<<endl;
cout<<"error:"<<exc.what()<<endl;
}
}//execute
