How do I add unprintable ascii control characters to a VARCHAR2 in Oracle PL/SQL? - oracle

I am supporting a label printing system which uses PL/SQL and an ORACLE database to fill in values that are then encoded in various barcodes (among other things). For a specific 2 dimensional data matrix barcode I'm attempting to create, I need to include some unprintable characters as control characters for the system that is scanning the barcode.
The problem is that I have no idea how to encode those characters.
Example:
v_string VARCHAR2(1000);
...
v_string := '[)><RS>06<GS>12SC<GS>16S2'||'<GS>V'||:(IN:-SPLR-)||'<GS>3S'||v_serial||'<GS>P'||:(IN:-CUSTITEM-)||'<GS>Q'||v_boxqty||'<GS>1T'||:(IN:-LOT-)||'<GS>15K123456789123'||:(IN:-PRODSEQ-)||'<RS><EOT>';
Then v_string is passed as a parameter to a function that actually populates the barcode on the printed label. The problem is that every <GS>, <RS>, and <EOT> in the string are supposed to be control characters. I have the ascii decimal and hex values for those control characters, but no idea how to add them into the above string instead of the placeholders.
Any help would be appreciated.

You can use the chr() function to supply individual ASCII characters:
CHR returns the character having the binary equivalent to n as a VARCHAR2 value in either the database character set or, if you specify USING NCHAR_CS, the national character set.
(You can also use unistr() for Unicode characters, but that doesn't seem to be necessary in this case; but note the ASCII/EBCDIC message in the chr() document...)
For those control characters you can use chr(4), chr(29) and chr(30):
v_string := '[)>'||chr(30)||'06'||chr(29)||'12SC'||chr(29)||'16S2'||chr(29)||'V'||:(IN:-SPLR-)||chr(29)||'3S'||v_serial||chr(29)||'P'||:(IN:-CUSTITEM-)||chr(29)||'Q'||v_boxqty||chr(29)||'1T'||:(IN:-LOT-)||chr(29)||'15K123456789123'||:(IN:-PRODSEQ-)||chr(30)||chr(4);
db<>fiddle showing the generated string - the printable parts, anyway - and it's dumped value, so you can see the 4/29/30 characters are actually there.
You could also build your string as you have it, then pass it through replace() to replace the <GS> etc. placeholders with the chr() values.

If you have the ASCII value, you can use the CHR function to construct your string, as in:
v_string:='xx'||chr(10).....

Related

When using a convert char to ASCII value routine, need to find out what values it is actually returning as they are not strictly ascii

When testing my code that uses a routine that checks for chars to show using an ASCII value routine, my program should drop control chars but keep chars that may be entered by the user. It seems that while the ASCII value routine is called "ascii", it does not just return ascii values: giving it a char of ƒ returns 402.
For example have found this web site
but it doesn't have ƒ 402 that I can see.
Need to know whether there are other ascii codes above 402 that I need to test my code with. The character set used internally by the software that 'ascii' is written in uses UCS2. The web site found doesn't mention USC2.
There are probably many interpretations ouf »Control Character« out there, but I'll assume you mean C0 and C1 control characters (includes references to the relevant Unicode Standards).
The commonly used 32-bit integer representation of Unicode characters in general is the codepoint notation: »U+« followed by a at least 4 digit positive hex number, which you will find near mentions of characters, e.g. as in »U+007F (delete)«. The result of your »ASCII value« routine will probably be this number without the »U+«;
UCS-2 is a specific encoding for Unicode characters, which you probably won't need to care about directly), and is equivalent to Unicode codepoints for all characters within the the range of the BMP only.

PLSQL - convert UTF-8 NVARCHAR2 to VARCHAR2

I have a table with a column configured as NVARCHAR2, I'm able save the string in UTF-8 without any issues.
But the application the calls the value does not fully support UTF-8.
This means that the string is passed to the database and back after the string is converted into HTML letter code. Each letter in the string is converted to such HTML code.
I'm looking for an easier solution.
I've considered converting it to BASE64, but it contains various characters which are considered illegal in the application.
In addition tried using HEXTORAW & RAWTOHEX.
None of the above helped.
If the column contains 'κόσμε' I need to find a way to convert/encode it to something else, but the decode should be possible to do from the HTML running the application.
Try using ASCIISTR function, it will convert it in something similar as JSON encodes unicode strings (it's actually the same, except "\" is used instead of "\u") and then when you receive it back from front end try using UNISTR to convert it back to unicode.
ASCIISTR: https://docs.oracle.com/cd/B28359_01/server.111/b28286/functions006.htm
UNISTR: https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions204.htm
SELECT ASCIISTR(N'κόσμε') FROM DUAL;
SELECT UNISTR('\03BA\1F79\03C3\03BC\03B5') FROM DUAL;

PL/SQL Apply Same Functions More Than Once

There is an encoding problem at existing Oracle database. From Java side, I apply these and fix it:
textToEscape = textToEscape.replace(/ö/g, 'ö');
textToEscape = textToEscape.replace(/ç/g, 'ç');
textToEscape = textToEscape.replace(/ü/g, 'ü');
textToEscape = textToEscape.replace(/ÅŸ/g, 'ş');
textToEscape = textToEscape.replace(/Ä/g, 'ğ');
There is a procedure which retrieves data from database. I want to write a function and apply that replace sequence inside it. I found that link:
https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions134.htm
However I want to apply consequent replaces. How can I chain them?
you can use Oracle CONVERT function to convert data into correct character set (compatible with your JAVA charset) inside database procedure itself.
That should handle all cases for you.
Assuming your database character set is AL32UTF8, The malformed characters that you see stem from a repeated conversion of an 8-bit character set encoding (presumably iso-8859-9 [Turkish]) to unicode in the utf-8 representation. The second of these conversions, of course, has been applied erroneously to the byte sequence that constituted the valis utf representation of your data.
You can reverse this within the database using the utl_raw package. Say tab.col contains your data, the following statement rectifies it.
update tab set col = utl_raw.cast_to_varchar2 ( utl_raw.convert ( utl_raw.cast_to_raw ( col ), 'WE8ISO8859P9', 'AL32UTF8' ) );
The casts retag the type of the character data which effectively allows for operating on the underlying octet (byte) sequence. on this level, the eroneus utf-8 mapping is invereted. since the result is still a valid representation in the database character set, a simple re-cast delivers the result.

Double Quotes in ASCII

What is the ASCII number for the double quote? (")
Also, is there a link to a list anywhere?
Finally, how do you enter it in the C family (esp. C#)
The ASCII code for the quotation mark is 34.
There are plenty of ASCII tables on the web. Note that some describe the standard 7-bit ASCII code, while others describe various 8-bit extensions that are super-sets of ASCII.
To put quotation marks in a string, you escape it using a backslash:
string msg = "Let's just call it a \"duck\" and be done with it.";
To put a quotation mark in a character literal, you don't need to escape it:
char quotationMark = '"';
Note: Strings and characters in C# are not ASCII, they are Unicode. As Unicode is a superset of ASCII the codes are still usable though. You would need a Unicode character table to look up some characters, but an ASCII table works fine for the most common characters.
It's 34. And you can find a list on Wikipedia.
yes, the answer the 34
In order to find the ascii value for special character and other alpha character I'm writing here small vbscript. In a note pad, write the below script save as abc.vbs(any name with extention .vbs) double click on the file to execute and you can see double quotes for 34.
For i=0 to 150
msgbox i&"="&char(i)
next
you are never going to need only 1 quote, right?
so I declare a CHAR variable i.e
char DoubleQuote;
then drop in a double quote
Convert.ToChar(34);
so use the variable DoubleQuote where you need it
works in SQL to generate dynamic SQL but there you need
DECLARE #SingleQuote CHAR(1)
and
SET #SingleQuote=CHAR(39)

Importing extended ASCII into Oracle

I have a procedure that imports a binary file containing some strings. The strings can contain extended ASCII, e.g. CHR(224), 'à'. The procedure is taking a RAW and converting the BCD bytes into characters in a string one by one.
The problem is that the extended ASCII characters are getting lost. I suspect this is due to their values meaning something else in UTF8.
I think what I need is a function that takes an ASCII character index and returns the appropriate UTF8 character.
Update: If I happen to know the equivalent Oracle character set for the incoming text can I then convert the raw bytes to UTF8? The source text will always be single byte.
There's no such thing as "extended ASCII." Or, to be more precise, so many encodings are supersets of ASCII, sharing the same first 127 code points, that the term is too vague to be meaningful. You need to find out if the strings in this file are encoded using UTF-8, ISO-8859-whatever, MacRoman, etc.
The answer to the second part of your question is the same. UTF-8 is, by design, a superset of ASCII. Any ASCII character (i.e. 0 through 127) is also a UTF-8 character. To translate some non-ASCII character (i.e. >= 128) into UTF-8, you first need to find out what encoding it's in.

Resources