run immediately with bind sql collection

Hi, I'm working on an implementation immediate execution where to use a binding that is to an SQL array type. The type of table is produced by be transmitted from an array of Java.

So it looks like:

execute immediate mystatement using myarray;

"mystatement" contains a forall command. I thought that it wouldn't work, because of limitations in the use of tables to link with dynamic sql, but it does. Also, I see in the Oracle documentation that allows dynamic sql to binds to SQL collection types. Am I so I read the documentation correctly, please, that this is a correct use of the immediate execution with a SQL collection?

I tested on 10.2 and 11 g

Thank you

David

979394 wrote:
Hi, I'm working on an implementation immediate execution where to use a binding that is to an SQL array type. The type of table is produced by be transmitted from an array of Java.

So it looks like:

execute immediate mystatement using myarray;

"mystatement" contains a forall command. I thought that it wouldn't work, because of limitations in the use of tables to link with dynamic sql, but it does. Also, I see in the Oracle documentation that allows dynamic sql to binds to SQL collection types. Am I so I read the documentation correctly, please, that this is a correct use of the immediate execution with a SQL collection?

I tested on 10.2 and 11 g

Thank you

David

Welcome to the Forum!
Here is a small demonstration to what Solomon said: (not the best of examples I would say, but should provide an indication)

drop table depts;
drop table emps;
drop type type_depts;

create table depts (dept_no   number, dept_name varchar2(25), loc varchar2(10));

create table emps (empno  number, name varchar2(25), dept_no  number, salary number);

create or replace type type_depts is table of number;

insert into depts values (10, 'ABC', '111');
insert into depts values (20, 'ABC1', '111');
insert into depts values (30, 'ABC2', '111');
insert into depts values (40, 'ABC3', '111');
insert into depts values (50, 'ABC4', '111');

insert into emps values (1, 'PQR', 10, 100);
insert into emps values (2, 'PQR1', 20, 100);
insert into emps values (3, 'PQR2', 30, 100);
insert into emps values (4, 'PQR3', 10, 100);
insert into emps values (5, 'PQR4', 30, 100);
insert into emps values (6, 'PQR5', 10, 100);
insert into emps values (7, 'PQR6', 40, 100);
insert into emps values (8, 'PQR7', 80, 100);

commit;

/* Block to find a DEPT_NO in EMP that does not exist in DEPT table */
set serveroutput on;
declare
  dept    type_depts;

  type type_emp is table of pls_integer index by pls_integer;
  emp     type_emp;

  idx     pls_integer;
begin
  select dept_no
    bulk collect into dept
    from depts;

  execute immediate 'select empno from emps where dept_no not in (select column_value from table(:1))' bulk collect into emp using dept;

  for i in emp.first..emp.last loop
    dbms_output.put_line('Emp No:- ' || emp(i));
  end loop;
end;

anonymous block completed
Emp No:- 8

As you say, the 'mystatement"contains the FORALL statement; Is the name of the Table known at runtime, or it is passed as an additional parameter? If the Table name is known, then, IMO, there is no any dynamic SQL. A FORALL statement should be enough.

Please provide details. In addition, please read {message identifier: = 9360002}.

Tags: Database

Similar Questions

  • run immediately with the help of clause

    Hey, if we can link the oracle parameters in the execute immediate statement why Oracle is having using the clause to it.
    What is the use of the use of this clause.

    When you say "bind" I think you mean something other than what most people hear when they hear "bind" in the context of variables.

    Yes we can include variables in a string dynamically executed like this:

    execute immediate 'select * from emp where deptno = '|| v_deptno;
    

    However, it actually treats the variable a hardcoded in a literal string value. The statement is difficult analyzed whenever it is executed.

    Whereas, the USING clause can specify placeholders in code and assign the values through the USING clause like this:

    execute immediate 'select * from emp where deptno = :1' using v_deptno;
    

    Now, the statement is executed with a variable binding, which means that it is only parsed hard in the first inning. It is of the most efficcient for code that is run a lot.

    Cheers, APC

  • using indexes on varchar confusion with pl/sql collections

    Hi, I seek to learn the mechanics behind the collections and have done ok so far until I came across you try using the index of varchar.

    I use the following code: -.
    declare
      type address_lines_tab is table of varchar2(50)
        index by pls_integer;
    
      type address_tab is table of address_lines_tab
        index by varchar(40);
    
      type student_rec is record(
        first     varchar2(40),
        last      varchar2(40),
        address   address_tab
      );
    
      type student_tab is table of student_rec
        index by pls_integer;
    
      student   student_tab;
      i         number       := 0;
      v         varchar2(20);
      x         number       := 0;
    begin
      student(1).first := 'mike';
      student(1).last := 'jones';
      student(1).address('home')(1) := 'the manor';
      student(1).address('home')(2) := 'london';
      student(1).address('home')(3) := 'w12 4kf';
      student(1).address('term')(1) := '5 university';
      student(1).address('term')(2) := 'plymouth';
      student(1).address('term')(3) := 'pl22da';
      student(2).first := 'helen';
      student(2).last := 'roots';
      student(2).address('home')(1) := '1 little lane';
      student(2).address('home')(2) := 'hull';
      student(2).address('home')(3) := 'h45 4fd';
      student(2).address('term')(1) := '3 university';
      student(2).address('term')(2) := 'plymouth';
      student(2).address('term')(3) := 'pl22da';
    
      for student_no in student.first .. student.last
      loop
        dbms_output.put_line(   'STUDNET NAME:'
                             || student(student_no).first
                             || ' '
                             || student(student_no).last);
    
        for add_type in
          student(student_no).address.first .. student(student_no).address.last
        loop
          dbms_output.put_line(student(student_no).address);
          for add_line in
            student(student_no).address(add_type).first .. student(student_no).address(add_type).last
          loop
            dbms_output.put_line(student(student_no).address(add_type)(add_line));
          end loop;
        end loop;
      end loop;
    end;
    the problem I have is in the second loop when trying to display 2 different types of address (IE home and term).

    because its indexed by a varchar, I get the following error: -.
    ORA-06502: PL/SQL: digital or value error: character of number conversion error

    How can I get around that, when a loop in the associative arrays that are indexed by varchar?

    Thank you very much

    It's the exit, I expect to see:-
    STUDNET NAME:mike jones
    HOME
    the manor
    london
    w12 4kf
    TERM
    5 university
    plymouth
    pl22da
    STUDNET NAME:helen roots
    HOME
    1 little lane
    hull
    h45 4fd
    TERM
    3 university
    plymouth
    pl22da

    Hello..

    The problem is tat you can not use a "student (student_no).address.first" and "student (student_no).address.last" in a loop; because they are varchar2 index...

    Yo can use, something like that...

        nuStudent := student(student_no).address.count;
        for add_type in 1 ..nuStudent 
    
  • Create directory and run immediately in pl/sql

    Hello


    Is could someone please tell me how I can run the following command in a PL/SQL procedure:


    create the directory DIR0001 as 'c:\data\testdir ';


    Any suggestions are greatly appreciated.


    Long life and prosperity.

    Here is the example of a PL/SQL block:

    begin
      execute immediate 'create directory DIR0001 as ''c:\data\testdir''';
    end;
    /
    
    anonymous block completed
    
  • PL/SQL collection headaches

    Hello guys,.

    Thought maybe you could help simple here, I write a procedure to validate a Tin CAN.

    Basic rules are

    A Tin CAN has exactly eleven digits.
    Among the ten first exactly two digits are the same (the others are all different).
    -And then some - check digit - check module.

    The control module that brings me to put all the numbers in a table. So far so good.
    Then, I need to check "exactly two. Now that I have them in a table, I had in my mind that I could use this table. But I'm NOT in good terms with PL/SQL collections ;)

    I've been watching of multiset, but doesn't seem not that it is, or?

    So far I did it in SQL, but which seems to repeat what I just did, so I thought if a solution using the table. (I know how to do these two things in a single SQL, but I fear that no one here will understand)

    This is my procedure (please do not pay attention to the management of exceptions)
    SQL> CREATE OR REPLACE PROCEDURE validate_otn (in_tin VARCHAR2) IS
      TYPE tin_t IS VARRAY (11) OF PLS_INTEGER NOT NULL;
    
      v_digits       tin_t := tin_t (0);
      v_count        NUMBER;
      v_count_dist   NUMBER;
    BEGIN
      --
      -- Verify that we have numeric, non-null input
      --
      IF TO_NUMBER (in_tin) IS NULL THEN
        RETURN;
      END IF;
    
      ---------
      -- Verify that we have exactly the right number of digits
      ---------
      IF LENGTH (in_tin) != v_digits.LIMIT THEN
        RAISE VALUE_ERROR;
      END IF;
    
      ---------
      -- Put all digits into array
      ---------
      SELECT     SUBSTR (in_tin,
                         LEVEL,
                         1
                        )
                   x
      BULK       COLLECT INTO v_digits
      FROM       DUAL
      CONNECT BY LEVEL <= LENGTH (in_tin);
    
      ---------
      -- Verify exactly one digit used twice, among first ten
      ---------
      SELECT COUNT (x),
             COUNT (DISTINCT x)
      INTO   v_count,
             v_count_dist
      FROM   (SELECT     SUBSTR (in_tin,
                                 LEVEL,
                                 1
                                )
                           x
              FROM       DUAL
              CONNECT BY LEVEL <= LENGTH (in_tin) - 1);
    
      IF v_count - v_count_dist != 1 THEN
        RAISE VALUE_ERROR;
      END IF;
    --
    -- Lots more to come, including some modulo checks, etc
    --
    EXCEPTION
      WHEN OTHERS THEN
        DBMS_OUTPUT.put_line (SQLERRM);
        RAISE VALUE_ERROR;
    END validate_otn;
    /
    Procedure created.
    
    SQL> show errors
    No errors.
    
    SQL> select banner from v$version;
    
    BANNER                                                          
    ----------------------------------------------------------------
    Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
    PL/SQL Release 10.2.0.3.0 - Production                          
    CORE     10.2.0.3.0     Production                                      
    TNS for Linux: Version 10.2.0.3.0 - Production                  
    NLSRTL Version 10.2.0.3.0 - Production                          
    
    5 rows selected.
    I'm looking to replace it with Collection/full year:
      SELECT COUNT (x),
             COUNT (DISTINCT x)
      INTO   v_count,
             v_count_dist
      FROM   (SELECT     SUBSTR (in_tin,
                                 LEVEL,
                                 1
                                )
                           x
              FROM       DUAL
              CONNECT BY LEVEL <= LENGTH (in_tin) - 1);
    Any ideas?


    I don't want to follow during a casting of hours - commuting.


    Best regards
    Peter

    Returns The VALUE of distinct values, for example:

    DECLARE
       p_tin CONSTANT sys.ku$_objnumset := sys.ku$_objnumset(1,2,2,3,4,5,6,7,8,9,10);
    BEGIN
       DBMS_OUTPUT.PUT_LINE(p_tin.count || ' elements');
       DBMS_OUTPUT.PUT_LINE(SET(p_tin).count || ' distinct elements');
    END;
    
    11 elements
    10 distinct elements
    

    You can probably use it somehow.

    Note that it needs correct nested table collections, not varrays.

  • problem with bind variables in the SQL query view object

    Hi all

    I use JDev 11.1.2.4.0.

    I have a problem with bind variables in the SQL query view object.

    This is my original SQL

    SELECT sum(t.TIME) , t.legertype_id
    FROM LEDGER t
    WHERE t.nctuser_id = '20022' 
          AND to_char(t.insertdate,'YYYYMMDD') in ('20130930','20130929')
    group by t.legertype_id
    

    In my view .xml object query tab, I am writing this

    SELECT sum(t.TIME) , t.legertype_id
    FROM LEDGER t
    WHERE   t.nctuser_id = '20022'
        AND to_char(t.insertdate,'YYYYMMDD') in :dddd
    group by t.legertype_id
    

    Davis here is a variable of Type liaison: String, updatable and necessary.

    I try to deal with Davis as ('20130930 ', ' 20130929') hoping the view object, run as my original SQL.

    But failed. The view object retrieves 0 line after that I run.

    Why?

    Thank you! ('2original SQL0130930', '20130929') ('20130930 ', ' 20130929')

    A variable binding cannot be used as this is why you must use years table. Check decompilation binary ADF: using oracle.jbo.domain.Array with ViewCriteria to see a solution.

    Timo

  • How can I create VI with inputs that run immediately when the update?

    I'm using LabView for controlling stepper motors. I would create a VI with a front panel that has 4 arrows, 2 per engine. My goal is to be able to run the VI and then press a button to move the engine.

    I created separate VI for each funcition of engines - one vi to set current operations, to determine the current travel, another to move up by a certain amount and so on. Work of these vi and I can move and adjust engines, but only by running separate VI.

    How can I combine them into a single VI and make them run to the pressure of a button or the change of a property? An example would be to establish a new current holding company and place the operation current vi run immediately and send the order to the engine. Then continue to press the arrow keys without having to hit 'run' on an another vi.

    Thank you very much


  • run immediately fails with the error

    The following code generates the error and I can not understand what the problem is:

    SET SERVEROUTPUT ON;

    declare

    Val number (21);

    s_sql varchar2 (2000);

    Start

    s_sql: = q '{select last_number in the Vale of all_sequences where sequence_owner = 'SST' and sequence_name = "ADDRESS_SEQ"}';

    Dbms_output.put_line ('sql 1 ' | s_sql);

    run immediately s_sql;

    end;


    Error report:

    ORA-00905: lack of keyword

    ORA-06512: at line 7

    00905 00000 - 'lack the key word'

    * Cause:

    * Action:

    select last_number SQL 1 in val all_sequences where sequence_owner = 'SST' and sequence_name = "ADDRESS_SEQ."

    The error is strange since

    Select last_number in the all_sequences where sequence_owner = 'SST' and sequence_name = "ADDRESS_SEQ."

    is a valid instruction

    Although I see no need for SQL dynamic in this case, in general, you must provide the vatiable to receive the value of the select statement outside the immediate execution.  More like:

    s_sql: = q '{select last_number in the all_sequences where sequence_owner = 'SST' and sequence_name = "ADDRESS_SEQ"}';

    execute immediate s_sql in val

    John

  • using where clause with value to hardcode in run immediately

    Dear Experts, I use below in the stored procedure make exception.

    RUN IMMEDIATELY "REMOVE CC. TB WHERE COL ='HG ";

    When the collar is varchar2 (30) DC. TB

    Please guide how to use above the statement in the stored procedure


    Thank you

    DBA wrote:
    Dear Experts, I use below in the stored procedure make exception.

    RUN IMMEDIATELY "REMOVE CC. TB WHERE COL ='HG ";

    When the collar is varchar2 (30) DC. TB

    Please guide how to use above the statement in the stored procedure

    Thank you

    Why you use dynamic SQL? DELETE statement is a DML statement and its valid inside a PL/SQL block.

    So, you can remove the immediate execution and write your DELETE statement directly.

    begin
      delete from cc.tb where col = 'HG';
    end;
    
  • Compare with variable binding sql stored proc vs

    I have a complicated logic coded in the two sql with variables and stored procedure I need to compare the performance of the two and decide which binding. with sql, I think I must watch the plan exec etc. and get metrics. How can I do to stored proc

    user8798946 wrote:
    the sql will be a plsql function. I have to choose wheter I implemting the sql code in the plsql or a version of sql plsql. hope that what I say makes sense.

    Are you meaning "I can write an SQL statement in a procedure, or I can PL/SQL code to do the same thing as the SQL statement and the loop via a slider?

    If so, then go with the SQL statement.

  • Run immediately by using bind variable in plsql

    Hello

    I have the procedure which has the status valid .

    SQL > create or replace PROCEDURE (p_CLGProcExcl_s_by_Db_Name_T)

    2 v_Database_name in VARCHAR2 DEFAULT NULL,

    3 cv_1 SYS_REFCURSOR to)

    4

    5 AS

    6 v_SQL VARCHAR2 (2000);

    7    /*

    8. check the table of CLGProcExclusions for columns (lke inserts\updates\deletes) and procs which do not return.  This will prevent

    9 the clg.exe to try to run all these without reason (since all its trying to do is determine what than the willreturn procs).

    10 that this saving thousands back and forth to the DB.

    11 However, the unfavorable to DELETE in the beging erases all procedures that may have been changed since the last time

    CLG 12 determined that it should be excluded column generation routines.

    13 * /

    BEGIN 14

    15 v_SQL: = ' delete object, e CLGProcExclusions e I

    where the 16

    17 i.owner = "' | v_Database_name | " '

    18 AND i.object_name = e.Procedure_Name

    19 AND i.LAST_DDL_TIME > e.CreatedDate';

    20 execute immediate v_SQL using v_Database_name;

    21 OPEN cv_1 to SELECT v_Database_name Database_Name, PROCEDURE_NAME OF CLGProcExclusions WHERE Database_Name is v_Database_name;.

    22 END;

    I have test, run this procedure using SQL developer tool, but encounter following error:

    ORA-00933: SQL not correctly completed command.

    ORA-06512: at "DBCC_CLG. P_CLGPROCEXCL_S_BY_DB_NAME_T', line 20

    ORA-06512: at line 7

    Recognizing the help / suggestion on this.

    Thank you.

    Why use dynamic SQL statements? You can simply do this.

    create or replace procedure p_clgprocexcl_s_by_db_name_t
    (
        v_database_name in   varchar2 default null
      , cv_1            out  sys_refcursor
    )
    as
      v_sql varchar2(2000);
    begin
      delete
        from clgprocexclusions a
       where exists
             (
                select null
                  from all_objects o
                 where o.owner          = v_database_name
                   and o.object_name    = a.procedure_name
                   and o.last_ddl_time  > a.createddate
             );
    
      open cv_1
      for
      select v_database_name database_name
           , procedure_name
        from clgprocexclusions
       where database_name = v_database_name ;
    end;
    
  • ONE ERROR: run immediately (p_sql) return to p_id;

    Has written a simple procedure:

    procedure p_test)
    P_ID number,
    p_sql in varchar2
    *)*
    is
    Start
    run immediately (p_sql) return to p_id;
    end;

    Now, test it:

    declare
    P_ID number;
    p_sql varchar2 (2000): = ' insert into test1 (pk, str) values (1, "aaa")';
    Start
    pkg_utility.sp_save_without_blob (p_id, p_sql);
    dbms_output.put_line ('p_id' | p_id);
    end;


    The problem:
    Without the 'back in p_id' statement, the sql code can be run successfully. But with the "p_id return', an error occurred:

    ORA-20999: unexpected error when insert into test1 (pk, str) values (1, 'aaa')
    ORA-01006: there is no bind variable


    What I've done wrong? and how do I solve the problem?


    Thank you for helping.

    You're not saying 'what' you try to return.

    See the examples in the doc of PL/SQL
    http://docs.Oracle.com/CD/B28359_01/AppDev.111/b28370/Collections.htm#BABHDGIG
    >
    Example 5-52, using the RETURN IN the Clause with a Record

    DECLARE
    RECORD IS of TYPE EmpRec (last_name, employees.last_name%TYPE,
    salary employees.salary%TYPE);
    method EmpRec;
    emp_id NUMBER: = 100;
    BEGIN
    UPDATE employees SET salary = salary * 1.1
    WHERE employee_id = emp_id
    RETURN last_name, salary INTO method;
    DBMS_OUTPUT. PUT_LINE
    ("Just give a stimulus to ' | emp_info.last_name |)
    ', which now makes | emp_info.salary);
    ROLLBACK;
    END;
    /

  • Run immediately produced confusing errors

    I have a procedure that removes the selected rows of a table based on a dynamic WHERE condition. The column values are of type VARCHAR2. Using SQL Developer debug mode, I put the finger on the line of boredom to the Execute Immediate statement that produces a ' ORA-00907: lack the right parenthesis "error with or the other of these channels:

    v_sql: = ' DELETE FROM schema.table WHERE (column1 = "Value1" GOLD column1 = "Value2" GOLD column1 = "Value3" ") AND (column2 ="value4")';
    v_sql: = ' REMOVE FROM schema.table WHERE column1 ("Value1", "Value2", "value3") AND column2 IN ("value4")';
    Immediately run v_sql;

    Still in PL/SQL, the same lines running without error:

    DELETE FROM schema.table WHERE (column1 = 'value1' OR column1 = 'value2' GOLD column1 = 'value3') AND (column2 = 'value4');
    REMOVE FROM schema.table WHERE column1 IN ('value1', 'value2', "value3") AND column2 IN ("value4");

    I can even run the same instructions in an anonymous block without error:

    Set serveroutput on
    DECLARE
    v_cnt NUMBER;
    v_sql varchar2 (2000);
    BEGIN
    v_sql: = ' REMOVE FROM schema.table WHERE column1 ("Value1", "Value2", "value3") AND column2 IN ("value4")';
    Immediately run v_sql;
    Run immediately "select count (*) table" in v_cnt;
    dbms_output.put_line (v_cnt);
    Rollback;
    Run immediately "select count (*) table" in v_cnt;
    dbms_output.put_line (v_cnt);
    END;
    /
    I must be blind because neither dynaminc SQL statement needs an another right parenthesis. I even added one to test (same error ORA-00907!). I even tried this

    v_sql: = "DELETE FROM schema.table WHERE ((column1 = '' valeur1 '') OR (column1 = 'value2'))';"

    (same error ORA-00907!)

    I even tried to run the same without parentheses (ORA-00900: invalid SQL statement error). I guess the problem is the single quotes.

    Just for fun I tried that as well

    EXECUTE IMMEDIATE chr (39) | v_sql | Chr (39);

    and, as I suspected, I got the error "invalid SQL statement.

    I even tried this

    EXECUTE IMMEDIATE chr (39) | v_sql;

    and of course I got an ' ORA-01756: not correctly completed string "error.

    When I tried this

    EXECUTE IMMEDIATE v_sql | Chr (39);

    the same error "missing right parenthesis" surfaced.

    I've never had this problem with the Execute Immediate statements before. Unless someone can offer a penny to buy a clue, looks like I have no choice but to make the Immediate Execute in a loop FORALL to each WHERE condition using a variable binding for the value of the column.

    Your procedure changed a bit:
    Removed options CHR (39) and 'DELETE FROM' has been added at the beginning of your v_sql variable.

    CREATE OR REPLACE PROCEDURE delete_rows_proc (
       p_table        IN   VARCHAR2,
       p_schema       IN   VARCHAR2,
       p_columns      IN   VARCHAR2,
       p_col_values   IN   VARCHAR2,
       p_col_delim    IN   VARCHAR2,
       p_val_delim    IN   VARCHAR2
    )
    AS
    /*
    generic procedure to delete selected rows from a table
    
    INPUT PARAMETERS:
    1) P_TABLE (required): table name
    2) P_SCHEMA (required): schema name
    3) P_COLUMNS (required): a delimited string of character type column names
    4) P_COL_VALUES (required): a delimited string of column values
    (must match P_COLUMNS in delimited sequence and number);
    5) P_COL_DELIM (required): column delimiter for P_COLUMNS and P_COL_VALUES;
    must be a keyboard character delimiter that DOES NOT appear elsewhere in the column values;
    6) P_VAL_DELIM (required): column value delimiter for P_COL_VALUES;
    must be a keyboard character delimiter that DOES NOT appear elsewhere in the column values;
    must be different from P_COL_DELIM
    
    NOTE: if P_COLUMNS is not null then P_COL_VALUES cannot be null
    
    example of P_COLUMNS and P_COL_VALUES:
    P_COLUMNS = 'column1#column2'
    P_COL_VALUES = 'value1,value2#value4'
    P_COL_DELIM = '#'
    P_VAL_DELIM = ','
    deletes rows WHERE ((column1 = 'value1') OR (column1 = 'value2') AND (column2= 'value4')
    */
       v_sql              VARCHAR2 (4000);
       v_where_clause     VARCHAR2 (3900);
       v_from_clause      VARCHAR2 (200);
       v_col              VARCHAR2 (50);
       v_txt              VARCHAR2 (1000);
       i_col_delim_cnt1   INTEGER         := 0;
       i_col_delim_cnt2   INTEGER         := 0;
       x_loop_cnt         INTEGER         := 0;
       y_loop_cnt         INTEGER         := 0;
       delim_txt          VARCHAR2 (1000);
       i_delim_cnt        INTEGER         := 0;
       i_cnt              INTEGER;
       e_delim_not_eq     EXCEPTION;
    
       FUNCTION assemble_or_str (v_col IN VARCHAR2, v_txt IN VARCHAR2)
          RETURN VARCHAR2
       IS
          v_return   VARCHAR2 (1000) := '';
       BEGIN
          IF LENGTH (v_col) > 0
          THEN
    -- add opening parenthesis
             v_return := v_return || '(';
          END IF;
    
          FOR i IN 1 .. i_delim_cnt + 1
          LOOP
             v_return :=
                   v_return
                || '('
                || v_col
                || ' = '
                || CHR (39)
                || get_delimited_text (v_txt, p_val_delim, i)
                || CHR (39)
                || ')';
    
             IF i < i_delim_cnt + 1
             THEN
                v_return := v_return || ' OR ';
             END IF;
          END LOOP;
    
          IF LENGTH (v_return) > 0
          THEN
    -- add closing parenthesis
             v_return := v_return || ')';
          END IF;
    
    --dbms_output.put_line('v_return=' || v_return);
          RETURN v_return;
    -- e.g., v_return = '((column1 = 'value1') OR (column1 = 'value2'))''
       END;
    BEGIN
       IF p_columns IS NOT NULL AND p_col_values IS NOT NULL
       THEN
    -- count the column delimiter in both parameters
          i_col_delim_cnt1 :=
                LENGTH (p_columns)
                - LENGTH (REPLACE (p_columns, p_col_delim, ''));
          i_col_delim_cnt2 :=
               LENGTH (p_col_values)
             - LENGTH (REPLACE (p_col_values, p_col_delim, ''));
    
          IF i_col_delim_cnt1 = i_col_delim_cnt2
          THEN
    -- if both strings have the same # of column delimiters
    -- assemble the where clause
             IF i_col_delim_cnt1 = 0
             THEN
    -- for single column
    -- find how many delimited values are in P_COL_VALUES
                i_delim_cnt :=
                     LENGTH (p_col_values)
                   - LENGTH (REPLACE (p_col_values, p_val_delim, ''));
    
                IF i_delim_cnt > 0
                THEN
    --dbms_output.put_line('i_delim_cnt = ' || i_delim_cnt);
    -- for single column with multiple column values
                   v_where_clause := assemble_or_str (p_columns, p_col_values);
                ELSE
    -- for single column with single column value
                   v_where_clause :=
                        p_columns || ' = ' || CHR (39) || p_col_values
                        || CHR (39);
                END IF;
             ELSE
    -- for multiple columns
                x_loop_cnt := i_col_delim_cnt1 + 1;
    
                FOR x IN 1 .. x_loop_cnt
                LOOP
    -- for each column
                   v_col := get_delimited_text (p_columns, p_col_delim, x);
                   v_txt := get_delimited_text (p_col_values, p_col_delim, x);
    --dbms_output.put_line('loop '||x||': vcol='||v_col);
    --dbms_output.put_line('loop '||x||': v_txt='||v_txt);
                   i_delim_cnt :=
                        LENGTH (v_txt)
                        - LENGTH (REPLACE (v_txt, p_val_delim, ''));
    
                   IF i_delim_cnt > 0
                   THEN
                      v_where_clause :=
                                 v_where_clause || assemble_or_str (v_col, v_txt);
                   ELSE
                      v_where_clause :=
                            v_where_clause
                         || '('
                         || v_col
                         || ' = '
                         || CHR (39)
                         || v_txt
                         || CHR (39)
                         || ')';
                   END IF;
    
                   IF x < x_loop_cnt
                   THEN
                      v_where_clause := v_where_clause || ' AND ';
                   END IF;
                END LOOP;
             END IF;
          ELSE
    -- if i_col_delim_cnt1 i_col_delim_cnt2
    -- raise exception
             RAISE e_delim_not_eq;
          END IF;
       END IF;
    
    -- assemble the dynamic SQL statement
       v_from_clause :=
                      (CASE p_schema
                          WHEN NULL
                             THEN ''
                          ELSE p_schema || '.'
                       END) || p_table;
       v_where_clause :=
           (CASE
               WHEN v_where_clause IS NULL
                  THEN ''
               ELSE ' WHERE ' || v_where_clause
            END
           );
       v_sql := 'DELETE FROM ' || v_from_clause || v_where_clause; -- Added 'DELETE FROM '
       DBMS_OUTPUT.put_line (v_sql);
    
    -- test clauses separately
    -- EXECUTE IMMEDIATE 'DELETE FROM '|| v_from_clause;
    -- EXECUTE IMMEDIATE 'DELETE FROM '|| v_from_clause || v_where_clause;
       EXECUTE IMMEDIATE v_sql;
    
       EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || p_table
                    INTO i_cnt;
    
       DBMS_OUTPUT.put_line ('i_cnt = ' || i_cnt);
       ROLLBACK;
    
       EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || p_table
                    INTO i_cnt;
    
       DBMS_OUTPUT.put_line ('i_cnt = ' || i_cnt);
    --commit;
    EXCEPTION
       WHEN e_delim_not_eq
       THEN
          DBMS_OUTPUT.put_line
             ('ERROR: delimiter number mismatch! A column delimiter was found in the P_COLUMNS string and/or the P_COL_VALUES string; however, the number of column delimiters between the two string does not match. Process cannot be completed.'
             );
    -- WHEN OTHERS THEN
    -- DBMS_OUTPUT.PUT_LINE('Error in DELETE_ROWS_PROC procedure!');
    -- DBMS_OUTPUT.PUT_LINE(SQLERRM);
    END delete_rows_proc;
    /
    
    SQL> SELECT * FROM TABLE1
      2  /
    
    COLUMN1                                            COLUMN2
    -------------------------------------------------- -------------------------------------------------
    value1                                             value3
    value2                                             value3
    value3                                             value3
    value4                                             value3
    value1                                             value4
    value2                                             value4
    value3                                             value4
    value4                                             value4
    
    8 rows selected.
    
    SQL> exec DELETE_ROWS_PROC('TABLE1', 'SCOTT', 'COLUMN1#COLUMN2', 'value1,value2#value4', '#', ',')
    DELETE FROM SCOTT.TABLE1 WHERE ((COLUMN1 = 'value1') OR (COLUMN1 = 'value2')) AND (COLUMN2 = 'value4
    i_cnt = 6
    i_cnt = 8
    
    PL/SQL procedure successfully completed.
    
    SQL> 
    

    I hope this helps.

    Kind regards
    JO

    Edit: Deleted a wrong comment

  • Run immediately in Oracle 10 g

    Hi, I have a small doubt regarding run immediately.

    According to my knowledge that we use run immediately to the writing of DDL(create,truncate,...) instructions to be executed in the procedure or function.

    But I saw in my organization, some of the senior people (already left organization) used to write the inserts, updates, deletes in will also run immediate even there is not much involved dynamic logic.

    But as per my knowledge run immediately can be misused by most pirates with SQL injection, I suppose!

    Is there some reason they use run immediately instead of writing code directly? Or is there an advantage in writing like this. ???

    Delivery immediate to create tables and another using DDL is fundamentally undesirable and should be avoided at all costs.
    Using run immediately you seem to exhibit, avoid too. Seniors were apparently not aware of the purpose of PL/SQL and the inconvenience of immediate execution.
    If I could vote to remove execute immediate PL/SQL, I would immediately in favour, especially in the packages, procedures and functions, as they are saved, which means pre-built.

    -----------
    Sybrand Bakker
    Senior Oracle DBA

  • Using XQuery with PL/SQL, link the Variable

    I am only able to find an example of use of xquery with pl/sql.

    [http://www.comp.dit.ie/btierney/oracle11gdoc/appdev.111/b28369/xdb_xquery.htm#CBAEEJDE]

    Why is what they show only using bind variables? It's the only way it should be used, it provides a performance gain more simply by using the crossing clause and a passing beam a PL/SQL variable? I'm looking to implement a solution for my company using Xquery in PL/SQL. I am concerned that these procedures will be called during a flow of the user interface and performance it must be as soon as possible.

    A PL/SQL variable, column, or the output of another operation would be all be equivalent to a connection variable that PL/SQL compilation is concerned. Which would be bad practice would be to build in XQuery with the predicate hardcoded in the XQuery operation whenever the XQuery query has been run.

Maybe you are looking for

  • named extended ACL doesn't work, can you help me?

    The camera I used is 2651xm router and NAT is used to connect my everything inside the LAN (192.168.1.x) to outside internet. A standard ACL was used to block some local host access outside the internet, and it worked fine. My question is, when I cre

  • Not able to re - import images into Lightroom CC

    I use Lightroom CC.  I had a disk failure and had to move all my data on a new disc. Now it does not open these files, but when I try re - import it tells me that they are already in the library.  How can I get LR to re-recoginize the existing data?R

  • ESXi 5.0 is having disconnected the VC frequently

    HelloWe use Vsphere 5.0. We have seen in one of our vcenter that esxi is disconnected again and again.We have done the troubleshooting on this issue below.(1) control access to the network of VC. Found ok.(2) check the availability of esxi. Search ok

  • What is "fade in" and "fade out" opacity?

    What is "bland in" and "fade out" (it's in "applied effects") and how can it be used?

  • Help! All creative Cloud applications crashing on launch!

    Everything was working fine until 2 days ago, and then all of a sudden, Indesign crashed on launch. I tried Photoshop and Illustrator, both crashed the launch.It works on a new MacBook Pro the retina (just a few weeks) OSX Yosemite 10.10.2Looking on