How to concatenate a tab in a DB2 view field? - sql

I've been attempting to create a Db2 (the database is hosted on an IBM i, running 7.3) view in which one of the fields (a character/char field) is constructed by concatenating several different pieces of data together. The catch is that between each of these fields of data, there needs to be a tab present which is used for delimiting the fields in a DataMatrix barcode.
The following link is an ASCII and EBCDIC character set that I'm using as a reference. I'm using the hexadecimal code for a horizontal tab as follows to try and concatenate the tabs in the character field that I'm constructing(e.g.):
select 'data1' || X'09' || 'data2' from
sysibm.sysdummy1;
Unfortunately, the only thing present, which results from the hexadecimal code (X'09') appears to be one single space, as follows:
Result set:
data1 data2
When I use the resulting field in the view to generate a 2D barcode, there are actually no spaces at all delimiting the fields (seen after scanning said barcode). What's the trick to actually getting a tab to be rendered in a Db2 view field? Is there a different code or function I should be using? I've also tried using char(05) and char(09), but to no avail. In addition, I've tried casting the hexadecimal code as a character, as follows, but with no success:
select 'data1' || cast(X'09' as CHAR) || 'data2' from
sysibm.sysdummy1;
Any thoughts or ideas would be much appreciated!

Try x'05' instead.
If you copy-past the following char sequence ("a" + "\tab" + "b") from some text editor, you get the result as described:
values hex('a b');
|00001 |
|------|
|810582|

Tou can use CHR() on both Db2 for LUW https://www.ibm.com/support/knowledgecenter/en/SSEPGG_11.5.0/com.ibm.db2.luw.sql.ref.doc/doc/r0000778.html
Returns the character that has the ASCII code value specified by the argument.
and Db2 for i https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_72/db2/rbafzscachr.htm
The CHR function returns the EBCDIC character that has the ASCII code value specified by the argument.
values 'A' || CHR(9) || 'B'
returns
1
---
A B

Related

Passing Same In Function but output are different

Facing issue with #Detail when passing value in function through string 'ABC' the getting correct output but when passing via variable then getting incorrect output. What i am doing wrong.
DECLARE #Detail varchar(4000)
SELECT #Detail = detail FROM table1
select #Detail
select * from dbo.SDF_SplitString(#Detail,' ',88)
INCORRECT OUTPUT
select * from dbo.SDF_SplitString(' 11/13/2019 12:15:0 11/13/2019 12:15:0 11/13/2019 14:30:0 BOM GOP SG 438 24A MR Kamleshwar Prasad 4',' ',88)
CORRECT OUTPUT
OK, so that query I had you run is showing that the character between 12:15:0 11/13/2019 is a TAB (ascii character 9), not a space (ascii character 32)
This is why you get the output you do; you should perhaps consider to replace tabs with spaces before you split, or upgrade your split function so you can pass multiple chars to it for splitting (I assume that's what the ' ' parameter is for)
When you copied your value out of SSMS results grid it swapped the tabs for spaces already (SSMS converted the tabs to spaces), so when you ran it, it "looked the right output" when using the hardcoded value that contained only spaces..
..but the data in the DB table definitely has tabs! Always be careful copying stuff out of SSMS results grid; it drops characters, changes characters and cuts longer data off at the end, so it cannot be guaranteed to be an accurate reflection of what is in the table.
select * from dbo.SDF_SplitString(REPLACE(#Detail, CHAR(9), ' '),' ',88)
should give the output you expect..
If you have the option of changing this field so it doesn't have delimited data in it would be safer; splitting can sometimes give unusable results if the positions change

Oracle RegEx in a Cast Procedure

I have a Cast Procedure for a table with "raw" data. Any time a record comes from any of our locations into the raw table, my procedure "cleans" the data and loads it into a new table. The original raw table is all varchars and my procedure converts date and number fields to the proper data types. From the clean table, a Java program selects any new records on a daily basis and FTPs them off in a file to another dept. Have just learned that a few of the fields accept input from users and on a rare occasion, someone uses a pipe in what they input. A pipe symbol happens to be the delimiter that the other dept is using and whenever a pipe shows up in the middle of a field, it throws a wrench on their end.
I've never used REGEX or REGEXP_REPLACE in Oracle before. There are only three fields where the users can input data - MISTINTCOMMENT, PALETTE, COLORID. How do I use REGEX or REGEXP_REPLACE to replace any pipes with a space? Do I want to do it on each field? Or is this something I should "wrap around" the entire statement (in case there's a field I missed where someone might be able to input a pipe)?
Here is the portion of the procedure where the Values are cleaned and inserted into new table. How to best use RegEx with this?
VALUES (CASE
WHEN THECOSTCENTER IS NOT NULL
THEN THECOSTCENTER
ELSE (SUBSTR(TRIM(THESENDING_QMGR), -6))
END,
CASE
WHEN THESTORENBR = '0' AND (SUBSTR(THESENDING_QMGR, 1, 5) = 'PDPOS')
THEN TO_NUMBER(SUBSTR(THESENDING_QMGR, 8, 4))
WHEN THESTORENBR = '0' AND (SUBSTR(THESENDING_QMGR, 1, 8) = 'PROD_POS')
THEN TO_NUMBER(SUBSTR(THESENDING_QMGR, 9, 4))
ELSE TO_NUMBER(NVL(THESTORENBR,'0'))
END,
TO_NUMBER(NVL(THECONTROLNBR,'0')), TO_NUMBER(NVL(THELINENBR,'0')), THESALESNBR, TO_NUMBER(NVL(THEQTYMISTINT,'0')), THEREASONCODE, THEMISTINTCOMMENT,
THESIZECODE, THETINTERMODEL, THETINTERSERIALNBR, TO_NUMBER(NVL(THEEMPNBR,'0')), TO_DATE(THETRANDATE,'YYYY-MM-DD'), THETRANTIME, THECDSADLFLD,
THEPRODNBR, THEPALETTE, THECOLORID, TO_DATE(THEINITTRANDATE,'YYYY-MM-DD'), TO_NUMBER(NVL(THEGALLONSMISTINTED,'0'),'999999999.99'), THEUPDATEEMPNBR,
TO_DATE(THEUPDATETRANDATE,'YYYY-MM-DD'), TO_NUMBER(NVL(THEGALLONS,'0'),'999999999.99'), THEFORMSOURCE, THEUPDATETRANTIME, THESOURCEIND,
TO_DATE(THECANCELDATE,'YYYY-MM-DD'), THECOLORTYPE, TO_NUMBER(NVL(THECANCELEMPNBR,'0')), TO_BOOLEAN(THENEEDEXTRACTED), TO_BOOLEAN(THEMISTINTMQXTR),
THEDATASOURCE, THETRANGUID, TO_NUMBER(NVL(THETERMNBR,'0')), TO_NUMBER(NVL(THETRANNBR,'0')), TO_NUMBER(NVL(THETRANID,'0')), THEID, THETINTABLESALESNBR,
TO_NUMBER(NVL(THERETURNQTY,'0')), THECREATED_TS, THEXMIT_GUID, THESENDING_QMGR, THEMSG_ID, THEPUT_TS,
THEBROKER_NAME, THECHECKSUM);
If you have to use a REGEXP_REPLACE to replace pipes, escape them:
REGEXP_REPLACE(x, '\|', ' ')
This is useful to know when your more complex expressions include a pipe.
In this case, REPLACE that performs literal text search and replace will suffice:
REPLACE(x, '|', ' ')

vertica UTF-8 character

I have a table with a column whose type is varchar(32) the value it has is
'Movies & TV' . This data is loaded by Copy command, when I query this table like
select * from activity where name='Movies & TV' (typed this value)
it won't return any record this is mainly because of & character there is something going on with this character.
When I tried
Select ISUTF8(name) from activity it returns true, which means the data is actually stored in the UTF-8 format.
Select length(name) and length('Movies & TV') are also same. However, when I paste these values in the vi editor and saw an extra space in the DB string. In addition, the field name in activity table can have Chines characters too, which is stored correctly in DB now.
Any idea what is going on here? Should I specify explicit UTF-8 when loading the data?
If you are doing it from SQLPLUS use
SET DEFINE OFF
to stop it treading & as a special case.
An alternate solution, use concatenation and the chr function:
SELECT * FROM activity WHERE name= 'Movies ' || chr(38) || ' TV';
Solution from:
How to insert a string which contains an "&"

Comma inside like query fails to return any result

Using Oracle db,
Select name from name_table where name like 'abc%';
returns one row with value "abc, cd" but when I do a select query with a comma before % in my like query, it fails to return any value.
Select name from name_table where name like 'abc,%';
returns no row. How can I handle a comma before % in the like query?
Example:
Database has "Sam, Smith" in the name column when the like has "Sam%" it returns one row, when i do "Sam,%" it doesn't return any row
NOT AN ANSWER but posting it as one since I can't format in a comment.
Look at this and use DUMP() on your own machine... see if this helps.
SQL> select dump('Smith, Stan') from dual;
DUMP('SMITH,STAN')
-----------------------------------------------------
Typ=96 Len=11: 83,109,105,116,104,44,32,83,116,97,110
If you count, the string is 11 characters (including the comma and the space). The comma is character 44, and the space is character 32. If you look at YOUR string and you don't see 44 where the comma should be, you will know that's the problem. You could then let us know what you see there (just for that character, I understand posting "Leno, Jay" would be a violation of privacy).
Also, make sure you don't have any extra characters (perhaps non-printable ones!) right before the comma. Just compare the two strings you are using as inputs and see where the differences may be.

Replace function doesn't work as expected

I'm having trouble figuring out why REPLACE() doesn't work correctly.
I'm getting a string formatted as:
RISHON_LEZION-CMTSDV4,Cable7/0/4/U1;RISHON_LEZION-CMTSDV4,Cable7/0/4/U2;RISHON_LEZION-CMTSDV4,Cable7/0/5/U0;.....
Up to 4000 characters .
Each spot of ; represent a new string(can be up to about 15 in one string). I'm splitting it by using REPLACE() - each occurence of ; replace with $ + go down a line + concat the entire string again (I have another part that is splitting down the string)
I think the length of the string is some how effecting the result, though I never heard replace has some kind of limitation about the length of the string.
SELECT REPLACE(HOT_ALERTKEY_PK, ';', '$' || CHR(13) || CHR(10) || HOT_ALERTKEY_PK || '$')
from (SELECT 'RISHON_LEZION-CMTSDV4,Cable7/0/3/U0;RISHON_LEZION-CMTSDV4,Cable7/0/3/U1;RISHON_LEZION-CMTSDV4,Cable7/0/3/U2;RISHON_LEZION-CMTSDV4,Cable7/0/4/U0;RISHON_LEZION-CMTSDV4,Cable7/0/4/U1;RISHON_LEZION-CMTSDV4,Cable7/0/4/U2;RISHON_LEZION-CMTSDV4,Cable7/0/5/U0;RISHON_LEZION-CMTSDV4,Cable7/0/5/U1;RISHON_LEZION-CMTSDV4,Cable7/0/5/U2;RISHON_LEZION-CMTSDV4,Cable7/0/7/U0;RISHON_LEZION-CMTSDV4,Cable7/0/7/U1;RISHON_LEZION-CMTSDV4,Cable7/0/7/U2;RISHON_LEZION-CMTSDV4,Cable7/0/9/U0;RISHON_LEZION-CMTSDV4,Cable7/0/9/U1;RISHON_LEZION-CMTSDV4,Cable7/0/9/U2' as hot_alertkey_pk
FROM dual)
This for some reason result in splitting the string correctly, up to cable7/0/5/U0; , and stops. If I remove one or more parts from the start of the string (up to the semicolumn is each part) then I'm getting it up to the next cables, according to how many I remove from the beggining.
Why is this happening ?
Thanks in advance.
If you wrap your sample input string within to_clob() in the inner query, and you wrap the resulting string within length() in the outer query, you will find that the result is 8127 characters. This answers your question, but only partially.
I am not sure why replace doesn't throw an error, or perhaps just truncate the result at 4000 characters. I got exactly the same result as you did in Oracle 11.2, with the result chopped off after 3503 characters. I just looked quickly at the Oracle documentation for replace() and it doesn't say what the behavior should be if the input is VARCHAR2 but the output is more than 4000 characters. It looks as though it performed as many substitutions as it could and then it stopped (the next substitution would have gone above 4000 characters).