I wrote a pipelined function to query data from a remote database. I keep getting
ORA-06502: PL/SQL: numeric or value error: character string buffer too
small.
I think I do understand when this error would occur, for example when a table column is defined as VARCHAR2(10) and you try to insert something bigger than 10 byte. But in this case, I really don't see whats wrong.
Perhaps first I show the parameters of the local and the remote database. I think it might be important, that on both DBs NLS_LENGTH_SEMANTICS is set to BYTE.
Local DB (where the pipelined function is stored):
params local db
Remote DB (from where data is queried):
params remote db
Now the code in local db:
create or replace function f_get_pl_data return tb_pl_palette pipelined is
begin
for i in (select p.*, 123 LAGER from palette#myremotedb p)
loop
pipe row(tt_pl_palette(i.pid,i.bereich,i.regal,i.fach,i.ebene,i.vol_klasse,i.lhm_typ,i.zustand,i.neu_datum,
i.neu_zeit,i.neu_usr,i.aender_datum,i.aender_zeit,i.aender_usr,i.verl_datum,i.tournr,
i.fil_nr,i.retournr,i.fz_nr,i.fahrer_nr,i.eroeff_auswahl,i.tpa_knz,i.lfsaender_knz,
i.verladen_am,i.verladen_um,i.verladen_von,i.verladen_von2,i.leer_gew,i.soll_gew,
i.ist_gew,i.lager));
end loop;
return;
end;
CREATE OR REPLACE TYPE "TT_PL_PALETTE" AS OBJECT (
pid VARCHAR2(14),
bereich VARCHAR2(2),
regal VARCHAR2(2),
fach VARCHAR2(3),
ebene VARCHAR2(2),
vol_klasse INTEGER,
lhm_typ INTEGER,
zustand INTEGER,
neu_datum DATE,
neu_zeit VARCHAR2(11),
neu_usr VARCHAR2(4),
aender_datum DATE,
aender_zeit VARCHAR2(11),
aender_usr VARCHAR2(4),
verl_datum DATE,
tournr VARCHAR2(6),
fil_nr VARCHAR2(4),
retournr VARCHAR2(10),
fz_nr INTEGER,
fahrer_nr INTEGER,
eroeff_auswahl INTEGER,
tpa_knz VARCHAR2(1),
lfsaender_knz VARCHAR2(1),
verladen_am DATE,
verladen_um VARCHAR2(11),
verladen_von VARCHAR2(4),
verladen_von2 VARCHAR2(4),
leer_gew NUMBER(7,3),
soll_gew NUMBER(7,3),
ist_gew NUMBER(7,3),
lager NUMBER
)
CREATE OR REPLACE TYPE "TB_PL_PALETTE" as TABLE OF TT_PL_PALETTE
And this is the table specifications on remote db:
create table PALETTE
(
pid VARCHAR2(14) not null,
bereich VARCHAR2(2) not null,
regal VARCHAR2(2) not null,
fach VARCHAR2(3) not null,
ebene VARCHAR2(2) not null,
vol_klasse INTEGER,
lhm_typ INTEGER,
zustand INTEGER,
neu_datum DATE default trunc(sysdate),
neu_zeit VARCHAR2(11) default to_char(sysdate, 'HH24:MI:SS'),
neu_usr VARCHAR2(4),
aender_datum DATE,
aender_zeit VARCHAR2(11),
aender_usr VARCHAR2(4),
verl_datum DATE,
tournr VARCHAR2(6),
fil_nr VARCHAR2(4),
retournr VARCHAR2(10),
fz_nr INTEGER,
fahrer_nr INTEGER,
eroeff_auswahl INTEGER,
tpa_knz VARCHAR2(1) default '0',
lfsaender_knz VARCHAR2(1) default 'N',
verladen_am DATE,
verladen_um VARCHAR2(11),
verladen_von VARCHAR2(4),
verladen_von2 VARCHAR2(4),
leer_gew NUMBER(7,3),
soll_gew NUMBER(7,3),
ist_gew NUMBER(7,3)
)
So you can see, when I created the type in local db I choosed the exact sizes of the columns in remote db.
But when I execute/query the pipelined function, I get this error (sorry it's german, but I wrote english in title):
error message
How can this happen? Do you have any idea what's wrong?
Appreciate any help, thanks!
EDIT 2021-03-02:
#ShaunPeterson Thanks for reply, NLS_CHARACTERSET is set to AL32UTF8 on both DBs, local and remote.
I just found out, the problem seems to be caused by 2 different IDEs that are used in our company.
I am using PL/SQL Developer from allround automations. When I posted the table specifications on remote DB (table "PALETTE"), I connected to remote DB using that IDE, and it showed the column types/sizes as you can see in my original post. I repeat the first 6 columns:
create table PALETTE
(
pid VARCHAR2(14) not null,
bereich VARCHAR2(2) not null,
regal VARCHAR2(2) not null,
fach VARCHAR2(3) not null,
ebene VARCHAR2(2) not null,
vol_klasse INTEGER,
But when Oracle SQL Developer is used, then it looks like this:
CREATE TABLE "PSTEDI"."PALETTE"
( "PID" VARCHAR2(14 CHAR) NOT NULL ENABLE,
"BEREICH" VARCHAR2(2 CHAR) NOT NULL ENABLE,
"REGAL" VARCHAR2(2 CHAR) NOT NULL ENABLE,
"FACH" VARCHAR2(3 CHAR) NOT NULL ENABLE,
"EBENE" VARCHAR2(2 CHAR) NOT NULL ENABLE,
"VOL_KLASSE" NUMBER(*,0),
So it seems PL/SQL Developer just shows wrong specifications. I have no idea why it is like that, and I would like to know, but that's another question.
I solved my problem using the column types and sizes Oracle SQL Developer shows.
Thank you.
#Dietz, what you said was fine for me.
I'm having the same problem as you, I am wondering if it's a bug. Like you:
I created types in ADT exactly as in their respective table columns.
I set my NLS_LENGTH_SEMANTICS.
However:
I set a default in SQL Developer.
I am not accessing a remote DB.
I don't believe it's related to either of these.
FYI, I'm going to try one more thing and if it doesn't work, I'll open a ticket with Oracle Support. I will update here with what I find or workaround from Oracle Support.
Related
create table sl_rep_winners(
slnum INT (12),
zone INT,
city nvarchar(200),
county nvarchar(200),
town nvarchar(200)
);
I get a "missing right parenthesis" error. What is the reason of error?
If you are using Oracle:
create table sl_rep_winners
(
slnum number(12),
zone number(10),
city varchar2(200),
county varchar2(200),
town varchar2(200)
);
INTEGER is supported as an ANSI datatype but gets converted to the equivalent Oracle datatype which is number().
FYI:
nvarchar & varchar2
I have a table with several columns, like this:
CREATE TABLE CRM.INFO_ADICIONAL
(
ID_INFO_ADICIONAL NUMBER(10) NOT NULL,
NOMBRE VARCHAR2(100 BYTE) NOT NULL,
OBLIGATORIO NUMBER(1) NOT NULL,
TIPO_DATO VARCHAR2(2 BYTE) NOT NULL,
ACTIVO NUMBER(1) NOT NULL,
ID_TIPO_REQUERIMIENTO NUMBER(10) NOT NULL,
ID_USUARIO_AUDIT NUMBER(10) NOT NULL,
ORDEN NUMBER(3) DEFAULT 1,
RECHAZO_POR_NO NUMBER(1),
ID_TIPO_ARCHIVO_ADJUNTO NUMBER(10),
SOLICITAR_EN VARCHAR2(30 BYTE),
ID_CONSULTA NUMBER(10),
COMBO_ID VARCHAR2(40 BYTE),
APLICAR_COMO_VENC NUMBER(1),
MODIFICABLE NUMBER(1) DEFAULT 0,
ID_AREA_GESTION NUMBER(10),
ID_TAREA NUMBER(10)
)
The "COMBO_ID" column is the target. It is defined as VARCHAR, but when I'm trying to insert a row, TOAD displays
"ORA-06502: PL/SQL: error : error de conversión de carácter a número
numérico o de valor"
Or a 'numeric conversion error', in english.
This table have some pre-existing data, and I even found some rows including values at COMBO_ID column, all of them being VARCHAR, i.e.:
NACION (Nation), SEXO (Sex), etc
I tried a few simple SELECT statements
SELECT
ID_INFO_ADICIONAL,
NOMBRE,
OBLIGATORIO,
TIPO_DATO,
ACTIVO,
ID_TIPO_REQUERIMIENTO,
ID_USUARIO_AUDIT,
ORDEN,
RECHAZO_POR_NO,
ID_TIPO_ARCHIVO_ADJUNTO,
SOLICITAR_EN,
COMBO_ID,
APLICAR_COMO_VENC,
ID_CONSULTA,
MODIFICABLE,
ID_AREA_GESTION,
ID_TAREA
INTO
pRegistro
FROM
crm.info_adicional
where pRegistro is declared as
pRegistro INFO_ADICIONAL%ROWTYPE;
Again, I'm still getting this 'numeric conversion error'.
But, wait, if I hardcode the SELECT value in COMBO_ID column with a NUMBER:
SELECT
--other columns
123456 COMBO_ID,
--other columns
INTO
pRegistro
FROM
crm.info_adicional
It works, what the heck, it's defined as VARCHAR.
If I do the same but harcoding a string, it fails to execute again
Already tried in my DEV environment, and it's working fine.
I'm not a pro in Oracle, but I feel pretty lost.
Could it be that tables get "confused"?
Any clues?
That error can also be raised if you try to push a character string that is longer than your VARCHAR2's capacity (40 in your case).
Try to check if all the data you are trying to insert is correct :
SELECT
COMBO_ID
FROM
crm.info_adicional
ORDER BY length(COMBO_ID) desc;
That would also explain why it works fine on your DEV environment which, I suppose, has different data.
Okay, I already found the answer.
Quoting Oracle Documentation:
The %ROWTYPE attribute provides a record type that represents a row in a table or view. Columns in a row and corresponding fields in a record have the same names and datatypes.
So, basically, the SELECT statement needed to be in the same order as the table columns definition.
In my case, I had a few columns (including COMBO_ID) in a different order.
Tried, re-ordering, and works like a charm.
Thank you all for the support.
Hi I have created a table Continent using below query
CREATE TABLE CONTINENTS
(
CONTNTCOD NUMBER(2) NOT NULL,
LOOKUPCOD VARCHAR2(20),
CONTNAM VARCHAR2(50),
CONTNAM_LCLLANG VARCHAR2(50),
);
The fourth column i.e. CONTNAM_LCLLANG is used to store data in different language.
When i tried to insert
अभिषेक it inserted something ¿¿¿¿¿¿
Select Unicode like utf8 or utf8_general_ci( in mysql ) because it support a many characters.
so, what you can do is change varchar to nvarchar
CREATE TABLE CONTINENTS
(
CONTNTCOD NUMBER(2) NOT NULL,
LOOKUPCOD VARCHAR2(20),
CONTNAM VARCHAR2(50),
CONTNAM_LCLLANG NVARCHAR2(50),
);
I am new to oracle,
I have created two tables using following queries,
CREATE TABLE employee
(
emp_name VARCHAR(20) NOT NULL,
street VARCHAR(50) NOT NULL,
city VARCHAR(20) NOT NULL,
PRIMARY KEY(emp_name)
)
and
CREATE TABLE company
(
comp_name VARCHAR(20) NOT NULL,
city VARCHAR(20) NOT NULL,
PRIMARY KEY(comp_name)
)
Now I am trying to create another table using some foreign keys,
CREATE TABLE works
(
emp_name varchar(20) NOT NULL,
comp_name varchar(20) NOT NULL,
salary int(10) NOT NULL,
FOREIGN KEY(emp_name) REFERENCES employee(emp_name),
FOREIGN KEY(comp_name) REFERENCES company(comp_name)
)
Getting ERROR : ORA-00907: missing right parenthesis
I have also tried with
CREATE TABLE works
(
emp_name varchar(20) NOT NULL,
comp_name varchar(20) NOT NULL,
salary int(10) NOT NULL,
constraint wemployee FOREIGN KEY(emp_name) REFERENCES employee(emp_name),
constraint wcompany FOREIGN KEY(comp_name) REFERENCES company(comp_name)
)
But getting same error.
Can any one tell me that where I am doing mistake?
I'm no expert in oracle, but are you allowed to specify the (10) in salary int(10) NOT NULL?
1: you should have a table called "test" with two columns, id and testdata. (This is just a dumb quick example, so I won't bother to specify any constraints on id.)
create table test (id number, testdata varchar2(255));
2: Next we'll create a sequence to use for the id numbers in our test table.
create sequence test_seq
start with 1
increment by 1
nomaxvalue;
You could change "start with 1" to any number you want to begin with (e.g. if you already have 213 entries in a table and you want to begin using this for your 214th entry, replace with "start with 214"). The "increment by 1" clause is the default, so you could omit it. You could also replace it with "increment by n" if you want it to skip n-1 numbers between id numbers. The "nomaxvalue" tells it to keep incrementing forever as opposed to resetting at some point.i (I'm sure Oracle has some limitation on how big it can get, but I don't know what that limit is).
3: Now we're ready to create the trigger that will automatically insert the next number from the sequence into the id column.
create trigger test_trigger
before insert on test
for each row beginselect test_seq.nextval into :new.id from dual;
end;
/
There are two different ways to create a table with constraints:
1)
create table department(
deptno number(5) primary key,
deptname varchar2(30),
empno number(5) references emp(empno));
2)
create table department(
deptno number(5),
deptname varchar2(30),
empno number(5),
constraint pkey_deptno primary key(deptno),
constraint fkey_empno foreign key(empno) references Emp(empno));
When creating the index inline with the rest of the table creation statement try dropping the FOREIGN KEY part:
CREATE TABLE works
(
emp_name varchar(20) NOT NULL,
comp_name varchar(20) NOT NULL,
salary int(10) NOT NULL,
emp_name REFERENCES employee(emp_name),
comp_name REFERENCES company(comp_name)
)
See this question for more details:
ORA-00907: missing right parenthesis
So this is from a uni coursework and is my first time working with Oracle (and using triggers). We are supposed to be creating a database for an airlines.
Part of the database is
CREATE TABLE FLIGHT_BOOKING (
BOOKING_ID NUMBER(11) PRIMARY KEY,
BOOKING_TIME DATE NOT NULL,
EMPLOYEE_ID NUMBER(11) NOT NULL,
FLIGHT_ID NUMBER(11) NOT NULL,
TOTAL_COST NUMBER(4,2) NOT NULL
);
CREATE TABLE FLIGHT (
FLIGHT_ID NUMBER(11) PRIMARY KEY,
PLANE_ID NUMBER(11) NOT NULL,
START_ID NUMBER(11) NOT NULL,
DESTINATION_ID NUMBER(11) NOT NULL,
TRANSIT_ID NUMBER(11),
DEPARTURE_TIME DATE NOT NULL,
ARRIVAL_TIME DATE NOT NULL,
NUM_BOOKED NUMBER (4) NOT NULL
);
CREATE TABLE PASSENGER (
PASSENGER_ID NUMBER(11) PRIMARY KEY,
FIRST_NAME VARCHAR2(20) NOT NULL,
MIDDLE_NAME VARCHAR2(20) NULL,
LAST_NAME VARCHAR2(20) NOT NULL,
TELEPHONE NUMBER(11) NOT NULL,
BOOKING_ID NUMBER(11) NOT NULL
);
So what I want to do is create a trigger such that every time a new passenger is added to the PASSENGER table, the trigger finds the corresponding FLIGHT_ID from the FLIGHT_BOOKING table and increments NUM_BOOKED for the corresponding flight in the FLIGHT table.
I have tried going through the oracle documentation, but i could not find anything that describes a situation where two or more tables are concerned.
Any help would be really appreciated!
you can do it like this:
CREATE OR REPLACE TRIGGER update_flight_booking_info
AFTER INSERT ON PASSENGER
FOR EACH ROW
DECLARE
v_flight_id number;
v_booking_id number;
BEGIN
v_booking_id := :new.booking_id ;
select flight_id into v_flight_id
from flight_booking
where booking_id = v_booking_id;
update flight
set NUM_BOOKED = NUM_BOOKED + 1
where flight_id = v_flight_id;
END;
HTH.
I'd rather not store that number, and calculate it as needed, but okay, it is just course material. :)
When you create a trigger, inside it you can put all kinds of code, including update statements.
So you can write a trigger like this:
create or replace trigger TIDB_BOOKING
before insert or delete
for each row
declare
V_Increment int;
begin
-- Inc or dec, depending on insert or update.
-- Hasn't a booking got a number of seats?
-- Also, can bookings be updated/moved to other flights?
-- These problems aren't yet taken into account in this code.
V_Increment := 1;
if deleting then
V_Increment := -1;
update FLIGHT f
set f.NUM_BOOKED = f.NUM_BOOKED + V_Increment
where f.FLIGHT_ID = nvl(:new.FLIGHT_ID, :old.FLIGHT_ID);
end;