Showing posts with label Oracle. Show all posts
Showing posts with label Oracle. Show all posts

Tuesday, September 19, 2017

SQL Injection - Which may Destroy Your Database




SQL Injection :-

It is a Code Injection technique which might destroy your database knowingly or Unknowingly. We should all very careful about it. 

Here in this blog, we will see how Injection a) might destroy your database and how it b) will bypass security as well. Yes, lets explore with examples. 




Scenario 1  ( How to break Security Login )

Here, it is to check the User login with Username and Password. Getting the inputs and passed in a query. If it matches with the User List in the User Table, then it will allow that user to login. 

Input Values  - Case 1

User id   =  1001
Password = pass

The above given inputs will frame the SQL as below. 

Select * from User_table  where User id = 101  and Password = 'pass';

The above query will check Username and Password in the User table and allow if the Username and Password is perfectly matched with any of the records.

Here, there is no SQL Injection. Great. 


Input Values - Case 2

User id = 1001 OR 1=1 
Password = pass

The above said Input values  will make SQL statement as below. 

Select * from User_table  where User id = 101  or 1=1  and Password = 'pass';

This will select records always even though if any one enters wrong username and password. Then the application or database is in User's hand to do whatever he want. 

This is one way of doing SQL Injection. Be careful about it. 




Scenario 2  ( How to Inject to destroy Database by dropping key tables )

Here, it is to pass input value to frame  a SQL statement to Execute. 

Delete from transaction where transaction_no = "Input Value"

Input Value - Case 1:

Transaction Number =  100001

With the above said Input Value, the query will be framed to execute as below. 

Delete from transaction where transaction_no = 100001

Here, it is perfect and there is no SQL injection takes place. Perfect One. But.,  lets see in other two cases below. 


Input Value - Case 2:

Transaction Number =  100001  or  1=1 ;

With the above said Input Value, the query will be framed to execute as below. 

Delete from transaction where transaction_no = 100001 or  1=1;

We all know that, the above statement will not delete only the transaction 100001 but all the transactions in the transaction table, which is the crisis to the business. 



Input Value - Case 3:

Transaction Number =  100001; drop table USER_LOGIN ;

With the above said Input Value, the query will be framed to execute as below. 

Delete from transaction where transaction_no = 100001; drop table USER_LOGIN;

Think about it, after deleting transaction what will happen. The key table USER_LOGIN will be dropped which may lead to DB Login Crash. 


Solution :-
1. Be very very careful about Input Parameters
2. Include this SQL injection scenarios in all your test cases during Testing.  

Avoid SQL Injection and Keep our database safe always.


Thanks for all your support. We will connect in our next blog with different topic

Regards,
Sathish





Monday, March 20, 2017

SQL Loader - Utility to load data from flat files to Oracle tables - Quick & Detailed view



It is very usual requirement to move custom data available in external files to be moved to the particular tables present in Oracle DB.  SQL Loader is one of the option; where we can play along with different requirements in moving the data. 


First of all, what is SQL Loader?  - A Quick view. 

SQL Loader is an utility by which we can move data from external files such as CSV, TXT, XLS etc., to Oracle tables. 


How to achieve this? 

Very simple. We need to create two files first.   1. Control file    and  2. Source data file. 


What is control file?

Control file is similar to txt file but have to be saved with extension  " .ctl " ; where we will hold the specifications about the flat file, data, table names, delimiter etc., 


Sample & Simple control file will be as following one:-


 load data
 infile 'c:\data\item_data.csv'     BADFILE 'myydata.bad'  DISCARDFILE 'mydata.dis'
 into table item
 fields terminated by "," optionally enclosed by '"'    
 ( item_gid, item_desc, item_type, domain_name)

==> infile holds the external source file name and its path details
       
The bad file and discard files both contain rejected rows, but they are rejected for different reasons:  Both are optional.
  • Bad file:  The bad file contains rows that were rejected because of errors.  These errors might include bad datatypes or referential integrity constraints.
  • Discard file:  The discard file contains rows that were discarded because they were filtered out because of a statement in the SQL*Loader control file.
==> into table clause holds the < table name > 
==> terminated by "," means data are separated by comma.  " # " means data are separated by #.
==> optionally enclosed by  '  " ' means..  values within double quotes with spaces will be considered as single data.
For example : " Logitech Pen Drive " will be considered as data for single column.  
==> last line in the above example holds the list of column names of the table ITEM.

Sample Source File :-

the source file  item_data.csv file may look like this:
10001,"Laptop HP", 'Electronic', 'Sales'
10002,"Logitech Pen drive", 'Electronic', 'Service'

One we created the above said two files, we have to execute the below SQLLDR statement from command promt. Upon execution of any of the below statement; data will be loaded into the table ITEM.


sqlldr username@server/password control=loader.ctl
sqlldr username/password@server control=loader.ctl

==> sqlldr = keyword
==> username, password & server names are related to the DB where we want to connect and load the data. 
==> control = keyword
==> loader.ctl  is the name of control file. 


More options on SQL Loader?  - A Detailed view. 

Load fixed length data ( instead of comma separator ). 

In this case, control file will be as follows.


load data
 infile 'c:\data\item_data.txt'
 into table item
 (  item_gid  position (02:05) char(4),
    item_desc position (08:27) char(20)
 )

item_data.txt will be like this:-


1234   Laptop
1111   Mouse


Can have data in control file itself ( No need of source file ). ? 

Yes we can .. as follows

Please note that;    infile *    and   begindata are the keywords change in this control file than earlier one. 


load data
 infile *
 replace
 into table item_data
 (  item_gid  position (02:05) char(4),
    item_desc position (08:27) char(20)
 )
begindata
1111  APPLE IPHONE 7S
2222  LENOVA LAPTOP
3333  LOGITECH MOUSE V2
4444  NIKON CAMERA 



Can we modify the data.. on the fly .. whilst upload the data.  ?

Yes we can.. by using the below one sample control file.


LOAD DATA
  INFILE *
  INTO TABLE modified_data
  (  rec_no                      "my_db_sequence.nextval",
     region                      CONSTANT '31',
     time_loaded                 "to_char(SYSDATE, 'HH24:MI')",
     data1        POSITION(1:5)  ":data1/100",
     data2        POSITION(6:15) "upper(:data2)",
     data3        POSITION(16:22)"to_date(:data3, 'YYMMDD')"
  )
BEGINDATA
11111AAAAAAAAAA991201

LOAD DATA
  INFILE 'mail_orders.txt'
  BADFILE 'bad_orders.txt'
  APPEND
  INTO TABLE mailing_list
  FIELDS TERMINATED BY ","
  (  addr,
     city,
     state,
     zipcode,
     mailing_addr   "decode(:mailing_addr, null, :addr, :mailing_addr)",
     mailing_city   "decode(:mailing_city, null, :city, :mailing_city)",
     mailing_state,
     move_date      "substr(:move_date, 3, 2) || substr(:move_date, 7, 2)"
  )


Can we upload data from multiple source files ? 

Yes we can . Please refer the below sample control file. 


LOAD DATA
  INFILE file1.dat
  INFILE file2.dat
  INFILE file3.dat
  APPEND
  INTO TABLE emp
  ( empno  POSITION(1:4)   INTEGER EXTERNAL,
    ename  POSITION(6:15)  CHAR,
    deptno POSITION(17:18) CHAR,
    mgr    POSITION(20:23) INTEGER EXTERNAL
  )


Can we upload into multiple tables ? 

Yes we can. please refer the below sample control file.



LOAD DATA INFILE 'mydata.dat' REPLACE INTO TABLE emp WHEN empno != ' ' ( empno POSITION(1:4) INTEGER EXTERNAL, ename POSITION(6:15) CHAR, deptno POSITION(17:18) CHAR, mgr POSITION(20:23) INTEGER EXTERNAL ) INTO TABLE proj WHEN projno != ' ' ( projno POSITION(25:27) INTEGER EXTERNAL, empno POSITION(1:4) INTEGER EXTERNAL )


Can we upload only selected data from source file ?

Yes we can. please refer the below sample control file. 


LOAD DATA
  INFILE  'mydata.dat' BADFILE  'mydata.bad' DISCARDFILE 'mydata.dis'
  APPEND
  INTO TABLE my_selective_table
  WHEN (01) <> 'H' and (01) <> 'T'
  (
     region              CONSTANT '31',
     service_key         POSITION(01:11)   INTEGER EXTERNAL,
     call_b_no           POSITION(12:29)   CHAR
  )
  INTO TABLE my_selective_table
  WHEN (30:37) = '20031217'
  (
     region              CONSTANT '31',
     service_key     POSITION(01:11)   INTEGER EXTERNAL,
     call_b_no         POSITION(12:29)   CHAR
  )


Can we load images, sound clips, blog data and documents ? 

Yes, we can by using the below control file as sample one. 


Consider the following table is created.

CREATE TABLE image_table (
       image_id   NUMBER(5),
       file_name  VARCHAR2(30),
       image_data BLOB);

Control File:
LOAD DATA
INFILE *
INTO TABLE image_table
REPLACE
FIELDS TERMINATED BY ','
(
 image_id   INTEGER(5),
 file_name  CHAR(30),
 image_data LOBFILE (file_name) TERMINATED BY EOF
)
BEGINDATA
001,image1.gif
002,image2.jpg
003,image3.jpg


We are at the end of the session of SQL Loader. Now you are proudly a SQL Loader Expert.  Try this out to  experience more.. 


Click the link and Like this FB page  to get more articles like this.

Monday, February 27, 2017

INSERT multiple rows with single SELECT statement - INSERT ALL




 
We might face the requirement to INSERT multiple records in a table; where we have either go for SQL Loader, CSV upload  or  Multiple INSERT statements. 

We have another simple option in ORACLE;  which is INSERT ALL..


Consider the table as example. 

TABLE NAME : DOMAIN


 Name             Type
 ---------------- ------------
 DOMAIN_NAME    VARCHAR2(30)
 REGION              VARCHAR2(10)
 
Consider the requirement to INSERT the below data 


DOMAIN_NAME       REGION
---------------- --------
D001                   APAC
D002                   EMEA
D003                   US
D004                   APAC
D005                   US
 
 
Using INSERT statements:-

INSERT into DOMAIN (DOMAIN_NAME, REGION) values ('D001', 'APAC' );
COMMIT;

INSERT into DOMAIN (DOMAIN_NAME, REGION) values ('D002', 'EMEA' );
COMMIT;
 
INSERT into DOMAIN (DOMAIN_NAME, REGION) values ('D003', 'US' );
COMMIT;
 
INSERT into DOMAIN (DOMAIN_NAME, REGION) values ('D004', 'APAC' );
COMMIT;

INSERT into DOMAIN (DOMAIN_NAME, REGION) values ('D005', 'US' );
COMMIT;


Think about if this requirement is for inserting more number of records. 
We need to write and execute "N" number of INSERT statements.

GOOD NEWS IS.. we can achieve the same by using single INSERT statement.

Using INSERT ALL statement:-

INSERT ALL 
into DOMAIN(DOMAIN_NAME, REGION) values('D001', 'APAC'
into DOMAIN(DOMAIN_NAME, REGION) values('D002', 'EMEA'
into DOMAIN(DOMAIN_NAME, REGION) values('D003', 'US'
into DOMAIN(DOMAIN_NAME, REGION) values('D004', 'APAC'
into DOMAIN(DOMAIN_NAME, REGION) values('D005', 'US' ) ;
COMMIT;


With respect to Performance; INSERT ALL is better, because parsing iteration to the table DOMAIN takes place for one time; whereas for INSERT statement, parsing takes place for multiple times.





Tuesday, February 21, 2017

SQL Query to generate CALENDAR for Year 2017


SQL is not only an  " Art of Generating Data " ,  but also an " Art of Showing Data "




We all know about date functions in SQL,  can we do create a calendar for year 2017.. using Date functions .. and also for years .. 2016..2018...1823...2957.. ?

YES.. WE CAN..  using SQL..

First we will see the Query to show the CALENDAR for year  2017.

Try executing the below queries in your SQL developer or TOAD by just changing year as you want. 

Calendar SQL Statement for 2017 :-

WITH TT AS (SELECT (TO_DATE('01-Jan-2017','DD-Mon-YYYY')) DAT FROM DUAL )
SELECT LPAD( MONTH, 20-(20-LENGTH(MONTH))/2 ) MONTH,  "Sun", "Mon", "Tue",
"Wed", "Thu", "Fri", "Sat"
FROM (SELECT TO_CHAR(DT,'fmMonthfm YYYY') MONTH,TO_CHAR(DT+1,'iw') WEEK,
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'1',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Sun",
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'2',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Mon",
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'3',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Tue",
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'4',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Wed",
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'5',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Thu",
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'6',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Fri",
nvl(MAX(DECODE(TO_CHAR(dt,'d'),'7',LPAD(TO_CHAR(dt,'fmdd'),2))),'  -') "Sat"
FROM ( SELECT TRUNC(tt.dat,'y')-1+ROWNUM dt, rownum
FROM SHIPMENT S, TT
WHERE ROWNUM <= ADD_MONTHS(TRUNC(TT.dat,'y'),12) - TRUNC(tt.dat,'y'))
GROUP BY TO_CHAR(DT,'fmMonthfm YYYY'), TO_CHAR( DT+1, 'iw' ))
ORDER BY TO_DATE( MONTH, 'Month YYYY' ) , 2

 

Oh.. I want to see my year of birth.. say for eg., 1991

Calendar SQL Statement for 1991 :-

WITH TT AS (SELECT (TO_DATE('01-Jan-1991','DD-Mon-YYYY')) DAT FROM DUAL )
SELECT LPAD( MONTH, 20-(20-LENGTH(MONTH))/2 ) MONTH,  "Sun", "Mon", "Tue",
"Wed", "Thu", "Fri", "Sat"
FROM (SELECT TO_CHAR(DT,'fmMonthfm YYYY') MONTH,TO_CHAR(DT+1,'iw') WEEK,
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'1',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Sun",
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'2',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Mon",
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'3',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Tue",
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'4',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Wed",
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'5',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Thu",
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'6',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Fri",
nvl(MAX(DECODE(TO_CHAR(dt,'d'),'7',LPAD(TO_CHAR(dt,'fmdd'),2))),'  -') "Sat"
FROM ( SELECT TRUNC(tt.dat,'y')-1+ROWNUM dt, rownum
FROM SHIPMENT S, TT
WHERE ROWNUM <= ADD_MONTHS(TRUNC(TT.dat,'y'),12) - TRUNC(tt.dat,'y'))
GROUP BY TO_CHAR(DT,'fmMonthfm YYYY'), TO_CHAR( DT+1, 'iw' ))
ORDER BY TO_DATE( MONTH, 'Month YYYY' ) , 2

 

Around 1000 years before :-

Calendar SQL Statement for 1015 :-

WITH TT AS (SELECT (TO_DATE('01-Jan-1015','DD-Mon-YYYY')) DAT FROM DUAL )
SELECT LPAD( MONTH, 20-(20-LENGTH(MONTH))/2 ) MONTH,  "Sun", "Mon", "Tue",
"Wed", "Thu", "Fri", "Sat"
FROM (SELECT TO_CHAR(DT,'fmMonthfm YYYY') MONTH,TO_CHAR(DT+1,'iw') WEEK,
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'1',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Sun",
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'2',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Mon",
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'3',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Tue",
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'4',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Wed",
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'5',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Thu",
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'6',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Fri",
nvl(MAX(DECODE(TO_CHAR(dt,'d'),'7',LPAD(TO_CHAR(dt,'fmdd'),2))),'  -') "Sat"
FROM ( SELECT TRUNC(tt.dat,'y')-1+ROWNUM dt, rownum
FROM SHIPMENT S, TT
WHERE ROWNUM <= ADD_MONTHS(TRUNC(TT.dat,'y'),12) - TRUNC(tt.dat,'y'))
GROUP BY TO_CHAR(DT,'fmMonthfm YYYY'), TO_CHAR( DT+1, 'iw' ))
ORDER BY TO_DATE( MONTH, 'Month YYYY' ) , 2 


After 1000 plus year and so on..

Calendar SQL Statement for 3742 AD :-

WITH TT AS (SELECT (TO_DATE('01-Jan-3742','DD-Mon-YYYY')) DAT FROM DUAL )
SELECT LPAD( MONTH, 20-(20-LENGTH(MONTH))/2 ) MONTH,  "Sun", "Mon", "Tue",
"Wed", "Thu", "Fri", "Sat"
FROM (SELECT TO_CHAR(DT,'fmMonthfm YYYY') MONTH,TO_CHAR(DT+1,'iw') WEEK,
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'1',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Sun",
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'2',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Mon",
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'3',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Tue",
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'4',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Wed",
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'5',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Thu",
NVL(MAX(DECODE(TO_CHAR(DT,'d'),'6',LPAD(TO_CHAR(DT,'fmdd'),2))),'  -') "Fri",
nvl(MAX(DECODE(TO_CHAR(dt,'d'),'7',LPAD(TO_CHAR(dt,'fmdd'),2))),'  -') "Sat"
FROM ( SELECT TRUNC(tt.dat,'y')-1+ROWNUM dt, rownum
FROM SHIPMENT S, TT
WHERE ROWNUM <= ADD_MONTHS(TRUNC(TT.dat,'y'),12) - TRUNC(tt.dat,'y'))
GROUP BY TO_CHAR(DT,'fmMonthfm YYYY'), TO_CHAR( DT+1, 'iw' ))
ORDER BY TO_DATE( MONTH, 'Month YYYY' ) , 2 

 

##  Kindly feel free to comment your feedback  ##

Sunday, February 19, 2017

How to Create and Use Oracle Database Link ( DB Link )



We of-course heard the keyword DB LINK from DBAs. Every developer should know about this to ease their day to day DB data handling tasks. 

Okay.. Let see in detail What is DB link ?, How to create DB link? and How perfectly use DB link?  in this article.  



About DB Link :-

Database Link is an object can be created in one database; by which we can access other database objects such as tables, views etc.,

For example :-  If we create DB Link in DEV DB to connect with QA DB, then we can access QA database from DEV DB.  We can do SELECT, INSERT, UPDATE & DELETE statements for QA tables from logging into DEV DB.

Prerequisites to create DB link :-

Database should have the below two accesses to create DB link 
          a)  CREATE DATA BASE LINK   ( at local DB )   
               to create private DB LINK

                     [OR]

               CREATE PUBLIC DATA BASE LINK ( at local DB )
               to create public DB LINK
               

          b)  CREATE SESSION ( at remote DB )

How to create DB link :-

SYNTAX 1  ( To create PRIVATE  DB  Link )

CREATE DATABASE LINK   DB_LINK_NAME  USING  SERVICE_NAME 


SYNTAX 2  ( To create PUBLIC   DB  Link )

CREATE PUBLIC DATABASE LINK   DB_LINK_NAME  USING  SERVICE_NAME

SYNTAX 3 (  To create PUBLIC  DB LINK to access particular schema  )

CREATE PUBLIC DATABASE LINK   DB_LINK_NAME  
CONNECT TO  SCHEMA_NAME
IDENTIFIED BY   PASSWORD
USING   SERVICE_NAME


DB_LINK_NAME  ->   Name to connect with remote DB
SERVICE_NAME  ->   Remote DB service name
SCHEMA_NAME   ->  User name of Remote DB schema name
PASSWORD         ->  Password to connect remote DB schema


How to use DB link :-


SELECT FROM TABLE_NAME@DB_LINK_NAME
DELETE FROM TABLE_NAME@DB_LINK_NAME
TABLE_NAME  ->  Table name of a remote DB 


How to see existing DB links in the current schema/DB :-

SELECT  *   FROM     DBA_DB_LINKS
( List all Database Links in the local database )

SELECT  *   FROM     ALL_DB_LINKS
( List all Database Links accessible to the current user )

SELECT  *   FROM     USER_DB_LINKS
( List all Database Links owned by current user )


How to Drop Data base link 


DROP DATABASE LINK  DB_LINK_NAME
DROP PUBLIC DATABASE LINK DB_LINK_NAME

( Think twice before you execute DROP DB LINK statement; since it will drop the access to other DB's object )


Your feedback about this article is most welcome. Please feel free to comment below. 

Friday, February 17, 2017

How to use IN and EXISTS in SQL effectively ?


Developers have this doubt in mind often on HOW and WHEN to use either IN or EXISTS.  Here is the solution.

Consider two tables - Shipment & Shipment Refnum

Shipment  ( Parent Table )
Shipment_gid    Varchar2
Domain_name   Varchar2


Shipment_Refnum ( Child Table )
Shipment_gid  Varchar2
Shipment_refnum_qual_gid   Varchar2
Shipemnt_refnum_value        Varchar2
Domain_name  Varchar2 


HOW to USE "IN"

When the INNER QUERY passes the direct output value to OUTER QUERY; we can use "IN" as below. 

SELECT *       /* outer query */
  FROM SHIPMENT S
 WHERE S.SHIPMENT_GID  IN
                                         ( SELECT    SHIPMENT_GID     /*  inner query */
                                                 FROM    SHIPMENT_REFNUM SR
                                             WHERE    SR.SHIPMENT_REFNUM_QUAL_GID = 'RQG'
                                                AND  SR.SHIPMENT_REFNUM_VALUE = 'SRV' )
AND S.DOMAIN_NAME = 'DUMMY';




The inner query is executed first and the list of values obtained as its result is used by the outer query.The inner query is executed for only once.


HOW to USE "EXISTS"

The first row from the outer query is selected ,then the inner query is executed and , the outer query output uses this result for checking.

This process of inner query execution repeats as many no.of times as there are outer query rows. That is, if there are ten rows that can result from outer query, the inner query is executed that many no.of times.

SELECT  *  FROM SHIPMENT S
                                               WHERE EXISTS
                                                                               (  SELECT  1  FROM SHIPMENT_REFNUM SR
                                                                                        WHERE SR.SHIPMENT_REFNUM_QUAL_GID = 'RQG'
                                                                                                AND  SR.SHIPMENT_REFNUM_VALUE = 'SRV'
                                                                                                AND SR.SHIPMENT_GID = S.SHIPMENT_GID )
AND S.DOMAIN_NAME = 'DUMMY';
   

                     

WHEN to USE "IN"  &  "EXISTS"

The recommendation at that time were:

  • If the majority of the filtering criteria is in the INNER query, use IN.
  • If the majority of the filtering criteria is in the outer query, use EXISTS.
When the INNER query has the feasibility of returning very less number of records, IN is better.

When the INNER query has the feasibility of returning more number of records, EXISTS is better. 


In other words,

  • IN for big OUTER query and small INNER query.
  • EXISTS for small OUTER query and big INNER query.



How to identify a particular string in LOB (XML_BLOB) column data ?





Dear Friends, 

You might have come across the situation to check whether a particular string is existing anywhere within the LOB column value. Here we go with the solution.


Say for example:-

Consider the table I_TRANSACTION  which has the below columns 

I_TRANSACTION_NO    NUMBER, 
XML_BLOB                   CLOB, 
DOMAIN_NAME            VARCHAR2


And the value for XML_BLOB seems like below.

<TenderOffer><Shipment><ShipmentHeader><ShipmentGid><Gid><DomainName>DUMMY</DomainName><Xid>SHIP12345</Xid></Gid></ShipmentGid><ShipmentRefnum><ShipmentRefnumQualifierGid><Gid><Xid>BM</Xid></Gid></ShipmentRefnumQualifierGid><ShipmentRefnumValue>.........

........
........
......../Gid></ShipmentGid></ShipmentStatus></Shipment><ExpectedResponseDt><GLogDate>20170216121036</GLogDate>


Requirement:-

If you want to identify whether the particular key value  "SHIP12345"  is available or not ?  

DBMS_LOB.INSTR function can be used to achieve this. 


Oracle Syntax :-

There are four parameters to be passed as below.
DBMS_LOB.INSTR   (   COLUMN_NAME,   VALUE_TO_SEARCH,    START_POSITION_SEARCH,  NTH_TIME_OF_OCCURRENCE ) 

Example Query:-

SELECT  DBMS_LOB.INSTR(   XML_BLOB,   'SHIP12345',   1,  1 ) 
FROM I_TRANSACTION
WHERE I_TRANSACTION_NO = 12345678



Output :-

If it returns  "0" , then the  "VALUE_TO_SEARCH" is NOT available in XML_BLOB for the transaction_no


If it returns value greater than "0" , then the "VALUE_TO_SEARCH"  is  Available in XML_BLOB for the transaction_no. Actually, it returns the position of the value in XML_BLOB.  if the return value is "72", it means the value is available from 72nd character of the XML_BLOB.