How to do a character to number conversion? - oracle

I'm trying to do a character to number conversion but the system doesn't let me and threw me the ORA-06502 ERROR .
This is the code that I'm trying to compile :
VPARAMETROS_MENSAJE VARCHAR2(2000);
ERROR_NUMBER NUMBER;
BEGIN
ERROR_NUMBER := 0;
ERROR_NUMBER := SQLCODE;
VPARAMETROS_MENSAJE :='{' +'"ERROR_NUMBER":"' + CAST('ERROR_NUMBER' AS
VARCHAR2) + '",' +'}' ;
THANKS YOU ALL!
I found the mistake traducing the code that I was trying to compile from Microsoft SQL Server to Oracle and it's finally works.
The error was in this line.
VPARAMETROS_MENSAJE :='{' ||'"ERROR_NUMBER":"' || CAST('ERROR_NUMBER' AS VARCHAR2) || '",' ||'}' ;

You are using Oracle but this is SQL Server Syntax. You need to use the below code -
VPARAMETROS_MENSAJE VARCHAR2(2000);
ERROR_NUMBER NUMBER;
BEGIN
ERROR_NUMBER := 0;
ERROR_NUMBER := SQLCODE;
VPARAMETROS_MENSAJE := '{"ERROR_NUMBER":"' || ERROR_NUMBER || '",}';

Related

small string buffer for a Oracle function

I wrote a this function to return varchar2 from some tables.
create or replace function info_raum(in_name varchar2)
return varchar2
is
v_fi_name fitnesscenter.name%type;
v_num number;
v_output varchar2(2000) :='';
begin
for rec in (select * from raum where name = in_name)
loop
select name
into v_fi_name
from fitnesscenter
where fitnesscenternr = rec.fitnesscenternr;
select count(*)
into v_num
from ist_im
where raumnr = rec.raumnr;
v_output := v_output || 'Fitnesscenter: ' || v_fi_name || ' - GeräteAnz: ' || v_num || ' ---';
end loop;
return v_output;
end;
Wenn I execute the code I get this error:
Connecting to the database developer1.
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 7
Process exited.
Disconnecting from the database developer1.
I think this is because I need a bigger datatype for v_output. But I can not fix it.
You just need to use the max size of PL/SQL VARCHAR2 as it is may be exceeding the size of 2000.
use the following:
V_OUTPUT VARCHAR2(32767) := ''; -- also assignment to null is not needed here

Oracle stored procedure runtime error with pls 00103

(Update 2019/07/23) New way to call procedure
SET SERVEROUTPUT ON
declare
variable res sys_refcursor;
begin
my_schema.SP_READ_MEMBER('11223344', '1970/01/01', res);
EXCEPTION
WHEN OTHERS
THEN DBMS_OUTPUT.put_line ('ERROR ' || SQLERRM);
end;
/
Result
Error at line 2
ORA-06550: line 2, column 16:
PLS-00103: Encountered the symbol "SYS_REFCURSOR" when expecting one of the following:
:= . ( # % ; not null range default character
The symbol ":=" was substituted for "SYS_REFCURSOR" to continue.
(Original post)
I'm not really good on Oracle's Stored Procedure, so this error confused me much time. Had read 10 more threads on this site about PLS-00103. but none of them seems helped with my error.
Here's my Stored Procedure
create or replace procedure my_schema.SP_READ_MEMBER(keywordP in varchar2, birthdayP in varchar2, resultP out sys_refcursor)
is
v_prg_name varchar2(20) := 'SP_READ_MEMBER';
sys_sql varchar2(1000);
begin
Insertlog(SYSDATE, v_prg_name, '1.0 Start');
sys_sql := sys_sql || 'select a.no, a.name, a.id_no, to_char(a.birthday, ''yyyy/MM/dd'') as birthday, ''REGISTERED'' as type, email, mobile from rep a where 1=1 ';
if keywordP is not null then
sys_sql := sys_sql || ' and (a.no=''' || keywordP || ''' or a.name=''' || keywordP || ''' or a.id_no=''' || keywordP || ''') ';
end if;
if birthdayP is not null then
sys_sql := sys_sql || ' and a.birthday=to_date(''' || birthdayP || ''', ''yyyy/MM/dd'') ';
end if;
open resultP for sys_sql;
Insertlog(SYSDATE, v_prg_name, '2.0 Finished w/o error');
exception
when others then
declare
error_time VARCHAR2(30) := RTRIM(TO_CHAR(SYSDATE, 'YYYY/MM/DD, HH24:MI:SS'));
error_code NUMBER := SQLCODE;
error_msg VARCHAR2(300) := SQLERRM;
begin
rollback;
DBMS_OUTPUT.PUT_LINE(error_time || ',' || TO_CHAR(error_code) || ',' || error_msg);
Insertlog(SYSDATE, v_prg_name, error_msg || ', 3.0 ERROR, sql:' || sys_sql);
end;
end;
/
And run it in toad, with following script :
SET SERVEROUTPUT ON
declare
res varchar2(1000);
begin
call my_schema.SP_READ_MEMBER('11223344', '1970/01/01', res);
EXCEPTION
WHEN OTHERS
THEN DBMS_OUTPUT.put_line ('ERROR ' || SQLERRM);
end;
/
This error message really confused me much hours...
Error at line 2
ORA-06550: line 4, column 8:
PLS-00103: Encountered the symbol "my_schema" when expecting one of the following:
:= . ( # % ;
The symbol ":=" was substituted for "my_schema" to continue.
Now I'm stuck here, please gives some suggestions, really need this ...
PS: Got same error message while called from c#
You have ro remove the call; for example:
SQL> begin
2 call testProc;
3 end;
4 /
call testProc;
*
ERROR at line 2:
ORA-06550: line 2, column 10:
PLS-00103: Encountered the symbol "TESTPROC" when expecting one of the
following:
:= . ( # % ;
The symbol ":=" was substituted for "TESTPROC" to continue.
SQL> begin
2 testProc;
3 end;
4 /
PL/SQL procedure successfully completed.
Also, notice that your procedure has a sys_refcursor out parameter, but you call it by passing a varchar2.
As an aside, using a varchar2 to handle dates is not a good idea; the date type would be better.
As mentioned in the previous answer, There are several mistakes in calling the procedure itself.
Your code to call the procedure should look like the following:
SET SERVEROUTPUT ON
declare
res SYS_REFCURSOR; -- Changed data type of this variable
begin
my_schema.SP_READ_MEMBER('11223344', '1970/01/01', res); -- removed 'call'
EXCEPTION
WHEN OTHERS
THEN DBMS_OUTPUT.put_line ('ERROR ' || SQLERRM);
end;
/
Cheers!!

DBMS_SQL.TO_REFCURSOR equivalent in Oracle 10g

I have the following code :
procedure Replace(sUser in Varchar2,sNomTable in varchar2,sColonne in varchar2,sID in Varchar2,nbCharAlterer IN NUMBER) is
l_cursor NUMBER;
l_return NUMBER;
l_ref_cursor SYS_REFCURSOR;
TYPE t_tab IS TABLE OF VARCHAR2(4000);
l_tab t_tab;
l_tab_Id t_tab;
sChaine VARCHAR2(4000 CHAR);
sqlReq CONSTANT VARCHAR2(1000):= 'select ' || sId || ',' || sColonne || ' from ' || sUser || '.' || sNomTable ;
begin
--
l_cursor := DBMS_SQL.open_cursor;
DBMS_SQL.parse(l_cursor, sqlReq, DBMS_SQL.NATIVE);
l_return := DBMS_SQL.EXECUTE(l_cursor);
-- Connvert from DBMS_SQL to a REF CURSOR.
l_ref_cursor := DBMS_SQL.to_refcursor(l_cursor);
Here I am getting the following error :
pls 00302 component 'TO_REFCURSOR' must be declared
since my oracle version is 10g.
Any idea of how to do the equivalent in Oracle 10g?
Here's how you could use native dynamic sql:
PROCEDURE p_replace(suser IN VARCHAR2,
snomtable IN VARCHAR2,
scolonne IN VARCHAR2,
sid IN VARCHAR2,
nbcharalterer IN NUMBER) IS
v_validate_sid_col_name VARCHAR2(32);
v_validate_scolonne_col_name VARCHAR2(32);
v_validate_suser VARCHAR2(32);
v_validate_snomtable VARCHAR2(32);
sqlreq VARCHAR2(2000);
refcur sys_refcur;
BEGIN
-- Check the input values are valid identifiers (to avoid sql injection)
-- N.B. this does not check they are valid object names!
v_validate_sid_col_name := dbms_assert.qualified_sql_name(sid);
v_validate_scolonne_col_name := dbms_assert.qualified_sql_name(scolonne);
v_validate_suser := dbms_assert.qualified_sql_name(suser);
v_validate_snomtable := dbms_assert.qualified_sql_name(scolonne);
sqlReq := 'select ' || v_validate_sid_col_name || ',' ||
v_validate_scolonne_col_name ||
' from ' || v_validate_suser || '.' || v_validate_snomtable;
-- or maybe you want to use execute immediate to bulk collect into arrays?
OPEN refcur FOR sqlreq;
...
END p_replace;
Note that I've changed the name of the procedure since "replace" is the name of a pre-existing built-in function, and therefore not a very good name to use.
You don't mention what it is you're going to do with the results of your query, so I wasn't sure if opening a ref cursor is what you actually need, or whether bulk collecting via execute immediate would work better for you.

How to deal with the single quote in pl/sql code

I met below error when I execute the following code.
Error report:
ORA-01722: invalid number
ORA-06512: at line 12
01722. 00000 - "invalid number"
Can you please help me to find out the root reason.
declare
v_str varchar2(100):='XY';
v_cnt number := 1;
v_text varchar2(100);
v_sysdate date := sysdate;
begin
v_text := 'select to_char(' || '''' || v_sysdate || '''' || ',''yyyy/mm/dd'') from dual';
dbms_output.put_line(v_text);
execute immediate v_text into v_str;
dbms_output.put_line(v_str);
end;
The problem is that you are trying to convert a char to a char as if the first one were a date. Notice that you're executing the following query:
select to_char('2014-03-14','yyyy/mm/dd') from dual
It doesn't make any sense. The "date" (2014-03-14) is actually a string and you can't treat that like if it were a date.
If you just want to cast v_sysdate to a varchar2, you could just do:
v_str := to_char(v_sysdate,'yyyy/mm/dd');
Or maybe you just were studying how dynamic SQL works...
Please, everyone test it before answer... problem with execute immediate..
------ so i think this is what you wanted..
declare
v_str varchar2(100):='XY';
v_cnt number := 1;
v_text varchar2(100);
v_sysdate date := sysdate; --
begin
v_text := 'select to_char(:x,''yyyy.mm.dd'') from dual';--:x dynamically built sql statement using IN OUT v_variable1, IN v_variable2;
dbms_output.put_line(v_text);
execute immediate v_text into v_str using in v_sysdate;
dbms_output.put_line(v_str);
end;
you can't just put variable into execute string and expect something ;) you need to define him to use in that place... v_sysdate goes into defined :x place...

Can you help me write a procedure in Oracle to spool data from a table to a CSV file?

I am writing a procedure to create a CSV file with the data in an Oracle table. I used "spool filename;" but an error is coming. Can I use spool in PL/SQL?
I think that there are better ways to implement this on Oracle 10g/11g, but this should work fine on Oracle 9i or higher:
CREATE OR REPLACE PROCEDURE prc_file_mult_column_generate(
p_file_dir VARCHAR2, -- mandatory (Oracle directory name)
p_file_name VARCHAR2, -- mandatory
p_sql_query VARCHAR2, -- Multiple column SQL SELECT statement that needs to be executed and processed
p_delimiter CHAR -- column delimiter
)
AS
l_cursor_handle INTEGER;
l_dummy NUMBER;
l_col_cnt INTEGER;
l_rec_tab DBMS_SQL.DESC_TAB;
l_current_col NUMBER(16);
l_current_line VARCHAR2(2047);
l_column_value VARCHAR2(300);
l_file_handle UTL_FILE.FILE_TYPE;
l_print_text VARCHAR2(100);
l_record_count NUMBER(16) := 0;
BEGIN
/* Open file for append*/
l_file_handle := UTL_FILE.FOPEN(p_file_dir, p_file_name, 'a', 2047); --Append Mode, 2047 chars per line max, possibly increasable
l_cursor_handle := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(l_cursor_handle, p_sql_query, DBMS_SQL.native);
l_dummy := DBMS_SQL.EXECUTE(l_cursor_handle);
/* Output column names and define them for latter retrieval of data */
DBMS_SQL.DESCRIBE_COLUMNS(l_cursor_handle, l_col_cnt, l_rec_tab); -- get column names
/* Append to file column headers */
l_current_col := l_rec_tab.FIRST;
IF (l_current_col IS NOT NULL) THEN
LOOP
DBMS_SQL.DEFINE_COLUMN(l_cursor_handle, l_current_col, l_column_value, 300);
l_print_text := l_rec_tab(l_current_col).col_name || p_delimiter;
UTL_FILE.PUT (l_file_handle, l_print_text);
l_current_col := l_rec_tab.NEXT(l_current_col);
EXIT WHEN (l_current_col IS NULL);
END LOOP;
END IF;
UTL_FILE.PUT_LINE (l_file_handle,' ');
/* Append data for each row */
LOOP
EXIT WHEN DBMS_SQL.FETCH_ROWS(l_cursor_handle) = 0; -- no more rows to be fetched
l_current_line := '';
/* Append data for each column */
FOR l_current_col IN 1..l_col_cnt LOOP
DBMS_SQL.COLUMN_VALUE (l_cursor_handle, l_current_col, l_column_value);
l_print_text := l_column_value || p_delimiter;
l_current_line := l_current_line || l_column_value || p_delimiter;
END LOOP;
l_record_count := l_record_count + 1;
UTL_FILE.PUT_LINE (l_file_handle, l_current_line);
END LOOP;
UTL_FILE.FCLOSE (l_file_handle);
DBMS_SQL.CLOSE_CURSOR(l_cursor_handle);
EXCEPTION
WHEN OTHERS THEN
-- Release resources
IF DBMS_SQL.IS_OPEN(l_cursor_handle) THEN
DBMS_SQL.CLOSE_CURSOR(l_cursor_handle);
END IF;
IF UTL_FILE.IS_OPEN (l_file_handle) THEN
UTL_FILE.FCLOSE (l_file_handle);
END IF;
--RAISE ;
DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.format_error_stack);
END;
/
spool is a sqlplus command. it cannot be used in pl/sql.
it seems that you have been trying a variety of ways to get oracle to do your formatting and file saving. why not have your program that is calling the proc do this work for you?
If you only need the data in a cvs file you can do this:
create a sql file with the query like this:
set feedback off verify off heading off pagesize 0
select field1 || ',' || field2 ... from table;
quit;
/
then call sqlplus from a terminal like this:
sqlplus -S user/password #file.sql> cvsfile.cvs
No, SPOOL is a SQL Plus command so you would have to do this in SQL Plus:
spool myfile.txt
exec myproc
spool off
You would probably also need to set some values before starting the process e.g.
set pagesize 0 linesize 1000 trimspool on
... to get the correct formatting.
Here are a couple of links you might find helpful:
A PL/SQL Tutorial and SQL*Plus User Guide (11g)
Creating an ascii file: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:459020243348 and http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:68212348056 and http://www.oracle-developer.net/display.php?id=425 .

Resources