Using substitution variables in table name - oracle

My issue is easy, I want to find out if what I am trying to do can be done or not.
I have tables like this : detailcro1, detailcro2, detailcro3 ... I want to use a substitution var for some automatic process.
I wrote
DEFINE TT = 'detailcro'
select * from &TT||'2';
and as a result I have ORA-00933:.
Can I create such a query ?
Thank you

You need to usu a dot notation at the end of the variable
SQL> select * from &TT.l;
Enter value for tt: dua
old 1: select * from &TT.l
new 1: select * from dual
D
-
X
so
SQL> DEFINE TT = 'detailcro';
SQL> select * from &TT.2;
old 1: select * from &TT.2
new 1: select * from detailcro2
no rows selected

Related

Can I define a variable for a list of values in SqlPlus

I have a script (for Oracle) with a number of sql statements that all target the same list of values, for example
select * from s1.t1 where f1 in ('val1', 'val2')
select * from s2.t2 where f2 in ('val1', 'val2')
-- etc.
Instead of pasting this list of values in at each place in the script, I would like to define a variable to hold that list, and then use it in the correct place, something like:
define var1 = "('val1','val2')"
select * from s1.t1 where f1 in &&var1
select * From s2.t2 where f2 in &&var1
When I attempt it the way it's written above, I get the error "ORA-00933: SQL command not properly ended", and the verified statement in the log looks like:
select * from s1.t1 where f1 in '('val1','val2')'
So I can see that the variable substitution is putting single quotes around my entire variable value, which is sort of reasonable but not what I want. Is there a way to get done what I want here?
Your 'verified statement' ends up as:
select * from s1.t1 where f1 in '('val1','val2')'
which means that, if you've defined the substitution variable as you said, your query is actually then using it as:
select * from s1.t1 where f1 in '&&var1';
old:select * from s1.t1 where f1 in '&&var1'
new:select * from s1.t1 where f1 in '('val1','val2')'
SQL Error: ORA-00933: SQL command not properly ended
Enclosing the variable in single quotes is necessary when the value is an unquoted string, which is usually the case with new_value and by default with define or accept or when prompted for the variable value. But here your variable value already has all the quotes you need, so it should just be as you actually showed it in your question, without the quotes:
select * from s1.t1 where f1 in &&var1;
old:select * from s1.t1 where f1 in &&var1
new:select * from s1.t1 where f1 in ('val1','val2')
which is now valid.
Works OK for me; example based on Scott's EMP table:
SQL> define vjob = "('CLERK', 'MANAGER')"
SQL> select count(*) from emp where job in &vjob;
old 1: select count(*) from emp where job in &vjob
new 1: select count(*) from emp where job in ('CLERK', 'MANAGER')
COUNT(*)
----------
7

how to get multiple values from different tables plsql

I usually do this query every day:
select * from table1
where name = 'PAUL';
select * from table2
where id_user = 012345;
select * from table25
where name = 'PAUL';
select * from table99
where name = 'PAUL';
select * from table28
where id_user = 012345;
.
.
.
I do this query every day. Today is 15 tables, tomorrow maybe 20, the only change is the name or id of the user to search. I have to go placing the username or id in each of the queries, so I need a query where there is a variable and assign the name and id.
.
.
There is a way to simplify this query and make it better? Such as:
DECLARE
l_name table1.name %type;
l_id_user table28.id_user %type;
BEGIN
l_id_user := 012345;
l_name := 'PAUL';
select * from table1
where name in ('l_name');
select * from table2
where id_user in (l_id_user);
.
.
.
END;
I tried that way but fails. I need this query because in most cases need to see up to 20 tables or more.
If what you want is an easy way to repeatedly run a sequence of select statements in SQL*Plus - but with varying criteria you can do it like this:
ACCEPT l_name PROMPT "Input user name: "
ACCEPT l_id_user PROMPT "Input user id: "
select * from table1
where name = '&l_name';
select * from table2
where id_user = &l_id_user;
select * from table25
where name = '&l_name';
select * from table99
where name = '&l_name';
select * from table28
where id_user = &l_id_user;
In a pl/sql block declare ... begin .. end; select statements behave differently from when you run them stand alone in SQL*Plus:
They won't automatically print output.
You must use e.g. a FOR LOOP or a variation of the SELECT INTO syntax to capture the result for subsequent processing. You should seek some documentation on pl/sql programming.
You should understand that pl/sql is definitely not designed for screen output.
It is possible to print out string values using dbms_output.put_line, but you are completely on your own with regards to formatting a row of values into a suitable string.
If your result contains more than a few columns formatting for screen output becomes very cumbersome as you wont have any formatting utilities like the java String.format() to assist you.
And if your result contains more than one row you have to provide some sort of loop construct allowing you to print out the individual rows.
Conlusion:
These are the drawbacks of pl/sql - I really don't see any benefits - unless your aim is to apply some logic to the data being read rather than just printing it to the screen or a file.

output/echo a meesage in hql/ hive query language

I need to create a hive.hql as follows.
HIVE.hql:
select * from tabel1;
select * from table2;
My question is: can i echo any message to my console like " results from table1 is obtained " in the hql code after table one is created like
select * from tabel1;
echo/print/output ("table 1 results obtained");
select * from table2;
In the *.hql file insert a line as below in between the two hive queries.
!echo "table 1 results obtained";
You can add a comment by editing your HIVE.hql :
select * from tabel1;
!sh echo "table 1 results obtained";
select * from table2;
In beeline just use the below
--add your comment after 2 hypens and its printed in the console
Other solutions didnt work probably they are removed in current version

Expected CHAR got NUMBER

DB: Oracle 11g
Query:
SELECT CASE
WHEN rs.OPTION = '3'
THEN
(SELECT COUNT(DISTINCT ex.EXTS) AS TMPCOL0
FROM CRSIDM.SUB_OPTS ex
INNER JOIN CRSIDM.SUB_OPTS_GRP cg
ON cg.GROUP_ID = ex.GRP_ID
)
ELSE
(SELECT COUNT(DISTINCT ex.EXTS) AS TMPCOL0
FROM CRSIDM.SUB_OPTS ex
INNER JOIN CRSIDM.SUB_OPTS_POL cg
ON cg.GROUP_ID = ex.GRP_ID
)
END AS PROPTS
FROM PR_OPTS
I am getting error 'expected CHAR got NUMBER', here EXTS,GROUP_ID & GRP_ID are numeric. Then how there is a chance of expecting CHAR?
Generally when Oracle compares different datatypes such as a NUMBER with a CHARACTER, implicit conversion kicks in and all is well (provided the data can be converted.) For example, if you have a function that expects a CHARACTER value but you pass it a NUMBER, all is well - Oracle simply converts the NUMBER to character.
E.g. a function like this:
create or replace function get_something(p_id VARCHAR2) return number ...
works if you call it with this:
get_dno(10);
or this:
get_dno('10');
and in SQL:
select * from some_table where numeric_column = '10' -- no problem.
A popular place where you see this kind of error is with the return values in CASE statements. For instance, you'll get that error if you have something like this:
SQL> SELECT CASE WHEN 1 = 1 THEN '1' ELSE 2 END
2 FROM dual
3 ;
SELECT CASE WHEN 1 = 1 THEN '1' ELSE 2 END
*
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected CHAR got NUMBER
(The datatype from the first WHEN clause is what it expects in the other WHEN/ELSE clauses that follow.)
But in your case the WHEN and THEN both return counts - the datatypes are consistent. So, I think you have a red-herring in there.
As Alex mentioned above, OPTION is a keyword and if you try and create a table with that as a column name, Oracle disagrees:
SQL> create table dummy
2 (option varchar2(10)
3 );
(option varchar2(10)
*
ERROR at line 2:
ORA-00904: : invalid identifier
This works:
SQL> create table dummy
2 (option_col varchar2(10)
3 );
Table created.
or you could do it with quotes:
SQL> create table dummy
2 ("option" varchar2(10));
Table created.
But now you're in a world of hurt - you need quotes from now on:
SQL> select option from dummy;
select option from dummy
*
ERROR at line 1:
ORA-00936: missing expression
SQL> select d.option from dummy d;
select d.option from dummy d
*
ERROR at line 1:
ORA-01747: invalid user.table.column, table.column, or column specification
With quotes:
SQL> select d."option" from dummy d;
no rows selected
So, if your query is really giving you "expected CHAR, got NUMBER", it looks to me like something is off.
Essentially, it means some of the fields you are using aren't compatible with each other. It's basically a "type mismatch". Just check to see if any types of CHAR are being used with types of NUMBER. Then you can either switch the type of one, or simply use a conversion as part of the query.
The issue is OPTION = '3', the quotation marks indicate that you're looking for a string containing the solitary character 3.
Try this instead:
SELECT CASE
WHEN rs.OPTION = 3
THEN
(SELECT COUNT(DISTINCT ex.EXTS) AS TMPCOL0
FROM CRSIDM.SUB_OPTS ex
INNER JOIN CRSIDM.SUB_OPTS_GRP cg
ON cg.GROUP_ID = ex.GRP_ID)
ELSE
(SELECT COUNT(DISTINCT ex.EXTS) AS TMPCOL0
FROM CRSIDM.SUB_OPTS ex
INNER JOIN CRSIDM.SUB_OPTS_POL cg
ON cg.GROUP_ID = ex.GRP_ID)
END AS PROPTS
FROM PR_OPTS

What is the difference between bind variables and substitution variables(which I input using &&)?

What is the difference between these two variable declarations?
1: num number:='&&num';
2: variable num1 number;
Since in both cases I can reference num by using &num or &&num in other files also,
and in the case of bind variables :num1.
Moreover I have one more confusion: whether any of the below statements differ somehow, are they both valid and do they mean the same thing?
1: variable num1 number;
2: var num1 number;
You appear to have some confusion about the differences between bind variables in Oracle and substitution variables in SQL*Plus.
Let's start with substitution variables. Substitution variables are unique to SQL*Plus and are not part of the database. They won't work if you try to use them with JDBC, for example.
Substitution variables can only hold a piece of text. If SQL*Plus encounters a substitution variable in a line of input, it will replace the variable with its text contents:
SQL> define subvar=X
SQL> select * from dual where dummy = &subvar;
old 1: select * from dual where dummy = &subvar
new 1: select * from dual where dummy = X
select * from dual where dummy = X
*
ERROR at line 1:
ORA-00904: "X": invalid identifier
Note that SQL*Plus replaced our substitution variable with its text value with no regard for whether it gave us valid SQL. In the example above, we omitted the single quotes around &subvar and it gave us invalid SQL, so we got an error.
The lines beginning old and new show us the line we entered before and after SQL*Plus applied the substitution variables. The new line is the line the database tried to run.
You can enable or disable the display of the old and new lines using SET VERIFY ON and SET VERIFY OFF. You can also turn the replacement of substitution variables on or off by using SET DEFINE ON and SET DEFINE OFF.
If we want to run the above query using the substitution variable, we must put quotes around it:
SQL> select * from dual where dummy = '&subvar';
old 1: select * from dual where dummy = '&subvar'
new 1: select * from dual where dummy = 'X'
D
-
X
If &subvar happens to contain a string that was a valid number (e.g. 5), then we can get away without using the quotes, but that's only because taking out the text &subvar and replacing it with the text 5 happens to give us valid SQL.
For example, suppose we have a table called test with the following data in it:
A
----------
1
2
3
4
5
Then we can do
SQL> define subvar=5
SQL> select * from test where a = &subvar;
old 1: select * from test where a = &subvar
new 1: select * from test where a = 5
A
----------
5
Bind variables, on the other hand, have types. They are not simple text values. Their values are sent to the database, and the database can also set their values.
SQL> variable bindvar varchar2(1);
SQL> exec :bindvar := 'X';
PL/SQL procedure successfully completed.
You don't put quotes around a bind variable when you want to use it:
SQL> select * from dual where dummy = :bindvar;
D
-
X
SQL> select * from dual where dummy = ':bindvar';
no rows selected
In the second example above, we got no rows returned because the DUAL table has no rows with the DUMMY column containing the text :bindvar.
You'll get an error if you attempt to assign a value of the wrong type to a bind variable:
SQL> variable bindvar number;
SQL> exec :bindvar := 'X';
BEGIN :bindvar := 'X'; END;
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at line 1
Bind variables are a standard part of the database, and you can use them with JDBC or whichever method of connecting to the database you choose.
Finally, variable num1 number and var num1 number both mean the same thing. They both define a bind variable num1 of type number. var is just an abbreviation for variable.

Resources