Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
CREATE TABLE emp (
empno NUMBER (10) NOT NULL,
empname VARCHAR2 (50) NOT NULL,
mgr VARCHAR2 (10),
hiredate DATE,
sal NUMBER (10),
comm VARCHAR2 (10),
CONSTRAINT emp_pk PRIMARY KEY (empno)
) ;
DESC emp ;
INSERT ALL
INTO emp
(100, 'MARK', 'CXS', hire_date('1999-09-08', 'yyyy/mm/dd'), 8000, 'axw')
(200, 'peter', 'NULL', hire_date('1996-01-08', 'yyyy/mm/dd'), 9000)
(300, 'karl', 'NULL', hire_date('1995-05-08', 'yyyy/mm/dd'), 5000, 'AZQ')
(400, 'MAx', 'NULL', hire_date('1994-04-08', 'yyyy/mm/dd'), 10000, 'DES')
(500, 'Maggie', 'SAQ', hire_date('1998-06-08', 'yyyy/mm/dd'), 20000, 'QAS')
SELECT * FROM dual ;
Your insert all syntax is malformed, you need multiple into ... values ... pairs. At the moment it's trying to interpret 100 as a column name, hence the specific error you're seeing.
You also have hire_date(...) instead of to_date(...), and you're missing one of the comm values; assuming that is supposed to be null:
INSERT ALL
INTO emp (empno, empname, mgr, hiredate, sal, comm)
VALUES (100, 'MARK', 'CXS', TO_DATE('1999-09-08', 'yyyy-mm-dd'), 8000, 'axw')
INTO emp (empno, empname, mgr, hiredate, sal, comm)
VALUES (200, 'peter', NULL, TO_DATE('1996-01-08', 'yyyy-mm-dd'), 9000, null)
INTO emp (empno, empname, mgr, hiredate, sal, comm)
VALUES (300, 'karl', NULL, TO_DATE('1995-05-08', 'yyyy-mm-dd'), 5000, 'AZQ')
INTO emp (empno, empname, mgr, hiredate, sal, comm)
VALUES (400, 'MAx', NULL, TO_DATE('1994-04-08', 'yyyy-mm-dd'), 10000, 'DES')
INTO emp (empno, empname, mgr, hiredate, sal, comm)
VALUES (500, 'Maggie', 'SAQ', TO_DATE('1998-06-08', 'yyyy-mm-dd'), 20000, 'QAS')
SELECT * FROM dual ;
5 rows inserted.
I've also changed the stirng literals 'NULL' to plain nulls, as it seems much more liekly that is what you really intended.
And I've changed the date format masks to use - rather than /, to match the values. But if you're using fixed values like that it's simpler to use date literals instead, e.g. instead of
INTO emp (empno, empname, mgr, hiredate, sal, comm)
VALUES (100, 'MARK', 'CXS', TO_DATE('1999-09-08', 'yyyy-mm-dd'), 8000, 'axw')
use:
INTO emp (empno, empname, mgr, hiredate, sal, comm)
VALUES (100, 'MARK', 'CXS', DATE '1999-09-08', 8000, 'axw')
The syntax for the INSERT ALL statement in Oracle/PLSQL is:
INSERT ALL
INTO mytable (column1, column2, column_n) VALUES (expr1, expr2, expr_n)
INTO mytable (column1, column2, column_n) VALUES (expr1, expr2, expr_n)
INTO mytable (column1, column2, column_n) VALUES (expr1, expr2, expr_n)
SELECT * FROM dual;
So in your case you can use
INSERT ALL
INTO emp (empno, empname, mgr, hiredate, sal, comm)
VALUES (100, 'MARK', 'CXS', TO_DATE('1999-09-08', 'yyyy-mm-dd'), 8000, 'axw')
INTO emp (empno, empname, mgr, hiredate, sal, comm)
VALUES (200, 'peter', NULL, TO_DATE('1996-01-08', 'yyyy-mm-dd'), 9000, null)
INTO emp (empno, empname, mgr, hiredate, sal, comm)
VALUES (300, 'karl', NULL, TO_DATE('1995-05-08', 'yyyy-mm-dd'), 5000, 'AZQ')
INTO emp (empno, empname, mgr, hiredate, sal, comm)
VALUES (400, 'MAx', NULL, TO_DATE('1994-04-08', 'yyyy-mm-dd'), 10000, 'DES')
INTO emp (empno, empname, mgr, hiredate, sal, comm)
VALUES (500, 'Maggie', 'SAQ', TO_DATE('1998-06-08', 'yyyy-mm-dd'), 20000, 'QAS')
SELECT * FROM dual ;
Also for any column you want blank/no value just put NULL if you include this as 'NULL' it will be considered as text NULL.
Related
I have problem with my dml trigger on oracle database.I want to launch trigger when i update first_name or last name on employees table in hr schema. During execution trigger i Have error ORA-00060: Please help. Idon't have any ideas how can i fix it.enter image description here
CREATE OR replace TRIGGER up_sal
BEFORE UPDATE OF first_name, last_name ON employees
FOR EACH ROW
DECLARE
PRAGMA autonomous_transaction;
var_sal employees.salary%TYPE;
var_avg NUMBER;
var_emp_id NUMBER;
BEGIN
SELECT salary
INTO var_sal
FROM employees
WHERE first_name = :NEW.first_name
OR last_name = :NEW.last_name;
SELECT Avg(salary)
INTO var_avg
FROM employees
WHERE department_id IN( :OLD.department_id );
IF var_sal < var_avg THEN
var_emp_id := :OLD.employee_id;
UPDATE employees
SET salary = var_avg * 1.1
WHERE employee_id = var_emp_id;
COMMIT;
END IF;
END;
You can use:
CREATE TRIGGER up_sal
BEFORE UPDATE OF first_name, last_name ON employees
FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
var_avg employees.salary%TYPE;
BEGIN
SELECT Avg(salary)
INTO var_avg
FROM employees
WHERE department_id IN( :OLD.department_id );
IF :NEW.salary < var_avg THEN
:NEW.salary := var_avg * 1.1;
END IF;
COMMIT;
END;
/
Which, for the sample data:
CREATE TABLE employees (
department_id NUMBER,
first_name VARCHAR2(20),
last_name VARCHAR2(20),
salary NUMBER
);
INSERT INTO employees (department_id, first_name, last_name, salary)
SELECT 1, 'Alice', 'Abbot', 90 FROM DUAL UNION ALL
SELECT 1, 'Betty', 'Baron', 95 FROM DUAL UNION ALL
SELECT 1, 'Carol', 'Count', 105 FROM DUAL UNION ALL
SELECT 1, 'Debra', 'Duke', 110 FROM DUAL;
Then if you do:
UPDATE employees
SET first_name = TRIM(first_name),
last_name = TRIM(last_name);
Then:
SELECT * FROM employees;
Outputs:
DEPARTMENT_ID
FIRST_NAME
LAST_NAME
SALARY
1
Alice
Abbot
110
1
Betty
Baron
110
1
Carol
Count
105
1
Debra
Duke
110
db<>fiddle here
Good day,
I am trying to capture date from a apex_item.text but its not working
my classic report table is
SELECT apex_item.checkbox2(1,productID,'class=indCheck')
|| apex_item.hidden(2,productname)
|| apex_item.hidden(3, productcode)
|| apex_item.hidden(5,amount)
as "SELECT",
PRODUCTID,
PRODUCTCODE,
PRODUCTNAME,
PRODUCTDESC,
CATEGORYCODE,
SERIALNUMBER,
UNITPRICE,
REORDERLEVEL,
DISCONTINUED,
UNITSINHAND,
STATUS,
LOCATION,
LOCATIONDESCRIPTION,
apex_item.text (20,amount) as amount
from PRODUCTS
my pl/sql consist of
begin
for idx in 1 .. apex_application.g_f01.count loop
if apex_application.g_f01(idx) is not null then
insert into pending
(products,employeename,department,dates ,amount
)
values
(apex_application.g_f02(idx),:app_user,:app_user,
sysdate,apex_application.g_f05(idx));
end if ;
end loop;
end;
everything is being captured except the apex_item.text (20,amount) as amount which is being reference with apex_application.g_f05(idx)
I did use the same code as you are using and it worked fine.
See my understanding.
Table 1:
DROP TABLE ASHISH_SAMPLE_EMP CASCADE CONSTRAINTS;
CREATE TABLE ASHISH_SAMPLE_EMP
(
EMPNO NUMBER,
ENAME VARCHAR2(20 BYTE),
SAL NUMBER,
LOC VARCHAR2(22 BYTE),
DEPT VARCHAR2(22 BYTE),
ACTIVE VARCHAR2(4 BYTE) DEFAULT 'N'
);
Sample data
SET DEFINE OFF;
Insert into ASHISH_SAMPLE_EMP
(EMPNO, ENAME, SAL, LOC, DEPT,
ACTIVE)
Values
(1, 'Sahay', 1000, 'Delhi', 'SOFTWARE',
'N');
Insert into ASHISH_SAMPLE_EMP
(EMPNO, ENAME, SAL, LOC, DEPT,
ACTIVE)
Values
(4, 'TEst', 555, 'Noida', 'DBA',
'N');
Insert into ASHISH_SAMPLE_EMP
(EMPNO, ENAME, SAL, LOC, DEPT,
ACTIVE)
Values
(7, 'TEst', 555, 'Noida', 'DBA',
'N');
Insert into ASHISH_SAMPLE_EMP
(EMPNO, ENAME, SAL, LOC, DEPT,
ACTIVE)
Values
(2, 'Ashish', 1000, 'Gurugram', 'IT2',
'N');
COMMIT;
Table 2:
CREATE TABLE ashish_apex_item_issue
(
empno NUMBER,
amount NUMBER
);
Report Query
select apex_item.checkbox2(1,empno,'class=indCheck') || apex_item.hidden(5,sal) as "SELECT",
EMPNO,
ENAME,
apex_item.text (20,SAL) as amount,
LOC,
DEPT,
ACTIVE
from ASHISH_SAMPLE_EMP
Save data Process
begin
for idx in 1 .. apex_application.g_f01.count loop
if apex_application.g_f01(idx) is not null then
insert into ashish_apex_item_issue
(empno,amount
)
values
(apex_application.g_f01(idx),apex_application.g_f05(idx));
end if ;
end loop;
end;
Please follow the below article
https://roelhartman.blogspot.com/2018/02/apexapplicationgf0x-array-processing-in.html
I cannot seem to find any problem:
INSERT ALL
INTO DEPT_PART PARTITION(part1) (EMPNO, ENAME, SAL, DEPTNO)
SELECT EMPNO,ENAME,SAL,DEPTNO FROM emp WHERE DEPTNO=10
INTO DEPT_PART PARTITION(part2) (EMPNO, ENAME, SAL, DEPTNO)
SELECT EMPNO,ENAME,SAL,DEPTNO FROM emp WHERE DEPTNO=20
INTO DEPT_PART PARTITION(part3) (EMPNO, ENAME, SAL, DEPTNO)
SELECT EMPNO,ENAME,SAL,DEPTNO FROM emp WHERE DEPTNO=30
SELECT * FROM DUAL;
You need to try INSERT FIRST like following:
INSERT FIRST
WHEN DEPTNO = 10 THEN
INTO DEPT_PART PARTITION(part1) (EMPNO, ENAME, SAL, DEPTNO)
WHEN DEPTNO = 20 THEN
INTO DEPT_PART PARTITION(part2) (EMPNO, ENAME, SAL, DEPTNO)
WHEN DEPTNO = 30 THEN
INTO DEPT_PART PARTITION(part3) (EMPNO, ENAME, SAL, DEPTNO)
SELECT EMPNO,ENAME,SAL,DEPTNO FROM emp WHERE DEPTNO IN (10,20,30)
Cheers!!
How to simplify following procedure?
I want to remove duplication of WITH clause.
IF p_YN = 'Y' THEN
OPEN p_cursor FOR
WITH VIEW_A AS
(
[very long select statements]
)
SELECT COL_A, COL_B, SUM(COL_C), SUM(COL_D) FROM VIEW_A
GROUP BY COL_A, COL_B;
ELSE
OPEN p_cursor FOR
WITH VIEW_A AS
(
[very long select statements]
)
SELECT COL_1, COL_2, SUM(COL_3), SUM(COL_4) FROM VIEW_A
GROUP BY COL_1, COL_2;
END IF;
I considered UNON ALL.
WITH VIEW_A AS
(
[very long select statements]
)
OPEN p_cursor FOR
SELECT COL_A, COL_B, SUM(COL_C), SUM(COL_D) FROM VIEW_A
GROUP BY COL_A, COL_B
WHERE p_YN = 'Y'
UNION ALL
SELECT COL_1, COL_2, SUM(COL_3), SUM(COL_4) FROM VIEW_A
GROUP BY COL_1, COL_2
WHERE p_YN <> 'Y';
But this doesn't work because two statements have different columns.
If UNION ALL can do what you need, maybe you can simply add same "fake" columns:
WITH VIEW_A AS
(
[very long select statements]
)
OPEN p_cursor FOR
SELECT COL_A, COL_B, SUM(COL_C), SUM(COL_D), NULL AS COL_1, NULL AS COL_2, NULL AS COL_3, NULL AS COL_4
FROM VIEW_A
GROUP BY COL_A, COL_B
WHERE p_YN = 'Y'
UNION ALL
SELECT NULL AS COL_A, NULL AS COL_B, NULL AS COL_C, NULL AS COL_D, COL_1, COL_2, SUM(COL_3), SUM(COL_4)
FROM VIEW_A
GROUP BY COL_1, COL_2
WHERE p_YN <> 'Y';
NULL should be changed in something else, depending on the types of your columns; besides, this may work or not, depending on what you need to do with the opened cursor.
I am trying to take some statistics against the Emp table, the create table & the rows inserted are given below. I am trying to develop a store procedure which will get all the columns for a particular table from oracle ALL_TAB_COLUMNS & I will generate the statistics.
The PL/SQL block of code given below is compiling but not returning any records when I run it. Can anyone please let me know where I might be getting wrong -
`is "distinct_cnt := 'SELECT COUNT(DISTINCT (' || table_rec.COLUMN_NAME || ')) FROM' || table_rec.TABLE_NAME;"`
a correct way of assigning the result to a variable.
create table emp( empno number(4,0),
ename varchar2(10),
job varchar2(9),
mgr number(4,0),
hiredate date,
sal number(7,2),
comm number(7,2),
deptno number(2,0)
)
insert into emp values( 7839, 'KING', 'PRESIDENT', null, to_date('17-11-1981','dd-mm-yyyy'), 5000, null, 10);
insert into emp values( 7698, 'BLAKE', 'MANAGER', 7839, to_date('1-5-1981','dd-mm-yyyy'), 2850, null, 30);
insert into emp values( 7782, 'CLARK', 'MANAGER', 7839, to_date('9-6-1981','dd-mm-yyyy'), 2450, null, 10);
insert into emp values( 7566, 'JONES', 'MANAGER', 7839, to_date('2-4-1981','dd-mm-yyyy'), 2975, null, 20);
insert into emp values( 7788, 'SCOTT', 'ANALYST', 7566, to_date('13-JUL-87','dd-mm-rr') - 85, 3000, null, 20);
insert into emp values( 7902, 'FORD', 'ANALYST', 7566, to_date('3-12-1981','dd-mm-yyyy'), 3000, null, 20);
insert into emp values( 7369, 'SMITH', 'CLERK', 7902, to_date('17-12-1980','dd-mm-yyyy'), 800, null, 20);
insert into emp values( 7499, 'ALLEN', 'SALESMAN', 7698, to_date('20-2-1981','dd-mm-yyyy'), 1600, 300, 30);
insert into emp values( 7521, 'WARD', 'SALESMAN', 7698, to_date('22-2-1981','dd-mm-yyyy'), 1250, 500, 30);
insert into emp values( 7654, 'MARTIN', 'SALESMAN', 7698, to_date('28-9-1981','dd-mm-yyyy'), 1250, 1400, 30);
insert into emp values( 7844, 'TURNER', 'SALESMAN', 7698, to_date('8-9-1981','dd-mm-yyyy'), 1500, 0, 30);
insert into emp values( 7876, 'ADAMS', 'CLERK', 7788, to_date('13-JUL-87', 'dd-mm-rr') - 51, 1100, null, 20);
insert into emp values( 7900, 'JAMES', 'CLERK', 7698, to_date('3-12-1981','dd-mm-yyyy'), 950, null, 30);
insert into emp values( 7934, 'MILLER', 'CLERK', 7782, to_date('23-1-1982','dd-mm-yyyy'), 1300, null, 10);
Commit;
create or replace
procedure p_profiling (V_tablename IN varchar2)
IS
cursor c1 is
select TABLE_NAME,
COLUMN_NAME
from
ALL_TAB_COLUMNS
where TABLE_NAME='V_tablename';
REC_CNT NUMBER;
distinct_cnt NUMBER;
is_valid NUMBER;
not_null NUMBER;
BEGIN
FOR table_rec in c1
LOOP
REC_CNT := 'SELECT COUNT(*) FROM' || table_rec.TABLE_NAME;
distinct_cnt := 'SELECT COUNT(DISTINCT (' || table_rec.COLUMN_NAME || ')) FROM' || table_rec.TABLE_NAME;
is_valid := 'SELECT COUNT(*) FROM '||table_rec.TABLE_NAME ||'WHERE'|| table_rec.COLUMN_NAME ||' IS NOT NULL
AND LENGTH('||table_rec.COLUMN_NAME||') = LENGTH(LTRIM(RTRIM('||table_rec.COLUMN_NAME||')))';
not_null := 'SELECT COUNT(*) FROM'|| table_rec.TABLE_NAME ||'WHERE '|| table_rec.COLUMN_NAME ||'IS NOT NULL';
DBMS_OUTPUT.PUT_LINE ('REC_CNT:'||REC_CNT||' '||'distinct_cnt:'||distinct_cnt||' '||'is_valid:'||is_valid ||' '||'TABLE_NAME'||table_rec.TABLE_NAME||' '||'COLUMN_NAME'||table_rec.COLUMN_NAME);
END LOOP;
END;
For executing the SQL statements created dynamically, you need to use EXECUTE IMMEDIATE:
create or replace
procedure p_profiling (V_tablename IN varchar2)
IS
cursor c1 is
select TABLE_NAME,
COLUMN_NAME
from
ALL_TAB_COLUMNS
where TABLE_NAME='V_tablename';
REC_CNT NUMBER;
distinct_cnt NUMBER;
is_valid NUMBER;
not_null NUMBER;
BEGIN
FOR table_rec in c1
LOOP
IF c1%ROWCOUNT = 1 THEN
EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM' ||
table_rec.TABLE_NAME INTO REC_CNT;
END IF;
EXECUTE IMMEDIATE 'SELECT COUNT(DISTINCT (' ||
table_rec.COLUMN_NAME || ')) FROM' ||
table_rec.TABLE_NAME INTO distinct_cnt;
EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM '||
table_rec.TABLE_NAME ||'WHERE'|| table_rec.COLUMN_NAME ||'
IS NOT NULL
AND LENGTH('||table_rec.COLUMN_NAME||') =
LENGTH(LTRIM(RTRIM ('||table_rec.COLUMN_NAME||')))' INTO is_valid;
EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM'||
table_rec.TABLE_NAME ||'WHERE '|| table_rec.COLUMN_NAME
||'IS NOT NULL' INTO not_null;
DBMS_OUTPUT.PUT_LINE('REC_CNT:'||REC_CNT||' '||'distinct_cnt:'||
distinct_cnt||' '
||'is_valid:'||is_valid ||' '||'TABLE_NAME'||table_rec.TABLE_NAME||' '
||'COLUMN_NAME'||table_rec.COLUMN_NAME);
END LOOP;
END;
You need to use EXECUTE IMMEDIATE in order to execute these dynamics queries an also to obtain the data you are looking for.
Review this post: dynamic SELECT INTO clause in PL/SQL
Hope this help.