When or Why to use a "SET DEFINE OFF" in Oracle Database - oracle

I'm watching a Script in Oracle and I see something I don't recognize
REM INSERTING into database1."Users"
SET DEFINE OFF;
Insert into database1."Users" ("id","right") values ('1','R');
I'm looking for documentation about "set define off" and it's literally writing "disable the parsing of commands to replace substitution variable with their values"
I don't really understand what they want to say.
Can anyone help me?

By default, SQL Plus treats '&' as a special character that begins a substitution string. This can cause problems when running scripts that happen to include '&' for other reasons:
SQL> insert into customers (customer_name) values ('Marks & Spencers Ltd');
Enter value for spencers:
old 1: insert into customers (customer_name) values ('Marks & Spencers Ltd')
new 1: insert into customers (customer_name) values ('Marks Ltd')
1 row created.
SQL> select customer_name from customers;
CUSTOMER_NAME
------------------------------
Marks Ltd
If you know your script includes (or may include) data containing '&' characters, and you do not want the substitution behaviour as above, then use set define off to switch off the behaviour while running the script:
SQL> set define off
SQL> insert into customers (customer_name) values ('Marks & Spencers Ltd');
1 row created.
SQL> select customer_name from customers;
CUSTOMER_NAME
------------------------------
Marks & Spencers Ltd
You might want to add set define on at the end of the script to restore the default behaviour.

Here is the example:
SQL> set define off;
SQL> select * from dual where dummy='&var';
no rows selected
SQL> set define on
SQL> /
Enter value for var: X
old 1: select * from dual where dummy='&var'
new 1: select * from dual where dummy='X'
D
-
X
With set define off, it took a row with &var value, prompted a user to enter a value for it and replaced &var with the entered value (in this case, X).

Related

ORACLE Cannot see apostrophes in my data, when read from SQL DEVELOPER

I'm trying to export a large amount of data from a Oracle DB.
One of the field contains a long string. This field is a VARCHAR2 (2000 chars).
For some reason a string like Mark's dog is shown (and exported) as Mark s dog
Pay attention! Space before the s char, is not a space... is an invisibile char that some editor see as PU2, but I cannot replace it.
Is there a reason for this issue? The production site (not one of mine...) shows the single quote correctly... so it's there somehow.
Thanks
Let's take a look, here's a scenario - I hope it's close to yours.
set sqlformat ansiconsole
drop table missing_quotes purge;
clear screen
create table missing_quotes
(id integer,
words varchar2(2000));
insert into missing_quotes values
(1, 'Mark''s dog');
insert into missing_quotes values
(2, 'Shelly''s cat');
select * from missing_quotes;
And the output -
Table MISSING_QUOTES created.
1 row inserted.
1 row inserted.
ID WORDS
1 Mark's dog
2 Shelly's cat
Now let's do the export. You're not saying how, but we'll just export the query results...as INSERT statements.
And our output -
REM INSERTING into MISSING_QUOTES
SET DEFINE OFF;
Insert into MISSING_QUOTES (ID,WORDS) values (1,'Mark''s dog');
Insert into MISSING_QUOTES (ID,WORDS) values (2,'Shelly''s cat');
Or CSV -
"ID","WORDS"
1,"Mark's dog"
2,"Shelly's cat"
Everything appears to be OK, including the apostrophe in your VARCHAR2(2000).

How to update value with special character in oracle 11g

I want to update the password having special characters ''?# #C $4 ABC (starting two characters are two single quotes) in Xyz table.
I am trying the following query
UPDATE Xyz set password="''?# #C $4" where user_no like '%123%';
But I am getting error as
ORA-00911: invalid charachter
The q-quoting mechanism helps in such situations, when you have to work with multiple single quotes within the string.
SQL> desc xyz
Name Null? Type
----------------------------------------- -------- ----------------------------
USER_NO NUMBER
PASSWORD VARCHAR2(20)
SQL> select * From xyz;
USER_NO PASSWORD
---------- --------------------
123 a
SQL> update xyz set password = q'[''?# #C $3]' where user_no = 123;
1 row updated.
SQL> select * From xyz;
USER_NO PASSWORD
---------- --------------------
123 ''?# #C $3
SQL>
Are you pasting the query from a different editor or IDE ? or Maybe copying from windows applications to Linux? In that case, there may be non-printable characters present.
If so, you could retype (not copy-paste) the SQL statement and try.
Also, double quotes aren't commonly used in SQL. You may want to replace them with single quotes.

When running report from forms (11g) get the error: REP-0788: Warning: The value of restricted LOV parameter is not among the selectable values

The parameter p_type is the LOV based on the select:
Select p_type
from parameter_types
where table_name = 'X'
and column_name = 'Y'
UNION
Select '-All-'
from dual;
Also the
1)Restrict List to Predermined Values is checked and
2) Hide First Column is unchecked.
3) initial value not given
I tried by setting up the into initial value to 'ALL'
Please help/suggest to debug this
It seems that you set parameter's initial value to something that LoV query doesn't return.
For example, suppose that you used Scott's DEPT table and set LoV to return this:
SQL> select dname from dept order by dname;
DNAME
--------------
ACCOUNTING
OPERATIONS
RESEARCH
SALES
Setting initial value to e.g. FINANCIALS would cause that error because FINANCIALS doesn't exist among selectable values (ACCOUNTING, OPERATIONS, RESEARCH, SALES).
What to do? Remove initial value, or set it to one of valid values.

Oracle SEQUENCE.Currval problem in CodeIgniter

I have a sequence named WCOMP_SEQ in oracle to generate auto increment column ON WCOMP table. When I insert a row to WCOMP table in SQLPlus, the row inserted and I can get the auto increment value using
SELECT WCOMP_SEQ.currval FROM dual
But when I ran insert a row using Database Class in CodeIgniter, the row inserted but when I ran the query above to get auto increment value I got Exception:
Exception: Undefined Index currval in E:...
How to fix this?
There is a way to get the value automatically assigned to a column: it is the RETURNING clause.
So, here is my sequence:
SQL> select emp_seq.currval from dual
2 /
CURRVAL
----------
8140
SQL>
I'm going to use it in an INSERT statement:
SQL> var seqval number
SQL> insert into emp
2 (empno, ename, deptno, sal, job)
3 values
4 (emp_seq.nextval, 'JELLEMA', 50, 4575, 'PAINTER')
5 returning empno into :seqval
6 /
1 row created.
SQL>
I returned the EMPNO into a SQL*Plus variable which I can print, and it has the same value as CURRVAL:
SQL> print :seqval
SEQVAL
----------
8141
SQL> select emp_seq.currval from dual
2 /
CURRVAL
----------
8141
SQL>
Your next question is, "does CodeIgniter support the RETURNING sysntax?" I have no idea, but I suspect it does not. Most non-Oracle frameworks don't.
There is always the option to wrap the INSERT statement in a stored procedure, but that's an architectural decision whoch many people dislike.
You can not fetch the SEQUENCE current value without issuing NEXTVAL (see here). So, if you do not want to increment the sequence value (by using NEXTVAL), you should instead query USER_SEQUENCES.
Something like this:
select Sequence_Name
, Last_Number
from user_sequences
where sequence_name = 'WCOMP_SEQ'
/
SEQUENCE_NAME LAST_NUMBER
------------- -----------
WCOMP_SEQ 20
Hope this helps.
In order to get currval on the sequence you will need to have at least one reference to the corresponding nextval for the sequence in the current user session. This is what causes it to set the currval value which would belong to the session.
If you are using it outside, it defeats the purpose which value could it return if there were other sessions active.

sqlplus pass a string containing ' ' such as 'index1','index2','index3'

I need to pass this value to my sql file cause I am executing then a where condition with a IN.
For instance : Delete FROM table WHERE col IN ('index1','index2','index3')
I have an issue when I try to call this sql file from cmd using sqlplus command
set INDEXES = 'index1','index2','index3'
sqlplus script %INDEXES%
When I do that, only index1 is passed or there is a problem
I tried to do that
set INDEXES = "'index1','index2','index3'"
sqlplus script %~INDEXES%
but there is a problem too
Here is my sql:
Delete FROM table WHERE col IN (&1)
Do you have any idea how I can successfully pass the string I need ?
thank you
Oracle does not come with a built-in string tokenizer. So, we have to build our own. There are several different solutions on SO. Here is one I published, which will work on 10g or higher. For earlier versions try this one.
Actually, your technique is correct.
sqlplus scott/tiger #script.sql "'index1','index2','index3'"
where script.sql is:
Delete FROM table WHERE col IN (&1)
will result in &1 being replaced, verbatim, with 'index1','index2','index3', resulting in sqlplus executing:
Delete FROM table WHERE col IN ('index1','index2','index3')
The problem i see is that the delete statement doesn't end in a semi-colon and the script doesn't commit/exit (maybe those were just excluded in your post).
So it follows that, if your command-line properly interpolates environment variables, then
set INDEXES = "'index1','index2','index3'"
sqlplus scott/tiger #script.sql %~INDEXES%
results in the same command as the first in my comment.
An easy way to see what sqlplus is doing with the command-line parameters is to simply add prompt to the beginning of the delete line in your script:
prompt Delete FROM table WHERE col IN (&1)
I would look at this as a variable in list question. These can be tricky and the answer varies based on the version of Oracle you have access to
create table aaa(aaa varchar2(50));
insert into aaa values('index1');
insert into aaa values('index2');
insert into aaa values('index3');
insert into aaa values('index4');
insert into aaa values('index5');
declare
pindexes varchar2(100) ;
begin
pindexes := 'index1,index2,index3';
delete aaa where aaa in (
select substr(pindexes,
loc+1,
nvl(
lead(loc) over (order by loc) - loc-1,
length(pindexes) - loc)
)
from (
select distinct (instr(pindexes, ',', 1, level)) loc
from dual
connect by level < length(pindexes)
)
);
end ;
/
select * from aaa;
/
--drop table aaa;
this way you just pass in your string as 'index1,index2,index3'
this should work 9i+
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:210612357425

Resources