DML statements in Function

Hi,
I have small question
Why we should not written DML statements in Function ?
Can any one explain that
Thanks...

971822 wrote:
Hi,
I have small question
Why we should not written DML statements in Function ?
Can any one explain thatThe answer is: "it depends".
Functions are used for many many different purposes, and it is the purpose that determines whether it's a good idea to write DML statements in a function.
As already mentioned, there are the purity rules, that basically say "if you're going to be calling the function from queries etc. then it cannot do DML, otherwise you'll get an exception"
But there are also functions that are intended to be used within PL/SQL code for other purposes. It may be that you need something that updates some data and returns a result from that updated data, or it returns how much data was effected, in which case it's perfectly ok to have a function do some DML.
As long as the code is well modularised and makes sense for the purpose for which it is intended, then you are doing the right thing. Where it goes wrong is when people lack design in their applications, and try to write 'generic' functions to be used in PL/SQL or SQL, or fail to modularise code so a function is doing the task of several things based on some parameters etc. when really each task should seperated to it's own functions/procedures etc.
So we cannot just say that we "should not" write DML inside functions; but we can say that there are design considerations (or lack of) when it would be bad practice to do so.

Similar Messages

  • If we use DML statement in function then that function can be used inside s

    if we use DML statement in function then that function can be used inside select query or any DML query?

    select f from t2;I think you meant to query t1.
    It works if the function is an autonomous transaction:
    create or replace function f return number
    is
    PRAGMA AUTONOMOUS_TRANSACTION;
    begin
        update t1 set c=2;
        commit;
        return 1;
    end;
    select f from t1But as Billy said why would you want to do DML this way. And this is not the way autonomous procedures should be used either.
    An an answer to an interview question though nothing wrong with it.

  • Udf in dml statements

    can we select udf which contains dml statements?

    1007109 wrote:
    can we select udf which contains dml statements?
    Excellent question! And one that illustrates just how careful you have to be when you ASK questions or provide answers.
    As with many things Oracle the correct answer is: it depends.
    Yes - you can. And no - you can't. And also, yes - you can!
    ANY one of those answers is correct, depending on what assumptions the questioner is making and/or what assumptions that you, the answerer are making.
    Sometimes a interviewer will ask this old 'trick' question and then get mad at you if you don't give them the answer that they want even if you give them an answer that is CORRECT and even if you explain WHY your answer is correct.
    Some questioners are looking for the answer that Frank gave:
    >
    A function that performs DML (or that calls another sub-program that performs DML) can NOT be used in a SQL statement, such as SELECT.
    >
    If you just read the 'restrictions' section in the Advanced App Developer's guide you might come up with the answer that Frank gave.
    http://docs.oracle.com/cd/E11882_01/appdev.112/e25518/adfns_packages.htm#i1008107
    >
    Restrictions
    When a new SQL statement is run, checks are made to see if it is logically embedded within the execution of a running SQL statement. This occurs if the statement is run from a trigger or from a subprogram that was in turn invoked from the running SQL statement. In these cases, further checks determine if the new SQL statement is safe in the specific context.
    These restrictions are enforced on subprograms:
      A subprogram invoked from a query (SELECT statement) or DML statement cannot end the current transaction, create or rollback to a savepoint, or ALTER the system or session.
      A subprogram invoked from a query or parallelized DML statement cannot run a DML statement or otherwise modify the database.
      A subprogram invoked from a DML statement cannot read or modify the particular table being modified by that DML statement.
    >
    But then if you read the very next sentence in that doc you will see this:
    >
    You can avoid these restrictions if the execution of the new SQL statement is not logically embedded in the context of the running statement. PL/SQL autonomous transactions provide one escape (see "Autonomous Transactions" ).
    >
    And finally if the term DML includes the SELECT statement and the SQL Language doc DOES use it that way
    http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_1001.htm#i2099257
    >
    The SELECT statement is a limited form of DML statement in that it can only access data in the database. It cannot manipulate data stored in the database, although it can manipulate the accessed data before returning the results of the query.
    >
    That doc also lists statements other than the traditional SELECT, INSERT, UPDATE or DELETE
    >
    Data Manipulation Language (DML) Statements
    Data manipulation language (DML) statements access and manipulate data in existing schema objects. These statements do not implicitly commit the current transaction. The data manipulation language statements are:
    CALL
    DELETE
    EXPLAIN PLAN
    INSERT
    LOCK TABLE
    MERGE
    SELECT
    UPDATE
    >
    So the CORRECT answer is:
    1. No, Frank's answer, if by DML you are only considering INSERT, UPDATE or DELETE statements and you do NOT use the AUTONOMOUS_TRANSACTION pragma.
    2. Yes - if DML includes SELECT (LOCK TABLE also works) - you don't need the pragma. A common use of functions is in LOOKUP operations. These functions can be, but should NOT be, called from a sql statement.
    3. Yes - if the AUTONOMOUS_TRANSACTION pragma is used. This is NOT recommended.
    Try some of the following code examples
    >
    create or replace function get_dname(p_deptno IN number) return varchar2 is
    v_dname dept.dname%type;
    begin
      select dname into v_dname from dept where deptno = p_deptno;
      return v_dname;
    end;
    select empno, ename, deptno, get_dname(deptno) from emp e
    where rownum < 4
    EMPNO,ENAME,DEPTNO,GET_DNAME(DEPTNO)
    7369,SMITH,20,RESEARCH*
    7499,ALLEN,30,SALES**
    7521,WARD,30,SALES**
    create or replace function get_dname1(p_deptno IN number) return varchar2 is
    v_dname dept.dname%type;
    begin
      update dept set dname = dname || '*' where deptno = p_deptno;
      select dname into v_dname from dept where deptno = p_deptno;
      return v_dname;
    end;
    select empno, ename, deptno, get_dname1(deptno) from emp e
    where rownum < 4
    ORA-14551: cannot perform a DML operation inside a query
    ORA-06512: at "SCOTT.GET_DNAME1", line 4
    create or replace function get_dname2(p_deptno IN number) return varchar2 is
    PRAGMA AUTONOMOUS_TRANSACTION;
    v_dname dept.dname%type;
    begin
      update dept set dname = dname || '*' where deptno = p_deptno;
      commit;
      select dname into v_dname from dept where deptno = p_deptno;
      return v_dname;
    end;
    select empno, ename, deptno, get_dname2(deptno) from emp e
    where rownum < 4
    EMPNO,ENAME,DEPTNO,GET_DNAME2(DEPTNO)
    7369,SMITH,20,RESEARCH**
    7499,ALLEN,30,SALES***
    7521,WARD,30,SALES****
    create or replace function get_dname3(p_deptno IN number) return varchar2 is
    v_dname dept.dname%type;
    begin
      lock table emp_copy in share mode;
      select dname into v_dname from dept where deptno = p_deptno;
      return v_dname;
    end;
    select empno, ename, deptno, get_dname3(deptno) from emp e
    where rownum < 4
    EMPNO,ENAME,DEPTNO,GET_DNAME2(DEPTNO)
    7369,SMITH,20,RESEARCH**
    7499,ALLEN,30,SALES***
    7521,WARD,30,SALES****
    >

  • Auditing DDL and DML statements of selective IP addresses....

    Hi all,
    DB : 11.2.0.2 64 bit
    OS : RHEL 5.7 64bit
    Hi all,
    I want to audit all DDL and DML statements for some selective IP Addresses or hostnames.
    I read about Fine Grained Audit. I got the following code to enable auditing of nondatabase user's actions(Application users).
    created policy for client identifier.......
    BEGIN
    DBMS_FGA.ADD_POLICY(OBJECT_SCHEMA => 'OE',
    OBJECT_NAME => 'ORDERS',
    POLICY_NAME => 'ORDERS_FGA_POL',
    AUDIT_CONDITION => 'SYS_CONTEXT(''USERENV'', ''CLIENT_IDENTIFIER'') = ''Robert''',
    HANDLER_SCHEMA => NULL,
    HANDLER_MODULE => NULL,
    ENABLE => True,
    STATEMENT_TYPES => 'INSERT,UPDATE,DELETE,SELECT',
    AUDIT_TRAIL => DBMS_FGA.DB + DBMS_FGA.EXTENDED,
    AUDIT_COLUMN_OPTS => DBMS_FGA.ANY_COLUMNS);
    END;
    But I want to audit all DDL and DML statements for a particular schema say ABC from selective IP addresses or hostnames so how can I do this?
    Pl suggest.....
    Regards,
    Andy.

    Hi,
    You could :
    1. create a function, say myfunction, returning 1 if you want to audit, 0 otherwise
    This function would test sys_context('userenv','ip_address') within the desired IP address to be audited
    2. create your fga on the objects you want to audit adding the clause audit_condition=>'myfunction=1'
    Nicolas.

  • Writing own dml statements in jdeveloper

    i need to write my own dml statement in a jdevelopers application. like on saving a purchase form i would like to update stock table as well. Some one told me to write code in DoDML procedure but how ? i mean what statement should i write there ?

    lot of possibilities but easy way is to call PL/SQL code i guess you are coming from FORMS background so it would be easy and understandable for you
    You can expose PL/SQL package as web-services also you can call stored procedures and functions in ADF
    here is the example http://baigsorcl.blogspot.com/2010/05/calling-plsql-procedure-and-function-in.html
    doDML() will work at entity level you can call your PL/SQL at doDML as well or as call its method binding

  • Calling PLSQL from DML Statements

    hello everybody,
    i have just a minor "problem". (this confuses me because of the 1z0-147 programming plsql exam)
    Oracle Documentation (10G R2 Application Developer's Guide - Fundamentals - 7 Coding PL/SQL Procedures and Packages) says:
    The following restrictions are enforced on subprograms:
    => A subprogram called from a DML statement may not read or modify the particular table being modified by that DML statement.
    i did some tests but they resulted not in an error (mutating table exception or whatever); so maybe Oracle's documentation is inaccurate here ?
    here is an example which works fine (10G R2):
    drop table ttestuh
    create table ttestuh ( s varchar2(19));
    insert into ttestuh values ( 'Oracle' );
    create or replace function getVal return varchar2 is
    retval ttestuh.s%type;
    begin
    select s into retval from ttestuh where rownum <2;
    return retval;
    end;
    create or replace function getVal2 return varchar2 is
    begin
    insert into ttestuh values ( 'ASDF');
    return 'ASDF';
    end;
    insert into ttestuh values ( getval );
    insert into ttestuh values ( getval2 );
    commit
    select * from ttestuh
    rows:
    Oracle
    Oracle
    ASDF
    ASDFit seems to be that even DML-doing PLSQL calls are allowed when called from an insert statement on the same table.
    (for update statements an mutating table exception is raised)
    thanks in advance for your opinions
    ulli

    I believe what docs are saying is correct. And also what you are seeing is correct. There may be a small issue in understanding the impact.
    SQL>  create or replace function fun1
      2   return number
      3   is
      4   begin
      5   delete test;
      6   end;
      7  .
    SQL>  create or replace function fun1
      2   return number
      3   is
      4   begin
      5   update test set owner='amn';
      6  end;
      7  /
    Function created.
    SQL> select fun1 from test;
    select fun1 from test
    ERROR at line 1:
    ORA-14551: cannot perform a DML operation inside a query
    ORA-06512: at "AMAN.FUN1", line 5
    SQL>  create or replace function fun1
      2   return number
      3   is
      4   begin
      5  insert into test(owner) values('new');
      6  end;
      7  /
    Function created.
    SQL> select fun1 from test;
    select fun1 from test
    ERROR at line 1:
    ORA-14551: cannot perform a DML operation inside a query
    ORA-06512: at "AMAN.FUN1", line 5
    SQL>The mutating error means that the data that you are trying to change is also read by the same session and this means, Oralce can't give a "dirty read" to you. That's why in the case of Update, the mutating error is returned. The insert statement is inserting new data which anyways your select can't see as long as its not committed and with it you haven't changed the existing one that's why its allowed.
    SQL> create or replace function fun1
      2  return varchar2
      3  is
      4  a varchar2(10);
      5  begin
      6  select owner into a from test where rownum<=1;
      7  end;
      8  /
    Function created.
    SQL> update test owner=fun1;
    update test owner=fun1
    ERROR at line 1:
    ORA-00971: missing SET keyword
    SQL> update test set owner=fun1;
    update test set owner=fun1
    ERROR at line 1:
    ORA-04091: table AMAN.TEST is mutating, trigger/function may not see it
    ORA-06512: at "AMAN.FUN1", line 6
    SQL>HTH
    Aman....

  • PLS-00435: DML statement without BULK In-BIND cannot be used

    My requirement
    I am dynamically creating a staging table my_stg, and then populate it. Seems simple, but not sure why i get this error,
    create table gtest4(myid varchar2(10), mykey varchar2(10));
    create table gtest5(myid varchar2(10), mykey varchar2(10));
    insert into gtest4 values(1,3);
    insert into gtest4 values(2,7);
    insert into gtest5 values(5,3);
    insert into gtest5 values (1,7);
    commit;
    /* Formatted on 2012/01/27 17:52 (Formatter Plus v4.8.8) */
    CREATE OR REPLACE PROCEDURE px
    IS
    TYPE rectype IS RECORD (
    myid VARCHAR2 (100),
    mykey VARCHAR2 (100)
    TYPE tabtype IS TABLE OF rectype
    INDEX BY BINARY_INTEGER;
    rec tabtype;
    cur sys_refcursor;
    BEGIN
    EXECUTE IMMEDIATE 'create table my_stg(myid varchar2(100), mykey varchar2(100)) ';
    OPEN cur FOR 'select a.myid, b.mykey
    from gtest4 a, gtest5 b
    where a.mykey = b.mykey';
    LOOP
    FETCH cur
    BULK COLLECT INTO rec LIMIT 500;
    FORALL i IN 1 .. rec.COUNT
    EXECUTE IMMEDIATE 'insert into my_stg(myid, mykey) values (rec(i).myid,
    rec(i).mykey)';
    EXIT WHEN cur%NOTFOUND;
    END LOOP;
    END;
    I compile the above proc, and get
    PLS-00435: DML statement without BULK In-BIND cannot be used
    the reason I do insert in execute immediate is because the table my_stg does not exist, it is created on the fly

    I tried the below, used plsql table variables instead of record type
    CREATE OR REPLACE PROCEDURE px
    IS
    TYPE rectype IS RECORD (
    myid VARCHAR2 (100),
    mykey VARCHAR2 (100)
    TYPE tabtype1 IS TABLE OF varchar2(100)
    INDEX BY BINARY_INTEGER;
    TYPE tabtype2 IS TABLE OF varchar2(100)
    INDEX BY BINARY_INTEGER;
    rec1 tabtype1;
    rec2 tabtype2;
    cur sys_refcursor;
    BEGIN
    EXECUTE IMMEDIATE 'create table my_stg(myid varchar2(100), mykey varchar2(100)) ';
    OPEN cur FOR 'select a.myid, b.mykey
    from gtest4 a, gtest5 b
    where a.mykey = b.mykey';
    LOOP
    FETCH cur
    BULK COLLECT INTO rec1, rec2 LIMIT 500;
    FORALL i IN 1 .. rec.COUNT
    execute immediate 'insert into my_stg(myid, mykey) values (:1,:2)
    using rec1(i).myid, rec2(i).mykey;
    EXIT WHEN cur%NOTFOUND;
    END LOOP;
    END;
    I get error
    PLS-00103: Encountered the symbol "insert into my_stg(myi
    mykey) values (:1,:2)
    using rec1(i).myi" when expecting one of the following:
    ( - + case mod new not null <an identifier>
    <a double-quoted delimited-identifier> <a bind variable>
    count current exists max min prior sql stddev sum varianc
    execute forall merge time timestamp interval date
    <a string literal with character set specification>
    <a number> <a single-quoted SQL string> pipe
    <an alternatively-quoted string literal
    Please help

  • Will Materialized view log reduces the performance of DML statements on the master table

    Hi all,
    I need to refresh a on demand fast refresh Materialized view in Oracle 11GR2. For this purpose I created a Materialized view log on the table (Non partitioned) in which records will be inserted @ rate of 5000/day as follows.
    CREATE MATERIALIZED VIEW LOG ON NOTES NOLOGGING WITH PRIMARY KEY INCLUDING NEW VALUES;
    This table already has 20L records and adding this Mview log will reduce the DML performance on the table ?
    Please guide me on this.

    Having the base table maintain a materialised view log will have an impact on the speed of DML statements - they are doing extra work, which will take extra time. A more sensible question would be to ask whether it will have a significant impact, to which the answer is almost certainly "no".
    5000 records inserted a day is nothing. Adding a view log to the heap really shouldn't cause any trouble at all - but ultimately only your own testing can establish that.

  • Explain plan on Update statement in function

    All,
    I have an update statement in a function and my explain plan shows:
    "Optimizer"     "Cost"     "Cardinality"     "Bytes"     
    "UPDATE STATEMENT"     "ALL_ROWS"     "2"     "1"     "7"     
    "UPDATE user.<table_name>"     ""     ""     ""     ""     
    "INDEX(UNIQUE SCAN) <table_name>.<PK_column_cons>"     "ANALYZED"     "1"     "1"     "7"
    Filtering is on index unique column, but cost is 1 what does that mean?
    do i need to change my update statement in function?
    Any ideas?
    Regards,
    ~ORA

    The cost is the optimizer's measure of how much effort it will take to execute the statement. For any statement the optimizer will evaluate a number of execution plans and choose the one with the lowest cost. I wouldn't worry too much about what it actually "means". However if you want to understand this subject in a lot more detail I would recommend the book Cost-Based Oracle Fundamentals by Jonathan Lewis.
    For your update statement the optimizer has chosen to access a single row by the primary key index, which is probably good enough, so you should not need to change it.
    The only faster way to access the data would be to use the row's ROWID directly. You would need to have fetched this explicitly in a previous SELECT statement, or you could use it implicitly with the WHERE CURRENT OF syntax for a cursor opened with FOR UPDATE.

  • Financial statement with Functional Area

    Dear Experts,
    We recently implemented SAP in our company.
    One problem we have is that our Financial statements are just on GL, our Management wants to see the Financial statement break up by departments (Cost centers) & Projects.
    I beleive that this is possible through Functional areas concept, but I don't know completely on how to configure & maintain Functional areas in order to get the Financial statements with Functional area.
    Please guide me a complete configuration step.
    Many Thanks.
    Sunil.

    Thanks Alice, but I partially disagree with your input.
    What is the benefit of maintaining Functional area in the Cost center master data then.
    I have seen some slides of Financial statements with Functional are break up by Cost center categories.
    Please give more idea on this.
    Thanks
    Sunil

  • Can we do Dml statements on materialize views

    I want to know can we do Dml statements on materialize views .If yes, how

    Can you? Maybe. Depends on how you created the materialized view. Should you? Maybe. Are you running a multi-master environment? Or are you using materialized views for one-way replication? If you are doing one-way replication, do you want your DML changes to be retained beyond the next refresh of the materialized view?
    Justin

  • Golden Gate - DML statements are not replicated to target database

    Hi,
    Testing Environment
    Source:
    OS: RHEL 4.6, Database: 11gR2, Golden Gate 10.4, ASM
    extract ext1
    connection to database
    userid ggate, password qwerty
    hostname and port for trail
    rmthost win2003, mgrport 7800
    path and name for trial
    rmttrail C:\app\admin\GOLDENGATE\dirdat\lt
    EXTTRAIL /u01/oracle/goldengate/dirdat/lt
    --TRANLOGOPTIONS ASMUSER SYS@ASM, ASMPASSWORD sys ALTARCHIVELOGDEST /u03/app/arch/ORCL/archivelog
    --DDL support
    ddl include mapped objname sender.*;
    --DML
    table sender.*;
    Target:
    OS: Windows 2003, Database: 11gR2, Golden Gate 10.4
    --replicate group
    replicat rep1
    --source and target defintions
    ASSUMETARGETDEFS
    --target database login
    userid ggate, password ggate
    --file for discared transaction
    discardfile C:\app\admin\GOLDENGATE\discard\rep1_disc.txt, append, megabytes 10
    --ddl support
    DDL
    --specifying table mapping
    map sender.* ,target receiver.* ;
    I've Successfully setup Oracle Golden Gate test environment as above.
    DDL statements are replicating successfully to target database.
    while DML statements are not being replicated to target database.
    Pl. try to solve the problem
    Regards,
    Edited by: Vihang Astik on Jul 2, 2010 2:33 PM

    Almost ok but how you will handle the overlapping (transactions captured by expdp & captured by Extract too) of transactions for the new table ?
    Metalink doc ID 1332674.1 has the complete steps. Follow the "without HANDLECOLLISIONS" approach.

  • How to monitor DML statements

    Hi pals,
    I want to know how i can monitor DML statements, i can able to monitor select statments but don't DML statements, is there any way or script in following format:
    Executer,Statement,%Completed,%left,Exec_Time,Time_left
    Where
    Executer is a user who runs the statement
    Statement which statement runs
    %completed how much DML operation completed
    %left how much DML operation left
    Exec_Time elapsed time
    time_left how much time remaining in complete operation
    I really apperciate you pals if you can give me some idea how this can be possible??
    Thanks in advance
    Hassan Khan

    Hi,
    These info can be found in V$SESSION_LOGOPS. But the view isn't populated for every query and sometimes it's a bit weird (I actually had queries that ouput 290% of "work" - parallel query side effect). Also notice that this is for long ops, and not everything will be reported there.
    HTH,
    Yoann.

  • How to Split ddl or dml statement

    Hi guys,
    i'm using oracle 11.2
    i've the following question.
    i've a string that can contains multiple ddl or dml statement and i need to split them in more statement.
    i.e. i can have a string like the below and i need 2 string each one with a statement:
    insert into TEST_KIT_USER1.table1 values (1,'a');
    insert into TEST_KIT_USER1.table1 values (2,'b');
    otherwise i can have a string like the below and i need 2 string each one with a statement:
    create table TEST_KIT_USER1.table2
    name char(10),
    surname CHAR(10 BYTE)
    create table TEST_KIT_USER1.table3
    id number,
    description CHAR(10 BYTE)
    is there a simple way to do this?

    Have you tried using iMovie?
    I know that iMovie HD '06 can do this, I'm not sure if '08 can.
    If you have iLife '08, you can download iMovie HD '06 from apple's site here.
    Good luck!

  • Constructing Database Update DML Statements

    This is a very common problem I am sure but want to know how others handle it. I am creating a web application via Servlets and JSPs. I am working with Oracle 10g.
    Here's the problem/question.
    When I present an html form to a user to update an existing record, how do I know what has changed in the record to create the dml statement? I could just update the entire record with the values supplied via the POST data on submit but that does not seem right since maybe only 1 out of 10 fields actually changed. This would also write needless audit and logging information to the database. I have thought about comparing the Request parameters sent with the post with the original java bean used to populate the form in the first place by adding it back to the request as an attribute. Is this the only way to do it or is there a better way?
    Thanks everyone,
    -Brian

    What database drivers are you using? I recall there being some bug in
    sp2 that caused delayed transaction commits for a very specific
    combination of transaction settings and database drivers.
    I think it was third-party type II Oracle drivers and local
    transactions, but I'm not sure.
    In any case, I'd contact support as there is a patch available.
    David
    Gurjit wrote:
    Hi all,
    I have posted something of this sort earlier too. The problem is that
    the database is not reflecting what has been updated using queries from the
    application.
    THe structure of the application is as follows.
    DB = Oracel 8.1.6
    Web Server = iPlanet 4.0
    App Server = iPlanet 6.0 sp2
    The database is connected to via the EJB's. No Database transactions are
    being used except for Bean transactions which are container managed. The
    setAutoCommit flag is set to true. Each query is a transaction. The jsp's
    call these ejb's through wrapper classes. As stated earlier the database
    updates (Inserts, update, delete statements) are not getting reflected in
    the database immediately. The updates happen after a gap of about 7-10
    minutes. Why is this sort of behaviour coming up. This is almost like batch
    updates happening on the database. Is there a setting in IPlanet for
    removing this kind of problem.
    Regards,
    Gurjit

Maybe you are looking for