Hello I'm converting a string {"view": 1, "date": "2020-10-13", "cuit": 30000000007, "ptoVta": 10, "tipoCmp": 1, "nroCmp": 94, " amount ": 12100," currency ":" DOL "," ctz ": 65," tipoDocRec ": 80," nroDocRec ": 20000000001," tipoCodAut ":" E "," codAut ": 70417054367476} to base64 with the following function
CREATE OR REPLACE function CRISOL.returnsbase64 (ptext varchar2) RETURN VARCHAR2 IS
vResult varchar2 (1000);
BEGIN
--Create encoded value
vResult: = '';
vResult: = utl_encode.text_encode (ptext, 'WE8ISO8859P1', UTL_ENCODE.BASE64);
- dbms_output.put_line (vResult);
return vResult;
EXCEPTION
WHEN OTHERS
THEN
RAISE_APPLICATION_ERROR (
-20800,
'Problems in the function returnsbase64 when converting:' || ptext || ' Error; '|| SQLERRM,
TRUE);
END;
turns it well
e78idmVyIjoxLCJmZWNoYSI6IjIwMjAtMTAtMTMiLCJjdWl0IjozMDAwMDAwMDAw
NywicHRvVnRhIjoxMCwidGlwb0NtcCI6MSwibnJvQ21wIjo5NCwiaW1wb3J0ZSI6
MTIxMDAsIm1vbmVkYSI6IkRPTCIsImN0eiI6NjUsInRpcG9Eb2NSZWMiOjgwLCJu
cm9Eb2NSZWMiOjIwMDAwMDAwMDAxLCJ0aXBvQ29kQXV0IjoiRSIsImNvZEF1dCI6
NzA0MTcwNTQzNjc0NzZ9
but I need you to not have line breaks
Is there any solution?
The comment by #WernfriedDomscheit is right, the line breaks are ignored; but if you are dealing with an application that wants it as one nice long string, just do something like this, using the regexp_replace function to change carriage returns and line feeds to null:
regexp_replace
(
utl_encode.text_encode (ptext, 'WE8ISO8859P1', UTL_ENCODE.BASE64)
, chr(10) || '|' || chr(13)
, null
)
Related
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
I have problems with opening cursor with string variable
here is my oracle database code
FUNCTION f_get_cursor(p_date_to_forecast VARCHAR) RETURN SYS_REFCURSOR AS
v_cursor SYS_REFCURSOR;
v_groupby_stmt VARCHAR(200) := 'GROUP BY '
|| CASE WHEN p_date_to_forecast = 'HOLIDAY' THEN
'DAY, ' ELSE '' END
|| 'TNI, FRMP, LR, HH;';
v_select_stmt VARCHAR2(1000) := 'SELECT WEEKDAY, TNI, FRMP, LR, HH,
AVG(Coalesce(VOLUME, 0)) AS AverageVolume
FROM (SELECT v.TNI, v.FRMP, v.LR, v.DAY,
v.HH, v.VOLUME, CASE WHEN
hd.HOLIDAY_DATE is not null
then ''HOLIDAY''
ELSE trim(to_char(v.DAY, ''Day''))
END AS WEEKDAY
FROM v_nem_rm16 v
LEFT JOIN DBP_ADMIN.DBP_HOLIDAY hd
ON v.DAY = hd.HOLIDAY_DATE
WHERE v.STATEMENT_TYPE !=''FORCAST'')
WHERE WEEKDAY = ''' || p_date_to_forecast
|| '''' || ' ' || v_groupby_stmt;
BEGIN
OPEN v_cursor FOR v_select_stmt;
return v_cursor;
END;
I am just trying to open cursor based on the parameter "p_date_to_forcast", which is just string of the name of the week like "Saturday, Tuesday..and so on" and return the cursor.
When I run the query, I got this error
00911. 00000 - "invalid character"
*Cause: identifiers may not start with any ASCII character other than
letters and numbers. $#_ are also allowed after the first
character. Identifiers enclosed by doublequotes may contain
any character other than a doublequote. Alternative quotes
(q'#...#') cannot use spaces, tabs, or carriage returns as
delimiters. For all other contexts, consult the SQL Language
Reference Manual.
*Action:
What is the problem and How can I fix it???
thanks
Have you tried this
for r_cur in your_cursor_name(Your_parameter) Loop
-- your working --
End loop;
CREATE OR REPLACE PROCEDURE format_phone_number
(p_phone_number IN OUT VARCHAR2)
IS
BEGIN
p_phone_number := '(' || SUBSTR(p_phone_number,1,3) || ')' ||
'-' || SUBSTR(p_phone_number,4,3) ||
'.' || SUBSTR(p_phone_number,7,4);
END format_phone_number;
-------------------------------------------------
DECLARE
v_number VARCHAR2(25) := '8002019201';
BEGIN
format_phone_number(v_number);
DBMS_OUTPUT.PUT_LINE(v_number);
END;
Output is ok (800)-201.9201. Question is why after i cut from the procedure like this for example :
CREATE OR REPLACE PROCEDURE format_phone_number
(p_phone_number IN OUT VARCHAR2)
IS
BEGIN
p_phone_number := '(' || SUBSTR(p_phone_number,1,3) || ')';
END format_phone_number;
After invoking again, it gives me only this (800) and not (800)2019201 "unformated" like. Is this a kind of a regular expression and it just can't parse the whole thing because of the limitation of initalization in the p_phone_number from the procedure?
The code is doing exactly what you told it to do. In the second code block only three characters are being taken from the initial value of p_phone_number. These three characters, and the leading and trailing parentheses, then replace the original contents of p_phone_number when the assignment is made. To get the result you're expecting you'd need to use:
p_phone_number := '(' || SUBSTR(p_phone_number,1,3) || ')' ||
SUBSTR(p_phone_number, 4, 7);
Share and enjoy.
I have a project which creates a procedure and takes Date parameter in the argument. Upon execution of the procedure, it displays the Order Id and Order details in the Order Date column using nested cursor loop. I am also trying to display an error message for the date which is not available in my order tables.
The code to create procedure is as
create or replace procedure a05_order_details_by_date(p_order_date in date)
as
v_msg varchar2(400);
v_order_id ppl_order_headers.order_id%type;
v_order_date ppl_order_headers.order_date%type := p_order_date;
cursor cur_orders is
select order_id, order_date
from ppl_order_headers
where extract(month from order_date) = extract(month from v_order_date) and
extract(year from order_date) = extract(year from v_order_date) ;
cursor cur_order_details is
select ppl_order_details.plant_id, ppl_order_details.quantity, ppl_order_details.price, sum(ppl_order_details.quantity*ppl_order_details.price) as Extcost
from ppl_order_details
join ppl_order_headers on ppl_order_details.order_id = ppl_order_headers.order_id
where ppl_order_headers.order_id = v_order_id
group by ppl_order_details.plant_id, ppl_order_details.quantity, ppl_order_details.price;
begin
<< order_loop >>
for rec_orders in cur_orders
loop
case
when (extract(month from v_order_date)) != (extract(month from rec_orders.order_date))
and
(extract(year from v_order_date))!= (extract(year from rec_orders.order_date)) then
pr.pr('There are no orders for the requested month: ' || to_char(v_order_date, 'Month YYYY'));
else
pr.pr('Order ID' || ' ' || 'Order Date');
v_order_id := rec_orders.order_id;
v_msg := rpad(v_order_id, 7) || ' ' || rec_orders.order_date;
pr.pr(v_msg);
<< order_details >>
for rec_order_details in cur_order_details
loop
pr.pr(' ' || ' Plant ID' || ' ' || 'Quantity' || ' ' || 'Price' || ' ' || 'ExtCost' );
v_msg := ' ' || rec_order_details.plant_id || ' ' || rec_order_details.quantity ||
' ' || rec_order_details.price || ' ' || rec_order_details.Extcost;
pr.pr(v_msg);
end loop;
end case;
end loop;
end;
/
The result is fine when the date is given within the dataset. but when I try to run the procedure with Future date or date which is not in dataset, it is supposed to show an error message. But instead, it just shows "Anonymous Block completed".
You're looping over orders where the order date year/month matches your argument year/month; so your loop only contains matching data. But then inside that loop you say:
case
when (extract(month from v_order_date)) != (extract(month from rec_orders.order_date))
and
(extract(year from v_order_date))!= (extract(year from rec_orders.order_date)) then
Firstly you probably meant that to be 'or' not 'and', otherwise the same month in a different year would still be valid. But much more importantly that case condition can never be true. You're inside a loop which already dictates that the month and year for this record must match your date argument, because of the cursor's where clause.
So this case statement is redundant. If any data is found by the cursor then you will always go into the 'else' clause. If no data is found then you won't come into the cursor loop at all (as Tony Andrews pointed out), so the case isn't even evaluated.
You could generate your message by counting the number of records found as you go around the loop, or by setting a boolean variable; and then checking that state after the loop:
...
-- initial state is that we haven't seen any matching records
v_record_found boolean := false;
begin
<< order_loop >>
for rec_orders in cur_orders
loop
-- we have seen records matching the argument
v_record_found := true;
pr.pr('Order ID' || ' ' || 'Order Date');
v_order_id := rec_orders.order_id;
...
<< order_details >>
for rec_order_details in cur_order_details
loop
pr.pr(...)
...
pr.pr(v_msg);
end loop;
end loop;
-- was the flag changed inside the loop?
if not v_record_found then
pr.pr('There are no orders for the requested month: '
|| to_char(v_order_date, 'Month YYYY'));
end if;
end;
If there are no matching records you don't go into the loop, and the flag is never changed to true. But if there are matching records it is set to true, and the 'no orders' messages isn't shown.
I have a table in which there is a primary key named CODE of Type VARCHAR(3). The problem is that all the available values from 000,001 .... 999 are used in different records. As the field CODE is in varchar format so we can have alphabets along with digits.
Is there any algorithm or function in plsql through which we can uniformly generate unique keys of length 3 which includes alphabets as well. Note that we cannot change the field size as it is referenced in so many other tables.
what about this solution
generate alpha-numeric code based on oracle sequence
please check code
declare
l_val number := 255; -- SQN_TMP_01.nextval;
l_base number := 62; -- 00azAZ
l_base_str varchar2(62) := '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
l_res number;
l_final varchar2(100);
begin
loop
-- init numberic value
l_val := SQN_TMP_01.nextval;
l_final := null;
dbms_output.put_line(l_val);
-- convert value to alphanumeric code
loop
l_res := mod(l_val, l_base);
l_final := substr(l_base_str, l_res + 1, 1) || l_final;
exit when l_val - l_res = 0;
l_val := trunc((l_val - l_res) / l_base);
dbms_output.put_line('res = ' || l_res || ' l_val = ' || l_val || ' final: "' || l_final || '"');
end loop;
dbms_output.put_line('check final: "' || l_final || '"');
-- exclude full numeric result as already used
exit when trim(translate(l_final, '0123456789', ' ')) is not null;
end loop;
dbms_output.put_line('final string: "' || l_final || '"');
end;
You should almost certainly migrate your field to an integer type. If that's impossible then it should be possible to convert to a larger char field as bpgergo suggests.
If you're really, really stuck with a 3 character limit you could use to_char(id, 'xxx') to convert to hex, as in: Oracle: How do I convert hex to decimal in Oracle SQL?
This would give you up to 4096 entries. It should be possible (but more complex) to use base64 (up to 262,144 entries), or go up to base 128 (2,097,152), or just use the whole field as a 3 byte unsigned integer if you don't care about the raw data being printable characters (16,777,216).