fluent nhibernate calling oracle function - oracle

`i try to call an oracle function inside a package
function :
FUNCTION test_func (I_PARAMS IN TPARAMS,
O_RESPONSE_CODE OUT VARCHAR2,
O_RESPONSE_EXPLANATION OUT VARCHAR2)
RETURN BOOLEAN IS
BEGIN
O_RESPONSE_CODE := 0;
O_RESPONSE_EXPLANATION := 'Başarılı';
return true;
END test_func;
Ora test script:
declare
I_PARAMS TPARAMS;
O_RESPONSE_CODE VARCHAR2(4);
O_RESPONSE_EXPLANATION VARCHAR2(500);
reslt boolean;
begin
O_RESPONSE_EXPLANATION := ' a';
O_RESPONSE_CODE := '2';
reslt := D_PKG.test_func(I_PARAMS , O_RESPONSE_CODE , O_RESPONSE_EXPLANATION );
dbms_output.put_line(o_response_explanation || ' ' || o_response_code);
end;
it works but my fluent code does not work :S could anyone help me?
and here is it...
IQuery query = session.CreateSQLQuery("reslt := D_PKG.test_func(I _PARAMS , O_RESPONSE_CODE , O_RESPONSE_EXPLANATION )")
.SetParameter("I_PARAMS", input, NHibernateUtil.Object)
.SetString("O_RESPONSE_CODE", null)
.SetString("O_RESPONSE_EXPLANATION", null)
.SetBoolean("reslt",false);
output.RESULT = query.ExecuteUpdate();
here is my Parameter I_PARAMS does not exist as a named parameter

May be session.CreateSQLQuery("reslt := D_PKG.test_func(:I _PARAMS , :O_RESPONSE_CODE , :O_RESPONSE_EXPLANATION )"). Missed the : char?

Related

How to concat a string to a variable in pl/sql(oracle function)?

I am trying to create a function that outputs non-english words in a string but i am getting the following error:
PLS-00103: Encountered the symbol "|" when expecting one of the
following:
:= . ( # % ;
The symbol ":= was inserted before "|" to continue.
The code that gives the error:
CREATE OR REPLACE Function
-- ...
IS
s varchar2(38);
lang varchar2(100);
begin
s := -- ...
lang := -- ...
lang || s; -- trying to concate here
end;
The concatenation operator seems not to be working. Can anyone point out any mistake I'm making.
As OldProgrammer wrote in a comment:
lang || s
should be
lang := lang || s
The errors are:
RETURN VARCHAR2 and not RETURN string
REGEXP_LIKE returns a boolean and not a string.
lang || s; should be lang := lang || s;
Which would give you the code:
CREATE OR REPLACE Function findAssamese(
string IN varchar2
) RETURN VARCHAR2
IS
s varchar2(38);
lang varchar2(100);
begin
for i in 1..length(string) loop
s := Substr(string,i,1);
if REGEXP_LIKE (s, '[A-Z]') OR REGEXP_LIKE (s, '[a-z]') then
lang := lang || s; -- trying to concate here
end if;
end loop;
return lang;
end;
/
However, you could simply write:
CREATE OR REPLACE Function findAssamese(
string IN varchar2
) RETURN VARCHAR2
IS
begin
return REGEXP_REPLACE(string, '[^A-Z]', NULL, 1, 0, 'i');
end;
/
db<>fiddle here

Oracle Reference to uninitialized composite while passing object as output parameter PL/SQL

I have a problem with "ORA-06530: Reference to uninitialized composite". The object is as far as I understand initialiazed.
CREATE OR REPLACE TYPE t_RetVal AS OBJECT
(
var_n_retVal NUMBER,
var_n_sqlcode NUMBER,
var_v_sqlerrm VARCHAR(255),
CONSTRUCTOR FUNCTION t_RetVal(SELF IN OUT NOCOPY t_RetVal) RETURN SELF AS RESULT
);
/
CREATE OR REPLACE TYPE BODY t_RetVal AS
CONSTRUCTOR FUNCTION t_RetVal(SELF IN OUT NOCOPY t_RetVal) RETURN SELF AS RESULT IS
BEGIN
SELF.var_n_retVal := 1;
SELF.var_n_sqlcode := 0;
SELF.var_v_sqlerrm := '';
RETURN;
END;
END;
create or replace FUNCTION get_Something(
id IN NUMBER,
out_t_RetVal OUT NOCOPY t_RetVal
)
RETURN NUMBER
IS
retVal NUMBER := 1;
BEGIN
out_t_RetVal.var_n_retVal:= 1;
out_t_RetVal.var_n_sqlcode := 0;
out_t_RetVal.var_v_sqlerrm := '';
RETURN out_t_RetVal;
END;
In the procedure i do the following and keep getting "ORA-06530: Reference to uninitialized composite".
create or replace procedure PROC is
var_t_SubFuncRetVal t_RetVal;
v_n_retVal number := 0;
v_error_text varchar2(1000);
BEGIN /*PROCEDURE START*/
var_t_SubFuncRetVal := t_RetVal();
v_n_retVal := get_Something( id, var_t_SubFuncRetVal);
IF (var_t_SubFuncRetVal.var_n_retVal >= 0) THEN
IF (var_t_SubFuncRetVal.var_n_retVal = 0) THEN
....
ELSE
....
END IF;
ELSE
v_error_text := 'Error message is '|| 'SQLCODE: '||var_t_SubFuncRetVal.var_n_sqlcode||' -- ERROR: '||var_t_SubFuncRetVal.var_v_sqlerrm;
END IF;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
END PROC;
Why is Oracle reporting this error ? How to properly pass object as out parameter ?

FireDac Call Function in Oracle

My code :
FDStoredProc1.StoredProcName := 'aaaaa' ;
with FDStoredProc1.Params do begin
Clear;
with Add do begin
ParamType := ptInput;
DataType := ftInteger;
end;
end;
FDStoredProc1.Params[0].Value := StrToint(edit1.Text) ;
edit1.Text := FDStoredProc1.ExecFunc() ;
My code in Oracle :
create or replace FUNCTION AAAAA (pn number) RETURN VARCHAR2 AS
BEGIN
update dmnv set thuong = pn ;
commit ;
RETURN '3'
END AAAAA;
There is no error when running, but the parameter is NULL at Oracle Server (version 12). So function is exec on Server with wrong parameter (the true parameter is the value in edit1.text).I have typed a number at edit1.
Give the parameter a name.
with Add do begin
Name := 'pn';
ParamType := ptInput;
DataType := ftInteger;
end;
with FDQuery1.SQL do begin
Clear;
Add('begin');
Add(' select aaaaa(8) from dual ;');
Add('end;');
end;
FDQuery1.ExecSQL;
Also get error.a INTO clause is expected

Find string value based on a string key in a given string

I have a string like so:
Directory=Voice Active Directory A,ID=VT-AD1,Location=Canada,UserName=admin,Password=passw0rd,Selector=AD1
I'm writing a function that will receive this value as parameter and another parameter as UserName
I need to find the value against key UserName from the given string which is admin
I'm searching if there is a RegEx within oracle to help out here.
Here is what I have made so far:
CREATE OR REPLACE FUNCTION GET_CSV_FIELD(Parameter_RowData IN CLOB, Parameter_Field_Name IN VARCHAR2 )
RETURN VARCHAR2
AS
Found_Index INTEGER;
End_Index INTEGER;
Pair_Index INTEGER;
Return_Result VARCHAR2(4000);
BEGIN
Found_Index := INSTR(Parameter_RowData, Parameter_Field_Name);
IF Found_Index > 0 THEN
End_Index := INSTR(Parameter_RowData, ',', Found_Index);
Pair_Index := INSTR(Parameter_RowData, '=', Found_Index);
IF End_Index = 0 THEN
Return_Result := '';
RETURN Return_Result;
END IF;
IF Pair_Index = 0 THEN
Return_Result := '';
RETURN Return_Result;
END IF;
Return_Result := SUBSTR(Parameter_RowData, Pair_Index + 1, End_Index - Pair_Index - 1);
ELSE
Return_Result := '';
END IF;
RETURN Return_Result;
END;
Any better method? Thanks.
You can do this with regular expressions:
select substr(regexp_substr(str, 'UserName=[^,]+'), 10)
The general method would be
select substr(regexp_substr(str, v_param || '=[^,]+'), length(v_param) + 2)

array or list into Oracle using cfprocparam

I have a list of values I want to insert into a table via a stored procedure.
I figured I would pass an array to oracle and loop through the array but I don't see how to pass an array into Oracle. I'd pass a list but I don't see how to work with the list to turn it into an array using PL/SQL (I'm fairly new to PL/SQL). Am I approaching this the wrong way?
Using Oracle 9i and CF8.
EDIT
Perhaps I'm thinking about this the wrong way? I'm sure I'm not doing anything new here...
I figured I'd convert the list to an associative array then loop the array because Oracle doesn't seem to work well with lists (in my limited observation).
I'm trying to add a product, then add records for the management team.
-- product table
productName = 'foo'
productDescription = 'bar'
...
...
etc
-- The managementteam table just has the id of the product and id of the users selected from a drop down.
The user IDs are passed in via a list like "1,3,6,20"
How should I go about adding the records to the management team table?
Here is where I am code wise
In theory I pass a list "1,2,3,4" to inserts.addProduct.
inserts.addProduct should call tools.listToArray and return an array.
inserts.addProduct recreates a list with a * delim as a test.
CREATE OR REPLACE PACKAGE tools AS
TYPE array_type is TABLE OF VARCHAR2(225) INDEX BY BINARY_INTEGER;
FUNCTION listToArray(in_list IN VARCHAR,
in_delim IN VARCHAR2 DEFAULT ',')
RETURN array_type;
END tools;
CREATE OR REPLACE PACKAGE BODY tools
AS
FUNCTION listToArray(in_list IN VARCHAR,
in_delim IN VARCHAR2 DEFAULT ',')
RETURN array_type
IS
l_token_count BINARY_INTEGER := 0;
-- l_token_tbl type_array;
i pls_integer;
l_start_pos INTEGER := 1;
l_end_pos INTEGER :=1;
p_parsed_table array_type;
BEGIN -- original work by John Spencer
WHILE l_end_pos <> 0 LOOP
l_end_pos := instr(in_list,in_delim,l_start_pos);
IF l_end_pos <> 0 THEN
l_token_count := l_token_count + 1;
p_parsed_table(l_token_count ) :=
substr(in_list,l_start_pos,l_end_pos - l_start_pos);
l_start_pos := l_end_pos + 1;
END IF;
END LOOP;
IF l_token_count = 0 THEN /* We haven't parsed anything so */
l_token_count := 1;
p_parsed_table(l_token_count) := in_list;
ELSE /* We need to get the last token */
l_token_count := l_token_count + 1;
p_parsed_table(l_token_count) := substr(in_list,l_start_pos);
END If;
RETURN p_parsed_table;
END listToArray; -- Procedure
END tools;
CREATE OR REPLACE PACKAGE inserts AS
TYPE array_type is TABLE OF VARCHAR2(225) INDEX BY BINARY_INTEGER;
PROCEDURE addProduct (inList IN VARCHAR2,
outList OUT VARCHAR2
);
END inserts;
CREATE OR REPLACE PACKAGE BODY inserts
AS
PROCEDURE addProduct (inList IN VARCHAR2,
outList OUT VARCHAR2
)
IS
i NUMBER;
localArray array_type := tools.listToArray(inList);
BEGIN
outList := '';
FOR i IN localArray.first .. localArray.last LOOP
outList := outList || '*' ||localArray(i); -- return a string just to test this mess
END LOOP;
END addProduct;
END inserts;
I'm currently getting an error "PLS-00382: expression is of wrong type" on localArray array_type := tools.listToArray(inList);
final working code (thanks so much!)
-- create sql type collection
CREATE OR REPLACE TYPE array_type is TABLE OF VARCHAR2(225);
/
CREATE OR REPLACE PACKAGE tools AS
FUNCTION listToArray(in_list IN VARCHAR,
in_delim IN VARCHAR2 DEFAULT ',')
RETURN array_type;
END tools;
/
CREATE OR REPLACE PACKAGE BODY tools
AS
FUNCTION listToArray(in_list IN VARCHAR,
in_delim IN VARCHAR2 DEFAULT ',')
RETURN array_type
IS
l_token_count BINARY_INTEGER := 0;
i pls_integer;
l_start_pos INTEGER := 1;
l_end_pos INTEGER :=1;
p_parsed_table array_type := array_type();
BEGIN
WHILE l_end_pos <> 0 LOOP
l_end_pos := instr(in_list,in_delim,l_start_pos);
IF l_end_pos <> 0 THEN
p_parsed_table.extend(1);
l_token_count := l_token_count + 1;
p_parsed_table(l_token_count ) :=
substr(in_list,l_start_pos,l_end_pos - l_start_pos);
l_start_pos := l_end_pos + 1;
END IF;
END LOOP;
p_parsed_table.extend(1);
IF l_token_count = 0 THEN /* We haven't parsed anything so */
l_token_count := 1;
p_parsed_table(l_token_count) := in_list;
ELSE /* We need to get the last token */
l_token_count := l_token_count + 1;
p_parsed_table(l_token_count) := substr(in_list,l_start_pos);
END If;
RETURN p_parsed_table;
END listToArray; -- Procedure
END tools;
/
CREATE OR REPLACE PACKAGE inserts AS
PROCEDURE addProduct (inList IN VARCHAR2,
outList OUT VARCHAR2
);
END inserts;
/
CREATE OR REPLACE PACKAGE BODY inserts
AS
PROCEDURE addProduct (inList IN VARCHAR2,
outList OUT VARCHAR2
)
IS
i NUMBER;
mylist VARCHAR(100);
localArray array_type := array_type();
BEGIN
localArray := tools.listToArray(inList);
mylist := '';
FOR i IN localArray.first .. localArray.last LOOP
mylist := mylist || localArray(i) || '*';
END LOOP;
aList := mylist;
END addProduct;
END inserts;
/
PL/SQL has supported arrays since Oracle 8.0. They used to be called PL/SQL tables which confused the heck out of everybody, so now they are called collections. Find out more.
The problem is, that they are implemented as User-Defined Types (i.e. objects). My reading of the ColdFusion documents suggests that cfprocparam only supports the "primitive" datatypes (number, varchar2, etc). So UDTs are not supported.
I'm not sure what you mean by this:
I'd pass a list but I don't see how to
work with the list to turn it into an
array using PL/SQL
If you mean you want to pass a string of comma separated values ....
"Fox in socks, Mr Knox, Sam-I-Am, The Lorax"
then I have a workaround for you. Oracle doesn't provide a built-in Tokenizer. But a long time ago John Spencer published a hand-rolled solution which works in Oracle 9i on the OTN forums. Find it here.
edit
but... Oracle hates me
Do not despair. The OTN forums have been upgraded a few times since John posted that , and the formatting seems to have corrupted the code somewhere along the way. There were a couple of compilation errors which it didn't use to have.
I have rewritten John's code, including a new function. THe main difference is that the nested table is declared as a SQL type rather than a PL/SQL type.
create or replace type tok_tbl as table of varchar2(225)
/
create or replace package parser is
function my_parse(
p_str_to_search in varchar2
, p_delimiter in varchar2 default ',')
return tok_tbl;
procedure my_parse(
p_str_to_search in varchar2
, p_delimiter in varchar2 default ','
, p_parsed_table out tok_tbl);
end parser;
/
As you can see, the function is just a wrapper to the procedure.
create or replace package body parser is
procedure my_parse ( p_str_to_search in varchar2
, p_delimiter in varchar2 default ','
, p_parsed_table out tok_tbl)
is
l_token_count binary_integer := 0;
l_token_tbl tok_tbl := tok_tbl();
i pls_integer;
l_start_pos integer := 1;
l_end_pos integer :=1;
begin
while l_end_pos != 0
loop
l_end_pos := instr(p_str_to_search,p_delimiter,l_start_pos);
if l_end_pos != 0 then
l_token_count := l_token_count + 1;
l_token_tbl.extend();
l_token_tbl(l_token_count ) :=
substr(p_str_to_search,l_start_pos,l_end_pos - l_start_pos);
l_start_pos := l_end_pos + 1;
end if;
end loop;
l_token_tbl.extend();
if l_token_count = 0 then /* we haven't parsed anything so */
l_token_count := 1;
l_token_tbl(l_token_count) := p_str_to_search;
else /* we need to get the last token */
l_token_count := l_token_count + 1;
l_token_tbl(l_token_count) := substr(p_str_to_search,l_start_pos);
end if;
p_parsed_table := l_token_tbl;
end my_parse;
function my_parse ( p_str_to_search in varchar2
, p_delimiter in varchar2 default ',')
return tok_tbl
is
rv tok_tbl;
begin
my_parse(p_str_to_search, p_delimiter, rv);
return rv;
end my_parse;
end parser;
/
The virtue of declaring the type in SQL is that we can use it in a FROM clause like this:
SQL> insert into t23
2 select trim(column_value)
3 from table(parser.my_parse('Fox in socks, Mr Knox, Sam-I-Am, The Lorax'))
4 /
4 rows created.
SQL> select * from t23
2 /
TXT
------------------------------------------------------------------------------
Fox in socks
Mr Knox
Sam-I-Am
The Lorax
SQL>

Resources