0

I'm trying to run below pl/sql block but I'm getting error:

set serveroutput on
declare
rowBefore            VARCHAR2(32000);
myschema             VARCHAR2(32000) := 'abc';
mytable              VARCHAR2(32000) := 'table1';
param1               VARCHAR2(32000) := 'Tom';
begin
    select count(*) into rowBefore from myschema.mytable where colA = param1;
   --select count(*) into rowBefore from abc.table1  where colA = 'Tom';
    DBMS_OUTPUT.PUT_LINE(rowBefore);
End;

How to correctly use my all parameters into select statement?

Update error:

Error report -
ORA-06550: linia 7, kolumna 50:
PL/SQL: ORA-00942: tabela lub perspektywa nie istnieje
ORA-06550: linia 7, kolumna 5:
PL/SQL: SQL Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:
2
  • Telling us what error you get is usually helpful. But you can’t use variables for object names in a SQL statement - you’d have to use dynamic SQL. There are lots of examples of how to do that around. Commented Jan 10, 2018 at 13:31
  • I update question. the comment select working, but when I'm trying to use parameters I got error Commented Jan 10, 2018 at 13:36

2 Answers 2

4

You can't use a variable as an identifier in a SQL statement. It is looking for a table that is actually called mytable - not one with the value of the variable with that name as you expect. And the same for the schema.

From the documentation:

  1. If the statement is a SELECT statement, the PL/SQL compiler removes the INTO clause.

  2. The PL/SQL compiler sends the statement to the SQL subsystem.

  3. The SQL subsystem checks the syntax of the statement.

If the syntax is incorrect, the compilation of the PL/SQL unit fails. If the syntax is correct, the SQL subsystem determines the names of the tables and tries to resolve the other names in the scope of the SQL statement.

...

It tries to resolve other names, e.g. functions; but table names (and schema names, and column names) have to be valid to the SQL parser.

You have to use dynamic SQL to create a string that contains the statement, concatenating in the identifiers:

execute immediate 'select count(*) from ' || myschema ||'.'|| mytable
  || ' where colA = :value'
into rowBefore using param1;

If you print out that generated statement with dbms_output you should see it matching the commented-out version, except for the use of a bind variable for the columns value. That would also help highlight any errors - like not including whitespace between the concatenated parts of the statement, which is a common and easy mistake.

It's often a good idea to build the statement as a string variable to make such debugging easier:

declare
  ...
  v_stmt varchar2(4000):
begin
  v_stmt := 'select count(*) from ' || myschema ||'.'|| mytable
    || ' where colA = :value';
  -- for debugging
  dbms_output.put_line(v_stmt);
  -- and run it
  execute immediate vStmt into rowBefore using param1;
  ...

If you are really getting the identifiers passed in by a user or client you should validate them to avoid unexpected errors and SQL injection attacks. Also, if the identifiers might be case sensitive (i.e. schemas/tables created with quoted identifiers) then you may need to add double-quotes to the generated statement, and make sure the variables are the correct case.

Sign up to request clarification or add additional context in comments.

5 Comments

thanks, I but something is wrong with colA, even I used it as parameter
@4est - sorry, I assumed colA was also a variable; seems like that's a fixed name regardless of the schema and table name? Updated to use that literal name.
thanks! now it's fine....but can do like: vS = 'select (*) into...' and then execute?
Yes, absolutely - that make it much easier to print and debug the statement. But without the into ... part. I've added a version that does that.
thank you once again, that is what I'm looking for, much appreciated your help @Alex!
0

error is ORA-942: table or view does not exists. run first below query and see if error still occurs.

-- should you use abc.table1, instead of myschema.mytable?
select count(*) rowBefore from myschema.mytable where colA = 'a';

if there is still error, then fix the SELECT statement first before you use it in the PL/SQL block.

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.