I'm trying to do this query using IN, but if the type is CLOB doesn't works.
I need that the parameter p_rut is CLOB and the query I need to use IN, because there it will a select that return more rows to compare.
How can I use parameter CLOB in a IN?
PROCEDURE INSERT_TEST (o_dat out o_cursor, p_rut in CLOB)
AS
BEGIN
OPEN o_dat FOR
select * from cliente
where rut in (p_rut);
END;
The table CLIENTE
CREATE TABLE CLIENTE
(
PRODUCTO VARCHAR(50),
RUT VARCHAR2(50),
DV VARCHAR2(50),
FONO1 VARCHAR2(50),
FONO2 VARCHAR2(50),
FONO3 VARCHAR2(50),
FONO4 VARCHAR2(50),
FONO5 VARCHAR2(50),
FONO6 VARCHAR2(50),
COMUNA VARCHAR2(50),
EDAD NUMBER(8),
SEXO NUMBER(8),
DIASMORA NUMBER(8),
AÑODEUDA NUMBER(8),
PAGOMINIMO NUMBER(8),
)
;
You can use:
DBMS_LOB.INSTR (
lob_loc IN CLOB CHARACTER SET ANY_CS,
pattern IN VARCHAR2 CHARACTER SET lob_loc%CHARSET,
offset IN INTEGER := 1,
nth IN INTEGER := 1)
RETURN INTEGER;
i.e.
PROCEDURE INSERT_TEST (o_dat out o_cursor, p_rut in CLOB)
AS
BEGIN
OPEN o_dat FOR
select * from cliente
where DBMS_LOB.INSTR (p_rut,rut)>0;
END;
using IN it can't use CLOB, so I just did a CAST to varchar2.
select * from cliente
where rut in (CAST (p_rut AS VARCHAR2(100));
Related
I was trying to create two object-relational tables and wanted to create a foreign key in the department table to reference the primary key of the employee table.
It throws "ORA-02330: datatype specification not allowed" when I try to create the DEPARTMENT TABLE when I try to create the department table.
CREATE or Replace TYPE EMP_TYPE AS OBJECT
(
EMP_ID INTEGER,
EMP_FNAME VARCHAR2(20),
EMP_LNAME VARCHAR2(25),
ADDRESS VARCHAR(30),
SALARY NUMBER (10),
JOB_TITLE VARCHAR2 (20));
CREATE TABLE EMPLOYEE OF EMP_TYPE (EMP_ID PRIMARY KEY);
CREATE OR REPLACE TYPE DEPT_TYPE AS OBJECT(
DEPT_ID INTEGER,
EMP_ID INTEGER,
DEPT_NAME VARCHAR(20),
LOCATION VARCHAR(20));
CREATE TABLE DEPARTMENT OF DEPT_TYPE (EMP_ID FOREIGN KEY REFERENCES EMPLOYEE(EMP_ID))
The last line is the one that throws the error
Wrong syntax. Should be
SQL> CREATE OR REPLACE TYPE EMP_TYPE AS OBJECT
2 (
3 EMP_ID INTEGER,
4 EMP_FNAME VARCHAR2 (20),
5 EMP_LNAME VARCHAR2 (25),
6 ADDRESS VARCHAR (30),
7 SALARY NUMBER (10),
8 JOB_TITLE VARCHAR2 (20)
9 );
10 /
Type created.
SQL> CREATE TABLE EMPLOYEE OF EMP_TYPE
2 ( EMP_ID PRIMARY KEY );
Table created.
SQL> CREATE OR REPLACE TYPE DEPT_TYPE AS OBJECT
2 (
3 DEPT_ID INTEGER,
4 EMP_ID INTEGER,
5 DEPT_NAME VARCHAR (20),
6 LOCATION VARCHAR (20)
7 );
8 /
Type created.
SQL> CREATE TABLE DEPARTMENT OF DEPT_TYPE
2 ( EMP_ID REFERENCES EMPLOYEE (EMP_ID) );
Table created.
SQL>
Create table emo(
Emo_id number(10) NOT NULL,
Name varchar2(100) NOT NULL,
Band var char2(2),
Emp_type varchar2(5) DEFAULT "FTE" NOT NULL
);
Should be
CREATE TABLE emo
(
Emo_id NUMBER (10) NOT NULL,
Name VARCHAR2 (100) NOT NULL,
Band VARCHAR2 (2),
Emp_type VARCHAR2 (5) DEFAULT 'FTE' NOT NULL
);
So:
not double but single quotes for column's default value
not var char2 but varchar2
I have a package with a INSERT in a sp, and I want to return the id of that insert. The table have a sequence and a trigger for the identity, but in the sp I don't know how can I return the id of the insert that i'm doing, because in the code java I need to use it.
CREATE OR REPLACE PACKAGE BODY PLUSALT.INSERTAR
IS
PROCEDURE INSERTAR_ESTRATEGIA(
P_USUARIO IN VARCHAR2,
P_CAMPAÑA IN NUMBER,
P_FKPLANTILLA IN NUMBER,
P_NOMBRE IN VARCHAR2)
IS
BEGIN
INSERT
INTO ESTRATEGIA VALUES
(
NULL,
P_CAMPAÑA,
P_USUARIO,
P_FKPLANTILLA,
P_NOMBRE,
NULL,
SYSDATE,
1,
'Y'
);
END;
END;
/
Ths is the table
CREATE TABLE ESTRATEGIA
(
ESID NUMBER(25) NOT NULL,
FK_CAMPAÑA NUMBER(5) NOT NULL,
FK_USUARIO NUMBER(8) NOT NULL,
FK_PLANTILLAESTRA NUMBER(8),
ESNOMBRE VARCHAR2(100),
ESDESCRIPCION VARCHAR2(300),
ESFCHCREACION DATE,
FKESTADO NUMBER(3) NOT NULL,
ESACTIVA CHAR(1)
)
;
The sequence
CREATE SEQUENCE ESTRATEGIA_SEC
START WITH 1
INCREMENT BY 1
NOMAXVALUE;
The trigger
CREATE TRIGGER TRIG_ESTRATEGIA
BEFORE INSERT ON ESTRATEGIA
FOR EACH ROW
BEGIN
SELECT ESTRATEGIA_SEC.nextval INTO :new.ESID FROM dual;
END
;
USE RETURNING INTO in the insert with an OUT parameter. Use this parameter P_ESID in your java code.
CREATE OR REPLACE PACKAGE BODY PLUSALT.INSERTAR
IS
PROCEDURE INSERTAR_ESTRATEGIA(
P_USUARIO IN VARCHAR2,
P_CAMPAÑA IN NUMBER,
P_FKPLANTILLA IN NUMBER,
P_NOMBRE IN VARCHAR2,
P_ESID OUT NUMBER)
IS
BEGIN
INSERT
INTO ESTRATEGIA VALUES
(
NULL,
P_CAMPAÑA,
P_USUARIO,
P_FKPLANTILLA,
P_NOMBRE,
NULL,
SYSDATE,
1,
'Y'
) RETURNING ESID INTO P_ESID ;
END;
END;
/
http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/returninginto_clause.htm
Quick demonstration.
SQL> create table t (id int);
Table created.
SQL> create sequence s;
Sequence created.
SQL> var x number
SQL> insert into t values(s.nextval) returning id into :x;
1 row created.
SQL> print x
X
----------
1
This is code:
CREATE TABLE emp_where (where_clause VARCHAR2(4000));
INSERT INTO emp_where (where_clause)
VALUES ('first_name=''KING'' or department_id = 20');
commit;
CREATE OR REPLACE TYPE t_emp_rec AS OBJECT (
EMPLOYEE_ID NUMBER(4),
FIRST_NAME VARCHAR2(10),
JOB_ID VARCHAR2(9),
MANAGER_ID NUMBER(4),
HIRE_DATE DATE,
SALARY NUMBER(7,2),
DEPARTMENT_ID NUMBER(2)
);
/
CREATE OR REPLACE TYPE t_emp_tab AS TABLE OF t_emp_rec;
/
CREATE OR REPLACE FUNCTION emp_fn RETURN t_emp_tab
PIPELINED IS
l_sql VARCHAR2(32767);
l_where VARCHAR2(4000);
TYPE l_cur_type IS REF CURSOR;
l_cur l_cur_type;
l_rec employees%ROWTYPE;
BEGIN
SELECT where_clause INTO l_where FROM emp_where;
l_sql := 'SELECT * FROM employees WHERE ' || l_where;
OPEN l_cur FOR l_sql;
LOOP
FETCH l_cur
INTO l_rec;
EXIT WHEN l_cur%NOTFOUND;
PIPE ROW(t_emp_rec(EMPLOYEE_ID => l_rec.EMPLOYEE_ID
,FIRST_NAME => l_rec.FIRST_NAME
,JOB_ID => l_rec.JOB_ID
,MANAGER_ID => l_rec.MANAGER_ID
,hire_date => l_rec.hire_date
,SALARY => l_rec.SALARY
,DEPARTMENT_ID => l_rec.DEPARTMENT_ID));
END LOOP;
RETURN;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20000, SQLERRM || chr(10) || l_sql);
END;
/
CREATE OR REPLACE VIEW emp_vw AS
UPDATE emp_where SET where_clause = 'EMPLOYEE_ID BETWEEN 100 and 200';
COMMIT;
SELECT * FROM emp_vw;
When I execute SELECT * FROM emp_vw; with this clause: EMPLOYEE_ID BETWEEN 100 and 200
Oracle gives me an error
ORA-20000: ORA-06502: PL/SQL: numeric or value error: number precision too large
SELECT * FROM employees WHERE EMPLOYEE_ID BETWEEN 100 and 200
But when I execute query itself (SELECT * FROM employees WHERE EMPLOYEE_ID BETWEEN 100 and 200) there is no error. Another scenario -
when clause is 'deparment_id = 20', executing a view is correct. But when I change '=' to '>' (department_id > 20) - numeric or value error: number precision too large.
Can someone explain me how this is happening?
If I run:
DESCRIBE employees
Then I get the output:
Name Null Type
-------------- -------- ------------
EMPLOYEE_ID NOT NULL NUMBER(6)
FIRST_NAME VARCHAR2(20)
LAST_NAME NOT NULL VARCHAR2(25)
EMAIL NOT NULL VARCHAR2(25)
PHONE_NUMBER VARCHAR2(20)
HIRE_DATE NOT NULL DATE
JOB_ID NOT NULL VARCHAR2(10)
SALARY NUMBER(8,2)
COMMISSION_PCT NUMBER(2,2)
MANAGER_ID NUMBER(6)
DEPARTMENT_ID NUMBER(4)
If you compare it to your t_emp_rec object then you will see that most of the object attributes are a smaller size than the table columns.
Change the object to have the same sizes and it should work:
CREATE OR REPLACE TYPE t_emp_rec AS OBJECT (
EMPLOYEE_ID NUMBER(6),
FIRST_NAME VARCHAR2(20),
JOB_ID VARCHAR2(10),
MANAGER_ID NUMBER(6),
HIRE_DATE DATE,
SALARY NUMBER(8,2),
DEPARTMENT_ID NUMBER(4)
);
/
CREATE TABLE customer_master(
cust_id NUMBER(6) CUSTOMER_SEQ.Nextval PRIMARY KEY,
cust_password VARCHAR2(10),
cust_fname VARCHAR2(30),
cust_lname VARCHAR2(30),
cust_gender VARCHAR2(8),
cust_dob DATE,
cust_email VARCHAR2(30),
cust_password VARCHAR2(30),
cust_mobile NUMBER(10),
cust_add VARCHAR2(100),
newsletter VARCHAR2(5) CHECK (newsletter IN('yes','no')),
mob_service VARCHAR2(5) CHECK (mob_service IN('yes','no'))
);
Try to use trigger.
CREATE TABLE customer_master(
cust_id NUMBER(6) PRIMARY KEY,
cust_password VARCHAR2(10),
cust_fname VARCHAR2(30),
cust_lname VARCHAR2(30),
cust_gender VARCHAR2(8),
cust_dob DATE,
cust_email VARCHAR2(30),
cust_mobile NUMBER(10),
cust_add VARCHAR2(100),
newsletter VARCHAR2(5) CHECK (newsletter IN('yes','no')),
mob_service VARCHAR2(5) CHECK (mob_service IN('yes','no'))
);
CREATE OR REPLACE TRIGGER INS_customer_master
BEFORE INSERT ON customer_master
FOR EACH ROW
DECLARE
i_LAST NUMBER;
BEGIN
SELECT CUSTOMER_SEQ.NEXTVAL INTO i_LAST FROM Dual;
:NEW.cust_id := i_LAST;
END;
/