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