Here is the code
vResult VARCHAR2(200);
BEGIN
fvData:=TRIM(fvData);
IF SUBSTR(fvData,LENGTH(fvData)-1,1)<>'*' THEN
fvData:=fvData||'**';
END IF;
vResult:=SUBSTR(fvData,1,InStr(fvData,'^^') - 1);
fvData:=SUBSTR(fvData,InStr(fvData,'^^') + 3);
RETURN vResult;
END StringExtract;
/
I have tried entering different ways, with fvdata=365 but nothing happens, I have try entering small SQL like
select InStr(367,'^^^^') - 1
from dual;
but I can't figure out how to do this big function.
In an attempt to help you get this working take a look at the following code. I have left out the detail of your function so we don't complicate things but you should be able to just plug that back in.
DECLARE
inputValue VARCHAR2(200) := :inputValue; -- << this bind variable allows you to provide different input each you run the code
FUNCTION stringExtract(fvData varchar2) RETURN varchar2
IS
vResult VARCHAR2(200);
BEGIN
vResult := TRIM(fvData);
RETURN vResult;
END stringExtract;
BEGIN
DBMS_OUTPUT.PUT_LINE(LENGTH(inputValue));
DBMS_OUTPUT.PUT_LINE(LENGTH(stringExtract(inputValue)));
END;
Hopefully you can take that as a template and adapt to get your program running.
Related
I have written following code in oracle pl/sql
create or replace procedure sorting_criteria(criteria in varchar)
as
begin
if(criteria='lowest price')
then
declare
p_name product.p_name%type;
cursor ptr is select p_name from product order by amount ASC;
begin
open ptr;
loop
fetch ptr into p_name;
exit when ptr%notfound;
dbms_output.put_line(p_name);
end loop;
close ptr;
end;
else if(criteria='highest price')
then
declare
p_name product.p_name%type;
cursor ptr is select p_name from product order by amount DESC;
begin
open ptr;
loop
fetch ptr into p_name;
exit when ptr%notfound;
dbms_output.put_line(p_name);
end loop;
close ptr;
end;
else
dbms_output.put_line('Enter valid criteria!');
end if;
end;
/
But it is giving following error: Error at line 35: PLS-00103: Encountered the symbol ";" when expecting one of the following: Please help
The ELSE-IF statement in PL/SQL has to be written as ELSIF. Otherwise, you should close the second IF with an other END IF; statement.
You can solve the issue by changing the ELSE IF at line 17 to an ELSIF
The answer by #GregorioPalamà correctly addresses your issues. But you can drastically reduce the workload by changing your thinking away from "If...then...else" to the "set of" and letting SQL do the work. In this case the only difference is sorting either ascending or descending on amount. The same effect can be achieved by sorting ascending on amount or minus amount; and SQL can make that decision. So you can reduce the procedure to validating the parameter and a single cursor for loop:
create or replace procedure sorting_criteria(criteria in varchar2)
as
cursor ptr(c_sort_criteria varchar2) is
select p_name
from product
order by case when c_sort_criteria = 'lowest price'
then amount
else -amount
end ;
begin
if criteria in ('lowest price', 'highest price')
then
for rec in ptr(criteria)
loop
dbms_output.put_line('Product: ' || rec.p_name );
end loop;
else
dbms_output.put_line('Enter valid criteria!');
end if;
end sorting_criteria;
/
See demo here. For demonstration purposed I added the amount to the dbms_output.
A couple notes:
While it is not incorrect using p_... as a column name, it is also
not a good idea. A very common convention (perhaps almost a
standard) to use p_... to indicate parameters. This easily leads to
confusion; confusion amongst developers is a bad thing.
IMHO it is a bug to name a local variable the same as a table
column name. While the compiler has scoping rules which one to use
it again leads to confusion. The statement "where table.name = name"
is always true, except when at least one of them is null, which possible could lead to updating/deleting every row in your table. In this
case p_name is both a column and a local variable.
I'm trying to get user input in SQLDeveloper in a procedure. But however , I'm getting some error like "missing defines". Please help me to solve this. Thanks in advance.
DECLARE
a NUMBER(5);
BEGIN
a := :a;
DBMS_OUTPUT.PUT_LINE('We took the number as ' || a);
END;
The error looks like this.
Error starting at line : 1 in command -
DECLARE
a NUMBER(5);
BEGIN
a := :a;
DBMS_OUTPUT.PUT_LINE('We took the number as ' || a);
END;
Error report -
Missing defines
We took the number as 15
Although I'm getting the correct answer at bottom, still why this errors?
Please execute the below statement:
DECLARE
a NUMBER(5):=15;
BEGIN
a := a;
DBMS_OUTPUT.PUT_LINE('We took the number as ' || a);
END;
In order to get user input in PLSQL Block, we use &, &givenumber will get the user input at run time.
DECLARE
a NUMBER(5);
BEGIN
a := &givenumber;
DBMS_OUTPUT.PUT_LINE('We took the number as ' || a);
END;
I have a pl sql code that execute three queries sequentially to determine a match level and do some logic
The issue is - when first query has no results (completely valid scenario) I get ORA-01403 No data found.
I understand that I need to incorporate [ Exception clause when NO_DATA_FOUND ]- but how to add it and continue to the next query?
PL/SQL Code
SELECT A into PARAM A FROM SAMPLE WHERE SOME CONDITION;
-- GOT ORA-01403 No data found HERE
MATCH_LEVEL =1;
if A is null then
do some logic;
end if
SELECT A INTO PARAM_B FROM SAMPLE WHERE SOME OTHER CONDITION
MATCH_LEVEL =2
if A is null then
do some logic 2;
end if
SELECT A INTO PARAM_B FROM SAMPLE WHERE SOME OTHER CONDITION
MATCH_LEVEL =3
if A is null then
do some logic 3;
end if
END PL/SQL Code
Declare
--your declarations
begin
SELECT A into PARAM A FROM SAMPLE WHERE SOME CONDITION;
-- GOT ORA-01403 No data found HERE
Begin
MATCH_LEVEL =1;
if A is null then
do some logic;
end if;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line ('Error...');
END;
--- and son on for other blocks
end;
Just surround your SELECT INTO with begin-end;
begin
-- your faulty statement here
Exception
When NO_DATA_FOUND Then
-- Do what you want or nothing
WHEN TOO_MANY_ROWS THEN
-- what if you get more then one row? and need specific handler for this
When OTHERS Then
-- do something here or nothing (optional - may happen if you have more than your SELECT INTO between 'begin' and 'Exception')
end;
This is like try block of PL/Sql
With this technique you can log the reason your statement failed.
For a SELECT ... INTO ... statement, the PL/SQL engine assume there will be one, and only one row returned by your query. If there is no row, or more than one, an exception is raised.
FWIW, you can handle such cases without resorting on exception handling by using aggregate functions. That way, there will always be only one row in the result set.
Assuming A can't be NULL in your rows:
SELECT MAX(A) into PARAM A FROM SAMPLE WHERE SOME CONDITION;
-- A would be NULL if there was *no* row. Otherwise, it is *the* value for *the* row
MATCH_LEVEL =1;
if A is null then
do some logic;
end if
If the NULL value is a possible case, just add an extra COUNT(*) column:
SELECT MAX(A), COUNT(*) into A, HAS_FOUND_ROW FROM SAMPLE WHERE SOME CONDITION;
if HAS_FOUND_ROW > 0 then
...
end if;
Oracle will not allow you to open an implicit cursor (i.e. a select statement in the body of a code block) that returns no rows. You have two options here (3 really, counting #Sylvain's answer, but that is an unusual approach): use an explicit cursor or handle the error.
Explicit Cursor
An explicit cursor is one found in the DECLARE section it must be opened and fetched manually (or in a FOR loop). This has the added advantage that, if you parameterize the query properly, you can write it once and use it multiple times.
DECLARE
a sample.a%type;
MATCH_LEVEL number;
cursor cur_params (some_column_value number) is
SELECT A FROM SAMPLE WHERE some_column = some_column_value;
BEGIN
MATCH_LEVEL := 1;
open cur_params (match_level);
fetch cur_params into a;
close cur_params;
if A is null then
null; --some logic goes here
end if;
MATCH_LEVEL := 2;
open cur_params (match_level);
fetch cur_params into a;
close cur_params;
if A is null then
null; --some logic goes here
end if;
end;
Handle the error
If you choose to handle the error, you'll need to create a BEGIN...END block around the code that is going to throw the error. When disregarding an error, it's crucial that you ensure that you are only disregarding the specific error you want avoid, when generated from the specific statement you expect it from. If you simply add the EXCEPTION section to your existing BEGIN...END block, for instance, you couldn't know which statement generated it, or even if it was really the error you expected.
DECLARE
a sample.a%type;
MATCH_LEVEL number;
BEGIN
MATCH_LEVEL := 1;
BEGIN
SELECT A into A FROM SAMPLE WHERE some_column = MATCH_LEVEL;
EXCEPTION
WHEN NO_DATA_FOUND THEN
null; --Do nothing
END;
if A is null then
null; --some logic goes here
end if;
MATCH_LEVEL := 2;
BEGIN
SELECT A into A FROM SAMPLE WHERE some_column = MATCH_LEVEL;
EXCEPTION
WHEN NO_DATA_FOUND THEN
null; --Do nothing
END;
if A is null then
null; --some logic goes here
end if;
end;
While I'd discourage it, you can catch any other errors in the same exception blocks. However, by definition, those errors would be unexpected, so it would be a poor practice to discard them (you'll never know they even happened!). Generally speaking, if you use a WHEN OTHERS clause in your exception handling, that clause should always conclude with RAISE;, so that the error gets passed up to the next level and is not lost.
I would like to make a try in Pascal. I started is but I the insert method does not work correctly. Here is a part of the program:
type PVrchol = ^Vrchol;
Vrchol = record
endOfTheWord:boolean;
deti:array['a'..'z'] of PVrchol;
end;
var trie:PVrchol;
FUNCTION getChildnode(current:PVrchol;k:char):PVrchol;
Begin
if current^.deti[k]<>nil then
getChildnode:=current^.deti[k]
else
getChildNode:=nil;
End;
PROCEDURE insertWord(word:string;var trie:PVrchol);
var i:integer;
current, childNode:PVrchol;
Begin
current:=trie;
childNode:=current;
for i:=1 to Length(word) do begin
childNode:=getChildnode(current,word[i]);
if childNode=nil then begin
new(childNode);
current^.deti[word[i]]:=childNode;
end;
current:=childNode;
end;
current^.endOfTheWord:=true;
End;
BEGIN
new(trie);
//there are some methods reading the words from input, and calling the insertWord procedure.
END.
The insertWord procedure always gets a word, so the parameter wont be "".
The problem might be that records are not automatically zeroed as classes are? Try adding
fillchar(childnode,sizeof(childnode),#0);
after the new(childnode)
I am new to pl/sql. can any one tell me how to call pl/sql function inside a trigger.
I tired it but it gives an error when i try to run it.
DROP TRIGGER INTF_CONTROLLER_TREXE;
CREATE OR REPLACE TRIGGER INTF_CONTROLLER_TREXE
before insert ON INTF_CONTROLLER for each row
begin
BACKOFFICE_UPDATE();
end;
CREATE OR REPLACE FUNCTION BACKOFFICE_UPDATE
RETURN NUMBER IS
tmpVar NUMBER;
BEGIN
tmpVar := 0;
DBMS_OUTPUT.put_line ('HELLO');
RETURN tmpVar;
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
WHEN OTHERS THEN
-- Consider logging the error and then re-raise
RAISE;
END BACKOFFICE_UPDATE;
I tried to run it using TOAD. it gives the following error
PLS-00221: 'BACKOFFICE_UPDATE' is not a procedure or is undefined
You need to store the result of your function call in a local variable
For example:
CREATE OR REPLACE TRIGGER INTF_CONTROLLER_TREXE
before insert ON INTF_CONTROLLER for each row
declare
dummy NUMBER;
begin
dummy := BACKOFFICE_UPDATE();
end;