0

When I run

SELECT COUNT(*) 
  INTO l_entry_found 
  FROM hera.hera_user@iam 
 WHERE username = docm.eb_key;

without execute immediate it works.

execute immediate'
      SELECT COUNT(*) INTO l_entry_found FROM hera.hera_user@iam WHERE 
      username = docm.eb_key;';

However throws an ora-00933.

What could be the Problem and how may i solve it? Thanks in advance!

2
  • you can't use select into in dynamic sql Commented Sep 7, 2018 at 13:32
  • 1
    You also need to remove the ; inside your SQL String. Commented Sep 7, 2018 at 13:38

3 Answers 3

2

you can't use select into in dynamic SQL and you do not need a semicolon either

declare
  l_entry number(10);
begin

  execute immediate'
        SELECT COUNT(*) FROM hera.hera_user@iam WHERE 
        username = '''||docm.eb_key||'''' INTO l_entry;
end;
Sign up to request clarification or add additional context in comments.

2 Comments

does every variable inside of the execute immediate Need to be defined there as well? as im now getting an invalid identifier on docm.eb_key
If your select hase more than one column as result then you need a variable for each column
1

You have some issues; say you have a table like

create table someTable(userName varchar2(100))

and a code like :

declare
    someVariable    varchar2(100);
    l_entry_found   number;
begin
    someVariable := 'someName';
    --
    SELECT COUNT(*)
    INTO l_entry_found
    FROM someTable
    WHERE username = someVariable;
end;

If you wat to switch to dynamic SQL, you need to

  • remove the semicolon
  • use bind variables to pass your parameter
  • move the INTO outside the dynamic part

Your code could be:

declare
    someVariable    varchar2(100);
    l_entry_found   number;
begin
    someVariable := 'someName';
    --
    execute immediate 
    'SELECT COUNT(*)
    FROM someTable
    WHERE username = :bindVar'
    into l_entry_found
    using someVariable;
end;

Here I assume that you have a good reason to switch to dynamic SQL, for example, your table name could change based on some parameter; if not, plain SQL is good enough for your task.

2 Comments

The code will be installed in our production, but will only be used on testservers. The DB link .@iam does not exist on production, so having it without dynamic SQL would give us an productive invalid. However my main Problem at this Point is, that i Need a Loop variable inside of the dynamic SQL which i cant use there. The whole Thing is just a small sleeper procedure which does nothing unless waiting for when some data arrived in the .@iam DB. Maybe ill just replace it with a hardwired wait 10 minutes if there is no Workaround for my Problem.
procedure check#hera is l_cnt number := 0; procedure check#docm is l_entry_found number; l_eb_key varchar2(10); begin for docm in (SELECT eb_key from tst_migr$eb_docm) loop l_eb_key := docm.eb_key; execute immediate' SELECT COUNT(*) FROM hera.hera_user@iam WHERE username = l_eb_key' INTO l_entry_found; if l_entry_found = 0 and l_cnt < 10 then dbms_lock.sleep(10); l_cnt := l_cnt + 1; check#docm; end if; end loop; end check#docm; begin check#docm; end check#hera;
0

The EXECUTE IMMEDIATE statement executes a dynamic SQL statement or anonymous PL/SQL block. You can use it to issue SQL statements that cannot be represented directly in PL/SQL, or to build up statements where you do not know all the table names, WHERE clauses, and so on in advance

enter image description here

Continuing with your question

-- Case using 1 output column 'COUNT(*)', 1 filter variable 'eb_key'
DECLARE
  --
  eb_key VARCHAR2(100) := 'something';
  l_entry_found number;
  --
BEGIN 
  execute immediate 'SELECT COUNT(*) FROM hera.hera_user@iam WHERE username = :eb_key;' USING eb_key INTO l_entry_found;
END;

-- Case using 2 output column 'COUNT(*)', 3 filter variable 'eb_key'
DECLARE
  --
  eb_column1 VARCHAR2(100) := 'something';
  eb_column2 VARCHAR2(100) := 'something';
  l_entry_found1 number;
  l_entry_found2 number;
  --
BEGIN 
  execute immediate 'SELECT column1, column2 FROM hera.hera_user@iam WHERE username = :eb_1 AND lastname = :eb_2;' USING eb_column1, eb_column2 INTO l_entry_found1,l_entry_found2;
END;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.