ÿ is not displaying while concatenate with other column in oracle - sql

I have a problem regarding a special character. I have a table test as below:
SQL> desc test
Name Type Nullable Default Comments
-------------- ----------------- -------- ------- --------
DOT DATE Y
LOWVAL_CHAR VARCHAR2(3) Y
I am inserting data in this table using sqlldr. The data file is as below:
1984/01/10ÿ:-1 0 -99999+99999Sourav Bhattacharya
ctl file is as below:
LOAD DATA
CHARACTERSET AL32UTF8
APPEND
PRESERVE BLANKS
INTO TABLE TEST
(dot POSITION(1) CHAR(10) "TO_DATE(:DOT,'YYYY/MM/DD')",
lowval_char POSITION(11) CHAR(1),
highval_char POSITION(12) CHAR(1),
lowval_un_num POSITION(13) INTEGER EXTERNAL(6),
highval_un_num POSITION(19) INTEGER EXTERNAL(6),
lowval_si_num POSITION(25) INTEGER EXTERNAL(6),
highval_si_num POSITION(31) INTEGER EXTERNAL(6),
fn POSITION(37) CHAR(10),
mn POSITION(47) CHAR(5),
ln POSITION(52) CHAR(20)
)
Data got inserted correctly.
Now if I execute the query
select dot,lowval_char from test;
It is giving me correct result but if I concatenate i.e
select dot||lowval_char from test;
ÿ is not displaying, only the dot value is visible.
If I do not use SQL loader and do any insert into it is giving correct result for both the cases.
Settings:
character set is AL32UTF8
nls_language='AMERICAN'
NLS_LENGTH_SEMANTICS='BYTE'

Related

Searching special data by 'WHERE' command for CLOB type

Look at below table.
I tried to print 'CORP_CODE' out with tuple which has same 'CORP_NAME' in it.
SO, I wrote this code.
SELECT CORP_CODE
FROM COMPANY_INFO
WHERE CORP_NAME = '다코'
However, There is important error. The above code show ORA-00932: "inconsistent datatypes: expected %s got %s"
I changed '' to "", But It isn't helpful.
I found more information, The column named 'CORP_NAME' is type of CLOB data. It seems that I need to use special methods for do it.
That table, I dind't make it myself. It was just made by python pandas function 'dataframe.to_sql'.
In this situlation, I have three questions for you.
How can I get CORP_CODE with CLOB data 'CORP_NAME' by WHERE command or anything else?
Should I re-make table and define 'CORP_NAME' as VARCHAR2? Is it the only way for me?
In pandas inner function 'to_sql', Can I set detail options for making table?
I make another table that 'CORP_NAME' as VARCHAR2(146).
However, I want to know how can I select something by WHERE sentences.
Try it like below:
WITH
tbl As
(
Select 111 "CODE", SubStr('물을 흘린다', 1, 100) "MULTIBYTE_VARCHAR_NAME", 'spill water' "VARCHAR_NAME", To_CLOB('물을 흘린다') "CLOB_NAME" From Dual Union All
Select 222 "CODE", SubStr('흘린다', 1, 100) "MULTIBYTE_VARCHAR_NAME", 'spill' "VARCHAR_NAME", To_CLOB('흘린다') "CLOB_NAME" From Dual Union All
Select 333 "CODE", SubStr('물을', 1, 100) "MULTIBYTE_VARCHAR_NAME", 'water' "VARCHAR_NAME", To_Clob('물을') "CLOB_NAME" From Dual
)
-- where condition on VARCHAR column
SELECT * FROM tbl WHERE VARCHAR_NAME = 'spill water';
-- Result:
-- CODE MULTIBYTE_VARCHAR_NAME VARCHAR_NAME CLOB_NAME
-- ---------- ---------------------- ------------ -------------
-- 111 물을 흘린다 spill water 물을 흘린다
-- where condition on MULTIBYTE_VARCHAR column
SELECT * FROM tbl WHERE MULTIBYTE_VARCHAR_NAME = '물을';
-- Result:
-- CODE MULTIBYTE_VARCHAR_NAME VARCHAR_NAME CLOB_NAME
-- ---------- ----------------------- ------------ ----------------
-- 333 물을 water 물을
-- where condition on CLOB column using DBMS_LOB.SubStr() and SubStr() functions
SELECT * FROM tbl WHERE DBMS_LOB.SubStr(CLOB_NAME, 100, 1) = SubStr('흘린다', 1, 100);
-- Result:
-- CODE MULTIBYTE_VARCHAR_NAME VARCHAR_NAME CLOB_NAME
-- ---------- ---------------------- ------------ -----------------
-- 222 흘린다 spill 흘린다
It looks like pandas made it of the type of CLOB. Your WHERE clause tried to compare that CLOB with your multibyte character string. This could cause the error "expecting something else than CLOB/MULTIBYTE".
More about checking multibytes here and about DBMS_LOB package here
Regards...
You can use the below to overcome your problem by comparing CLOB with CLOB using dbms_lob.compare
SELECT CORP_CODE
FROM COMPANY_INFO
WHERE dbms_lob.compare(CORP_NAME, to_clob('다코')) = 0;

Can STRtOK function return a null/0 value?

I'm trying to use the strtok function to breakout a concatenated string.
This is what I have so far. My source tables are sitting in Teradata and I'm running the code via SAS.
proc sql;
connect to teradata as tera ( server='XXXXXX' authdomain='XXXXX';
execute(
update DB.Table1
from
(
select id, string_key
from DB.Table2
where date_time >= current_date
) c
set
country = STRTOK (c.string_key,',',1),
Expense = STRTOK (c.string_key,',',2),
First_Name = STRTOK (c.string_key,',',3),
) by tera
disconnect from tera
quit;
An example of a value in string_key is :
UK,244,Jack,Mathews
For the above example, my code has no problem creating the required output i.e:
Country
Expense
First name
UK
244
Jack
However in instances where a value in string_key has a null value after the delimiter, the strtok function returns the next available value in the wrong column.
for e.g when string_key is :
UK,244,,Mathews
then the output I get is
Country
Expense
First name
UK
244
Mathews
but what I want is that the First_name column should be empty as there is no value for it in the string_key.
i.e I want it is
Country
Expense
First name
UK
244
Could someone pls help tweak my code such that the column populates with a null value if the string has a null value?
Many thanks!
STRTOK doesn't play nicely with consecutive delimiters. You can replace consecutive delimiters with <delimiter><space><delimiter>. In your case:
trim(strtok(oreplace(string_key,',,',', ,'),',',3))
Alternatively, you could use csvld:
select
*
from
table (csvld(<table>.string_key,',','')
returns(a varchar(100), b varchar(100), c varchar(100), d varchar (100))) as t;
A RegEx should work:
SELECT 'UK,244,,Mathews' AS string_key
,REGEXP_SUBSTR(string_key, '(,|^)\K([^,]*)(?=,|$)',1,1)
,REGEXP_SUBSTR(string_key, '(,|^)\K([^,]*)(?=,|$)',1,2)
,REGEXP_SUBSTR(string_key, '(,|^)\K([^,]*)(?=,|$)',1,3)
,REGEXP_SUBSTR(string_key, '(,|^)\K([^,]*)(?=,|$)',1,4)
;
See RegEx101

Oracle convert column which is varchar / hex to numeric format after loading data from xlsx file

I loaded an Excel file into a table and found out that some data in my varchar2 field is in HEX format.
When I execute my query, I have no problem, but when I try to insert my data into another table with a number format it does not work.
This query shows which column is in HEX format :
SELECT qty, TO_NUMBER(REPLACE(qty, CHR(32), '')) as nbkg, RAWTOHEX(qty) as Graphics
FROM (
SELECT nvl(qty, 0) AS qty,
case
when pkg_tools.f_is_number(qty) = 1 then 'OK'
else 'NOK'
end kg
FROM table
)
WHERE kg = 'NOK';
*qty is a varchar2(50)
My output :
qty nbkg Graphics
--- ---- --------
10 009,000 10009,000 3130203030392C303030 -- work
3 250,00 3250,00 33203235302C3030 -- work
1 000,00 1000,00 31203030302C3030 -- work
1 230,00 1 230,00 31A03233302C3030 -- Not work
1 750,00 1 750,00 31A03735302C3030 -- Not work
4 000,00 4 000,00 34A03030302C3030 -- Not work
1 980,00 1 980,00 31A03938302C3030 -- Not work
1 050,00 1 050,00 31A03035302C3030 -- Not work
1 050,00 1 050,00 31A03035302C3030 -- Not work
1 000,00 1 000,00 31A03030302C3030 -- Not work
39 950,00 39 950,00 3339A03935302C3030 -- Not work
3 000,00 3 000,00 33A03030302C3030
...
...
I am trying to convert it into a number before inserting my data :
SELECT TO_NUMBER(REPLACE(qty, CHR(32), ''))
FROM table;
SELECT TO_NUMBER(REGEXP_REPLACE(qty, '\s'))
FROM table;
and I am getting an error :
ORA-01722: invalid number
How can i convert this column which is varchar / hex to numeric format?
Thank you.
add a Format mask and NLS information by using to_number function.
so it could look like:
select to_number('1 250,000','999G999G999D99999','NLS_NUMERIC_CHARACTERS='', ''') as n
from dual
if you check the hex value e.g. 31A03030302C3030 you can see the A0 on the second Position. that is displayed as empty string but is and not a space that has a hex Position 20 in ASCII table. So just replace that 160 with 32
to_number(replace('1 250,000',chr(160),chr(32)),'999G999G999D99999','NLS_NUMERIC_CHARACTERS='', ''') as n
result:
n
------
1250

SQL* Loader Handling formatted dates

I'm developing this solution where I'll receive a spool file and I need to insert it to a table.
I always use SQL* Loader and it fits well. But I never used it with dates. I'm getting this error as I'll show:
Control File
OPTIONS (ERRORS=999999999, ROWS=999999999)
load data
infile 'spool.csv'
append
into table A_CONTROL
fields terminated by ","
TRAILING NULLCOLS
(
AStatus,
ASystem,
ADate,
AUser,
)
spool.csv
foo,bar,2015/01/12 13:22:21,User
But when I run the loader I got this error
Column Name Position Len Term Encl Datatype
------------------------------ ---------- ----- ---- ---- ---------------------
AStatus FIRST * , CHARACTER
ASystem NEXT * , CHARACTER
ADate NEXT * , CHARACTER
AUser NEXT * , CHARACTER
Record 1: Rejected - Error on table A_CONTROL, column ADate.
ORA-01861: literal does not match format string
Table A_CONTROL:
0 Rows successfully loaded.
1 Row not loaded due to data errors.
0 Rows not loaded because all WHEN clauses were failed.
0 Rows not loaded because all fields were null.
Convert the string to date for insertion.
OPTIONS (ERRORS=999999999, ROWS=999999999)
load data
infile 'spool.csv'
append
into table A_CONTROL
fields terminated by ","
TRAILING NULLCOLS
(
AStatus,
ASystem,
ADate "TO_DATE(:ADate,'YYYY/MM/DD HH24:MI:SS')",
AUser,
)

Select part of a string from a object type column SQL

So shortly I am receiving an SQL Error: ORA-00932: inconsistent datatypes: expected NUMBER got OE.CUST_ADDRESS_TYP
00932. 00000 - "inconsistent datatypes: expected %s got %s" when I am trying to retrieve a part of a string data.
SELECT dbms_lob.SUBSTR(cus.cust_address, 0, INSTR(cus.cust_address, ',')-1) AS output
FROM oe.customers cus;
So basically that's my statement.
The data looks like : OE.CUST_ADDRESS_TYP('322 E Michigan St','53202','Milwaukee','WI','US')
And I only want to display the city, which in this case would be Milwaukee.
However, the data_type of cust_address column is set to CUST_ADDRESS_TYP which is an object column of type address_typ.
I just want to select part of a string for instance, I want to only select Milwaukee from OE.CUST_ADDRESS_TYP('322 E Michigan St','53202','Milwaukee','WI','US').
CUST_ADDRESS CUST_ADDRESS_TYP Yes 4 Object column of type address_typ.
This is how it is showed in the table.
Really buggers me off as the statement works on varchar type columns but not on this one.
Kind regards,
P.S. Fixed it by using the object type column, didn't use Treat tho. Thanks anyaway.
See object type request semantic in Oracle documentation:
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions198.htm
SQL> create type comp_type is object(
2 x varchar2(10)
3 , y varchar2(10)
4 )
5 /
SQL> create table t (col comp_type)
2 /
SQL> insert into t values(comp_type('A','B'))
2 /
SQL> commit
2 /
SQL> select treat(col as comp_type).x, treat(col as comp_type).y from t
2 /
TREAT(COLA TREAT(COLA
---------- ----------
A B