My requirement is to encrypt varchar2 column and store that value again in that same column, and later again want to decrypt it and store actual value in same column .
I use dbms_crypto package but its encrypted value exceeds the length of the input column so I tried a compression function but did not achieve the result.
DECLARE
lv_input VARCHAR2(20) := 'shrikant';
lv_output VARCHAR2(200) ;
lv_out VARCHAR2(20);
lv_raw_again RAW(20) ;
BEGIN
dbms_output.put_line(lv_input||'lenth '||length(lv_input));
lv_output := rawtohex(DBMS_CRYPTO.encrypt(UTL_RAW.CAST_TO_RAW (lv_input), 4353,
UTL_RAW.CAST_TO_RAW ('zzzzzzzzz')));
dbms_output.put_line(lv_output||'length '||LENGTH(lv_output));
lv_raw_again := hextoraw(lv_output);
lv_out := utl_raw.cast_to_varchar2(dbms_crypto.Decrypt(src => lv_raw_again,
typ => 4353,
key => UTL_RAW.CAST_TO_RAW ('zzzzzzzzz') ));
dbms_output.put_line(lv_raw_again||'length '||LENGTH(lv_raw_again));
dbms_output.put_line(lv_out||LENGTH(lv_out));
END;
Here my input length is 8 and I want its encrypted result length also as 8 so I can store that value in that same field.
Related
BLOB to CLOB Conversion : Cyrillic characters are not getting converted properly
Based on our product migration, I have an requirement to replace below mentioned single byte character to Double byte character in each and every record but the respective column is BLOB datatype encoded with AL32UTF8 so I'm using the below procedure to convert column from BLOB to CLOB and replace the single byte character to Double byte character and convert back to CLOB to BLOB.
NLS_CHAR--> AL32UTF8
For ex:
when I tried with CL8ISO8859P5 character set in CLOB conversion function, Bulgarian data is corrupted and If I tried with AL32UTF8 character set then the respective Cyrillic character got corrupted.
select convert_to_clob(XMLRECORD) From F_TEC_OUTPUT_T
CLOB conversion with AL32UTF8 characterset:
ONE�АНУЛИРАНЕ НА ОПРОСТЕНА ФАКТУРА_�THREE
CLOB conversion with CL8ISO8859P5 characterset:
ONEўаааЃааа ааа аа ааа ааЁаЂааа аЄаааЂаЃа а_ўTHREE
select recid, dbms_lob.substr(XMLRECORD) as raw_xrec
from F_TEC_OUTPUT_T
[enter image description here][1]
Please suggest the proper way to convert this.
Single byte ---> Double byte
ў --> яЃО
§ --> яЃН
ќ --> яЃМ
In RAW:
FE --> EFA3BE
FD --> EFA3BD
FC --> EFA3BC
FB --> EFA3BB
l_clob CLOB;
l_dest_offset NUMBER := 1;
l_src_offset NUMBER := 1;
l_lang_context NUMBER := dbms_lob.default_lang_ctx;
l_warning NUMBER;
BEGIN
dbms_lob.createtemporary(l_clob, TRUE);
dbms_lob.converttoclob(dest_lob => l_clob,
src_blob => l_blob,
amount => dbms_lob.lobmaxsize,
dest_offset => l_dest_offset,
src_offset => l_src_offset,
blob_csid => nls_charset_id('CL8ISO8859P5'),
lang_context => l_lang_context,
warning => l_warning);
RETURN l_clob;
END convert_to_clob;
CREATE OR REPLACE FUNCTION convert_to_blob(l_clob CLOB) RETURN BLOB IS
l_blob BLOB;
l_dest_offset NUMBER := 1;
l_src_offset NUMBER := 1;
l_lang_context NUMBER := dbms_lob.default_lang_ctx;
l_warning NUMBER;
BEGIN
dbms_lob.createtemporary(l_blob, TRUE);
dbms_lob.converttoblob(dest_lob => l_blob,
src_clob => l_clob,
amount => dbms_lob.lobmaxsize,
dest_offset => l_dest_offset,
src_offset => l_src_offset,
blob_csid => nls_charset_id('AL32UTF8'),
lang_context => l_lang_context,
warning => l_warning);
RETURN l_blob;
END convert_to_blob;
CREATE OR REPLACE PROCEDURE convert_blob_file(p_tname in varchar2,parallel_no_cnt in number default 1,record_cmt_cnt in number default 1) IS
TYPE cur_typ IS REF CURSOR;
getcursordata cur_typ;
ConversionRecID VARCHAR2(2000);
BinaryValueSource BLOB;
BinaryValueDest BLOB;
BinaryValueTemp CLOB;
cnt NUMBER := 1;
Dicttablename VARCHAR2(2000);
Marker_R_count NUMBER := 0;
XmlrecordTemp CLOB;
Selectstring VARCHAR2(2000);
select_table_query VARCHAR2(1000):= 'SELECT /*+ PARALLEL('''||parallel_no_cnt||''') */ RECID,XMLRECORD FROM ' || p_tname || ' WHERE XMLRECORD IS NOT NULL';
BEGIN
OPEN getcursordata FOR select_table_query;
LOOP
FETCH getcursordata INTO ConversionRecID, BinaryValueSource;
EXIT WHEN getcursordata%NOTFOUND;
BinaryValueTemp := convert_to_clob(BinaryValueSource);
BinaryValueTemp := REPLACE(BinaryValueTemp,CHR(53662),CHR(15705022)); -- #FM Separator
BinaryValueTemp := REPLACE(BinaryValueTemp,CHR(49831),CHR(15705021)); -- #VM Separator
BinaryValueTemp := REPLACE(BinaryValueTemp,CHR(53660),CHR(15705020)); -- #SM Separator
BinaryValueTemp := REPLACE(BinaryValueTemp,CHR(53659),CHR(15705019)); -- #TM Separator
BinaryValueDest := convert_to_blob(BinaryValueTemp);
EXECUTE IMMEDIATE 'UPDATE /*+ PARALLEL('''||parallel_no_cnt||''') */'||p_tname||' SET XMLRECORD = :v1 WHERE RECID= :v2' USING BinaryValueDest,ConversionRecID;
IF cnt=record_cmt_cnt THEN
cnt:=1;
COMMIT;
ELSE
cnt := cnt + 1;
END IF;
END LOOP;
CLOSE getcursordata;
DBMS_OUTPUT.PUT_LINE('Time------'||to_char(sysdate, 'HH24:MI:SS'));
END;```
[1]: https://i.stack.imgur.com/t9w19.jpg
Delphi 10 with Firemonkey and SQLite: After running the code below I want to get the ID of the last record inserted into an SQLite table. How do I get the last ID?
NOTE: The ID field of Table 1 is autoincrement.
var myQr: TFDQuery;
begin
myQr := TFDQuery.Create(Self);
with myQr do begin
SQL.Add('Insert into table1 values (:_id, :_name, :_dthr)');
Params.ParamByName('_id').ParamType := TParamType.ptInput;
Params.ParamByName('_id').DataType := TFieldType.ftInteger;
Params.ParamByName('_id').Value := null;
ParamByName('_name').AsString := 'name test';
ParamByName('_dthr').AsDateTime := Now;
ExecSQL;
end;
// How to get last ID? <<<<<<<<<<<<<=================
myQr.DisposeOf;
You could query last_insert_rowid if your ID column is declared as INTEGER PRIMARY KEY. In such case the column becomes alias for the ROWID. If that is your case, you can query it natively e.g. this way:
uses
FireDAC.Phys.SQLiteWrapper;
function GetLastInsertRowID(Connection: TFDConnection): Int64;
begin
Result := Int64((TObject(Connection.CliObj) as TSQLiteDatabase).LastInsertRowid);
end;
Or in common way by calling GetLastAutoGenValue method:
function GetLastInsertRowID(Connection: TFDConnection): Int64;
begin
Result := Int64(Connection.GetLastAutoGenValue(''));
end;
I have a function, that calculates hash value of big string! First of all I wrote a cursor T1_CUT, which can include variable count of SELECT statements, something like:
SELECT T1.COL1||T1.COL2||...||T1.COLn FROM T1 WHERE id=documentid
SELECT T2.COL1||T2.COL2||...||T2.COLn FROM T2 WHERE id=documentid
...
SELECT Tn.COL1||Tn.COL2||...||Tn.COLn FROM Tn WHERE id=documentid
Each SELECT can contain one or more rows. So, I concat ALL values in rows in each SELECT and ALL SELECTs values in one big string V_RESULT with type VARCHAR2(32767). After that I get hash value (S_HASH_RESULT) of this big string using MD5. It works fine about 8 monthes, but few days ago I've got ORA-06502 (no surprise). It means, that my final big string have more than 32K symbols (we use 1byte character set - CL8MSWIN1251).
Friends, how can I rewrite my function for using BLOB data type to V_RESULT variable, not VARCHAR2(32767).
Below, text of my function:
FUNCTION CALC_HASH (P_PARTAB_ID IN NUMBER, P_DOC_ID IN NUMBER)
RETURN VARCHAR2
IS
S_HASH_RESULT VARCHAR2(1000);
V_RESULT VARCHAR2(32767);
CURSOR T1_CUT IS
...
/*BIG COMPLAIN SELECT*/
...
T1 T1_CUT%ROWTYPE;
TYPE VALUES_T IS TABLE OF VARCHAR2(32767);
L_VALUES VALUES_T;
BEGIN
OPEN T1_CUT;
FETCH T1_CUT INTO T1;
WHILE T1_CUT%FOUND
LOOP
EXECUTE IMMEDIATE
T1.TEXT
BULK COLLECT INTO L_VALUES;
FOR INDX IN 1 .. L_VALUES.COUNT
LOOP
V_RESULT := V_RESULT || '' ||TO_CHAR(L_VALUES (INDX));
END LOOP;
FETCH T1_CUT INTO T1;
END LOOP;
CLOSE T1_CUT;
S_HASH_RESULT := DBMS_OBFUSCATION_TOOLKIT.MD5(input_string=>V_RESULT);
RETURN S_HASH_RESULT;
END CALC_HASH;
Thanks in advance!
there is a function called utl_raw.cast_to_raw(vc) which transforms a varchar2 into a BLOB value.
However, I recommend to use CLOB to store string values. BLOB has no character semantics at all, i.e., NLS_LANG settings are ignored.
EDIT:
if you want to transform VARCHAR2 to CLOB, simply use TO_CLOB
DECLARE
l_string NVARCHAR2(600) := '123456';
checksum NVARCHAR2(600);
BEGIN
DBMS_OUTPUT.DISABLE;
DBMS_OUTPUT.ENABLE(1000000);
DBMS_OBFUSCATION_TOOLKIT.md5 (input_string => l_string, checksum_string => checksum);
DBMS_OUTPUT.PUT_LINE(RAWTONHEX(utl_raw.cast_to_raw(checksum)));
END;
Expected value: e10adc3949ba59abbe56e057f20f883e
But it returns: FFFD00390049FFFD0059FFFDFFFD0056FFFD000FFFFD003E
Note I want to maintain nvarchar2 datatype. The value from checksum variable gets stored in column that is of type nvarchar2.
I am aware that md5 accepts and returns data in varchar2. But if someone can help me figure this out using nvarchar2 data type, that would be great.
The NLS_CHARACTERSET = AL32UTF8
The following should work via dbms_crypto using hash()
declare
l_src nvarchar2(100) := '123456';
l_raw_hash raw(100);
begin
l_raw_hash := dbms_crypto.hash(to_clob(l_src), dbms_crypto.HASH_MD5);
dbms_output.put_line(l_raw_hash);
end;
Result: E10ADC3949BA59ABBE56E057F20F883E
l_raw_hash will be in raw format. You can use UTL_RAW to convert it to another datat type. Just make sure your display is showing the proper character set or thing will look interesting.
I have a column in my oracle table with CLOB datatype.
How do I store .txt file in this column and how can I retrieve the same file?
Below is the table definition
fileID Number
logFile CLOB
Thanks in advance
Loading a file into a CLOB in PL/SQL is pretty easy-- you just need to use the DBMS_LOB.LoadCLOBFromFile procedure
CREATE DIRECTORY file_dir
AS <<path on database server file system>>;
GRANT read, write
ON file_dir
TO your_user_name;
DECLARE
l_src_file bfile := BFileName( 'FILE_DIR', <<name of file>> );
l_dest_lob clob;
l_dest_offset integer := 1;
l_src_offset integer := 1;
l_lang_context number := dbms_lob.default_lang_ctx;
l_warning number;
BEGIN
dbms_lob.open( l_src_file, dbms_lob.lob_readonly );
INSERT INTO some_table( fileID, logFile )
VALUES( fileIDSeq.nextval, empty_clob() )
RETURNING logFile
INTO l_dest_lob;
dbms_lob.LoadCLOBFromFile(
dest_lob => l_dest_lob,
src_bfile => l_src_file,
amount => dbms_lob.getLength( l_src_file ),
dest_offset => l_dest_offset,
src_offset => l_src_offset,
bfile_csid => dbms_lob.default_csid,
lang_context => l_lang_context,
warning => l_warning );
dbms_lob.close( l_src_file );
END;
/
Writing the file from the CLOB to the file system again is a bit more involved. I would use something like Tom Kyte's clob_to_file procedure