can I insert data into database with column name from input user ?
example:
INSERT INTO res_booking_status
(AirlineCode,
flightnumber,
departuredate,
totalbooking,:#${header[Subclass]})
Values (:#${header[AirlineCode]},
:#${header[FlightNumber]},
:#$ { header[departuredate] },
1,
1 );
I don't know JBoss Fuse, but - as far as Oracle is concerned - you'd use dynamic SQL for such a purpose.
Here's an example based on Scott's schema - I'm inserting a row into the EMP table, into its EMPNO and ENAME columns (which are obligatory). The 3rd and 4th parameters of my procedure are
custom column name
custom value for that column
This is the EMP table:
SQL> desc emp
Name Null? Type
----------------------------------------- -------- ----------------------------
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)
A procedure:
PAR_EMPNO and PAR_ENAME are obligatory columns' values
PAR_COL1 is custom column name
PAR_VAL1 is custom column's value
L_STR variable contains SQL statement
EXECUTE IMMEDIATE runs dynamic SQL, using parameters you passed:
.
SQL> CREATE OR REPLACE PROCEDURE p_userins (par_empno IN NUMBER,
2 par_ename IN VARCHAR2,
3 par_col1 IN VARCHAR2,
4 par_val1 IN VARCHAR2)
5 IS
6 l_str VARCHAR2 (500);
7 BEGIN
8 l_str :=
9 'insert into emp (empno, ename, '
10 || par_col1
11 || ') values (:a, :b, :c)';
12
13 EXECUTE IMMEDIATE l_str USING par_empno, par_ename, par_val1;
14 END;
15 /
Procedure created.
Testing:
SQL> EXEC p_userins(1, 'LF', 'deptno', 20);
PL/SQL procedure successfully completed.
SQL> SELECT empno, ename, job, sal, deptno FROM emp WHERE empno = 1;
EMPNO ENAME JOB SAL DEPTNO
---------- ---------- --------- ---------- ----------
1 LF 20
SQL>
Seems to be OK.
Now, how will you use it JBoss Fuse, no idea - if you can call a stored procedure, fine - above is the code you might want to adjust.
Related
I have a select query
select s.site, s.date, s.loaction, s.modified, sysdate p_run_date
from table s
where s.site = 123 --p_site
and s.date >= sysdate -p_date.
i want to create a pl/sql procedure to create a table where p_date and p_site need to be input to the procedure
Why would you want to do that? We normally do NOT create tables dynamically (which is what you'd use in PL/SQL). That procedure would try to create a table with the same name every time you call it (but with different parameters) and fail because table with such a name already exists (as it was created the first time you ran the procedure). Therefore, having a one-time procedure is pretty much useless.
If it must be done, oh well ...
SQL> create or replace procedure p_test (par_deptno in number, par_job in varchar2)
2 is
3 l_str varchar2(200);
4 begin
5 l_str := 'create table my_test as ' ||
6 'select deptno, ename, job, sal ' ||
7 'from emp ' ||
8 'where deptno = ' || dbms_assert.enquote_literal(par_deptno) ||
9 ' and job = ' || dbms_assert.enquote_literal(par_job);
10 execute immediate l_str;
11 end;
12 /
Procedure created.
Testing:
SQL> exec p_test(10, 'CLERK');
PL/SQL procedure successfully completed.
SQL> select * from my_test;
DEPTNO ENAME JOB SAL
---------- ---------- --------- ----------
10 MILLER CLERK 1300
Let's try it again, with different parameters:
SQL> exec p_test(20, 'MANAGER');
BEGIN p_test(20, 'MANAGER'); END;
*
ERROR at line 1:
ORA-00955: name is already used by an existing object
ORA-06512: at "SCOTT.P_TEST", line 10
ORA-06512: at line 1
SQL>
As I said, it'll fail. What you're trying to do is just wrong. You'd rather create a view.
I have to capture an insert statement's column names and column values , based on these 2 inputs I need to calculate a unique column value(sub-partition) and assign it to this insert so that the insert goes into a particular sub-partition of this table.
I'm not sure what you mean by "capturing" the INSERT statement.
From my point of view, you should compose it (the INSERT) yourself, using dynamic SQL.
My database is XE and it doesn't support partitioning, so I'd rather not guess it and not being able to test it; you'd, of course, use your own syntax. I'm using CASE to decide whether someone's COMM columns should get a value or not; you'd do it similarly.
Procedure:
SQL> create or replace procedure p_test
2 (p_empno in varchar2,
3 p_ename in varchar2,
4 p_sal in number)
5 is
6 l_str varchar2(200);
7 begin
8 l_str := 'insert into test (empno, ename, sal, comm) ' ||
9 'values (' ||
10 p_empno ||', '||
11 chr(39) || p_ename || chr(39) || ', ' ||
12 p_sal ||', '||
13 case when p_sal < 1000 then 100 else 0 end ||')';
14 dbms_output.put_line(l_str);
15 execute immediate l_str;
16 end;
17 /
Procedure created.
Testing:
SQL> set serveroutput on;
SQL> exec p_test(1, 'Little', 750);
insert into test (empno, ename, sal, comm) values (1, 'Little', 750, 100)
PL/SQL procedure successfully completed.
SQL> exec p_test(1, 'Foot', 2000);
insert into test (empno, ename, sal, comm) values (1, 'Foot', 2000, 0)
PL/SQL procedure successfully completed.
SQL> select * From test;
EMPNO ENAME SAL COMM
---------- ---------- ---------- ----------
1 Little 750 100
1 Foot 2000 0
SQL>
#Littlefoot , Thanks as in insert into abc ('name','empid','partition_id') values ('nparab',2000,10); The value of partition_id=10 is not known it will be calculated based on name and empid combination...I even dont knw the incoming insert statement , can i use trigger to catch the incoming insert then I can pass the column name and column value to let say a function and that function based on input combination of column name and column value calculates the partition_id and the function returns partition_id which is picked by the incoming insert so that insert statement goes in respective subpartition based on the partition_id
I have Created a table valued function in Sql server 2012 which works fine
but when i applied same code on same table but with Oracle Sql developer
it shows syntax error
Function in SQL Server
Create Function fx_Mfr
(
#Mfr varchar
)
returns table
as
Return
Select * from Manufacturer
where Mfr = #Mfr
One option is to return ref cursor, such as in this example (which, kind of, simulates what you have in MS SQL Server):
SQL> create or replace function fx (par_deptno in number)
2 return sys_refcursor
3 is
4 rc sys_refcursor;
5 begin
6 open rc for
7 select deptno, ename, job, sal
8 from emp
9 where deptno = par_deptno;
10 return rc;
11 end;
12 /
Function created.
SQL> select fx(10) from dual;
FX(10)
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
DEPTNO ENAME JOB SAL
---------- ---------- --------- ----------
10 CLARK MANAGER 2450
10 KING PRESIDENT 10000
10 MILLER CLERK 1300
SQL>
Or using implicit statement results - if you're on Oracle 12c or higher version Database. This feature was added to make migrating your code from SQL Server easier.
CREATE OR REPLACE PROCEDURE fx (par_deptno IN NUMBER)
AS
l_cursor_1 SYS_REFCURSOR;
BEGIN
OPEN l_cursor_1 FOR
SELECT department_id, first_name, last_name, job_id, salary
FROM employees
WHERE department_id = par_deptno;
DBMS_SQL.RETURN_RESULT(l_cursor_1);
END;
/
And then execute the program
DECLARE
PAR_DEPTNO NUMBER;
BEGIN
PAR_DEPTNO := 100;
FX(
PAR_DEPTNO => PAR_DEPTNO
);
END;
The output is auto-magically returned from the database:
Examples/docs on Oracle-Base
In Oracle 11g , I am trying to return multiple columns from a function call which is joined with a tables. This function takes employee_id as input and should return first_name and last_name as two separate columns from employees table.
I created a type
create or replace
type mytype as object
( val_1 varchar2(100),
val_2 number
);
/
And function
create or replace
function myfunc(p_in number) return mytype is
v_deptname varchar2(100);
v_mgrid number;
begin
select department_name,manager_id into v_deptname,v_mgrid from DEPARTMENTS where department_id = p_in;
return
mytype(v_deptname,v_mgrid);
end;
/
Both got created successfully. But when I execute function ,
select employee_id, salary, myfunc(department_id) from EMPLOYEES where employee_id in(100,101);
It gives result like below,
EMPLOYEE_ID SALARY
----------- ----------
MYFUNC(DEPARTMENT_ID)(VAL_1, VAL_2)
--------------------------------------------------------------------------------
100 24000
MYTYPE('Executive', 100)
101 17000
MYTYPE('Executive', 100)
But i want my result to be like ,
EMPLOYEE_ID SALARY VAL_1 VAL_2
----------- ---------- ------------------------------ ----------
100 24000 Executive 100
101 17000 Executive 100
Please help to achieve this.
Thanks
Well, you might be missing yet another type, based on MYTYPE.
Here's an example (I'm using Scott's schema as I don't have your tables). I've added DEPTNO into MYTYPE so that I'd be able to join the result (returned by the function) with the EMP table.
This is what you have:
SQL> create or replace type mytype as object
2 (deptno number,
3 dname varchar2(20),
4 loc varchar2(20));
5 /
Type created.
This is what you are missing:
SQL> create or replace type mytab as table of mytype;
2 /
Type created.
A function: note line 9:
SQL> create or replace function myfunc (p_in number) return mytab is
2 v_dname varchar2(20);
3 v_loc varchar2(20);
4 begin
5 select dname, loc
6 into v_dname, v_loc
7 from dept
8 where deptno = p_in;
9 return mytab(mytype(p_in, v_dname, v_loc));
10 end myfunc;
11 /
Function created.
Testing:
SQL> select * from table(myfunc(10));
DEPTNO DNAME LOC
---------- -------------------- --------------------
10 ACCOUNTING NEW YORK
SQL>
SQL> select e.ename, e.sal, m.dname, m.loc
2 from emp e join table(myfunc(e.deptno)) m on m.deptno = e.deptno
3 where e.deptno = 10
4 order by m.dname, e.ename;
ENAME SAL DNAME LOC
---------- ---------- -------------------- --------------------
CLARK 2450 ACCOUNTING NEW YORK
KING 10000 ACCOUNTING NEW YORK
MILLER 1300 ACCOUNTING NEW YORK
SQL>
You can try as below:
--Tables
CREATE TABLE dept (
deptno NUMBER,
dname VARCHAR2 (20),
loc VARCHAR2 (20)
);
/
CREATE TABLE employee (
employee_id NUMBER,
salary NUMBER
);
Code:
CREATE OR REPLACE TYPE mytype AS OBJECT (
deptno NUMBER,
dname VARCHAR2 (20),
loc VARCHAR2 (20)
);
CREATE OR REPLACE TYPE mytab AS TABLE OF mytype;
CREATE OR REPLACE FUNCTION myfunc ( p_in NUMBER)
RETURN mytab
IS
v_var mytab := mytab ();
BEGIN
SELECT
mytype (
deptno,
dname,
loc
)
BULK COLLECT INTO
v_var
FROM
dept
WHERE
deptno = p_in;
return (v_var);
END myfunc;
/
Execution:
SELECT
e.*,
t.deptno,
t.dname
FROM
employee e
CROSS JOIN
TABLE ( myfunc (100) ) t ;
Output:
Employee_Id SALARY DEPT DNAME
--------- ------ ---- ------
1001 20000 100 Executive
1002 25000 100 Executive
I need to write a procedure and update trigger. When any update is done on the table, the trigger should make a call to the procedure. Procedure should update the changes in another table. In that another table old value, updated value should be there.
What you described sounds like an ordinary logging; you don't really need a procedure, trigger does it all. Here's an example:
SQL> create table emp_log (empno number, sal_old number, sal_new number);
Table created.
SQL> create or replace trigger trg_bu_emp
2 before update of sal on emp
3 for each row
4 begin
5 insert into emp_log (empno, sal_old, sal_new)
6 values
7 (:new.empno, :old.sal, :new.sal);
8 end;
9 /
Trigger created.
SQL> select empno, ename, sal from emp where ename = 'KING';
EMPNO ENAME SAL
---------- ---------- ----------
7839 KING 5000
SQL> update emp set sal = 7000 where ename = 'KING';
1 row updated.
SQL> select * from emp_log;
EMPNO SAL_OLD SAL_NEW
---------- ---------- ----------
7839 5000 7000
SQL>
[EDIT, after reading a comment]
Homework, eh? So - create a procedure:
SQL> rollback;
Rollback complete.
SQL> create or replace procedure p_emp_sal_log
2 (par_empno in emp.empno%type, par_sal_old in emp.sal%type,
3 par_sal_new in emp.sal%type)
4 is
5 begin
6 insert into emp_log (empno, sal_old, sal_new)
7 values
8 (par_empno, par_sal_old, par_sal_new);
9 end;
10 /
Procedure created.
SQL> create or replace trigger trg_bu_emp
2 before update of sal on emp
3 for each row
4 begin
5 p_emp_sal_log(:new.empno, :old.sal, :new.sal);
6 end;
7 /
Trigger created.
SQL> update emp set sal = 2000 where ename = 'KING';
1 row updated.
SQL> select * from emp_log;
EMPNO SAL_OLD SAL_NEW
---------- ---------- ----------
7839 5000 2000
SQL>