I got some trouble with executing dynamic SQL with binding variables (in and out) via dbms_sql.
I always get an ORA-06502 but cannot get the reason.
I could reduce the SQL-snippet so far to know that the out parameter occurs the error.
declare
l_cur_id NUMBER;
l_sql VARCHAR2(100) := 'begin :1 := ''test''; end;';
l_res VARCHAR2(100);
l_dbms NUMBER;
begin
l_cur_id := dbms_sql.open_cursor;
dbms_sql.parse(l_cur_id, l_sql, dbms_sql.native);
dbms_sql.bind_variable(l_cur_id, '1', l_res);
l_dbms := dbms_sql.execute(l_cur_id); -- ORA here
dbms_sql.close_cursor(l_cur_id);
exception
when others then
dbms_sql.close_cursor(l_cur_id);
raise;
end;
/
In-parameters work fine.
I'm using Oracle Database 12 Enterprise Edition Release 12.1.0.2.0
Do I have to config the out-parameter in another way?
I'm thankful for any help.
You haven't specified a size for the bind variable. By default it uses the current length of the variable; from the documentation:
Parameter
Description
out_value_size
Maximum expected OUT value size, in bytes, for the VARCHAR2, RAW, CHAR OUT or IN/OUT variable. If no size is given, then the length of the current value is used. This parameter must be specified if the value parameter is not initialized.
As that variable is by default initialised as null, that length is zero; which is the same as saying it isn't initialised. So it errors when it tries to assign the four-character 'test' to to the zero-character variable.
You also need to call dbms_sql.variable_value to get retrieve the out bind variable value.
If you initialised l_res with a value at least as long as anything you might assign inside the dynamic block then it would work:
declare
...
l_res VARCHAR2(100) := 'xxxx';
...
begin
...
dbms_sql.bind_variable(l_cur_id, '1', l_res);
l_dbms := dbms_sql.execute(l_cur_id);
dbms_sql.variable_value(l_cur_id, '1', l_res);
...
end;
/
but that obviously ideal, as really you'd need to supply a value 100-chars long, and remember to adjust that if the length changed later; so instead specify the length in the bind call:
declare
...
l_res VARCHAR2(100);
...
begin
...
dbms_sql.bind_variable(l_cur_id, '1', l_res, 100);
l_dbms := dbms_sql.execute(l_cur_id);
dbms_sql.variable_value(l_cur_id, '1', l_res);
...
end;
/
db<>fiddle
I have a procedure
create or replace PROCEDURE PROC_PROJPREL_TEMPL_SERV_MAT(
P_TABELA IN VARCHAR2,
P_COLUNAS IN VARCHAR2,
P_DADOS IN CLOB,
O_CODIGO OUT NUMBER,
O_MENSAGEM OUT VARCHAR2
) IS
BEGIN
o_codigo := 0;
o_mensagem := '';
-- no implementation coded yet
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20101, 'erro ao executar procedure ');
END PROC_PROJPREL_TEMPL_SERV_MAT;
And I need to execute this in SQL Developer.
I tried using anonymous block
declare
i_tabela varchar2(30);
i_colunas varchar2(4000);
i_dados clob;
o_codigo number;
o_mensagem varchar2(4000);
begin
i_tabela := 'table_name'; -- max 30 characters
i_colunas := 'columns_names'; -- less 4000 characters
i_dados := '45000 characters';
proc_projprel_templ_serv_mat(i_tabela, i_colunas, i_dados, o_codigo, o_mensagem);
end;
But it returns an error "string literal too long"
and I tried using "call" command too.
call proc_projprel_templ_serv_mat('table_name', 'columns_names', &DATAS);
But it returns an error ORA-00972 identifier is too long, Cause: An identifier with more than 30 characters was specified, Action: Specify at most 30 characters.
Somebody can help me?
The maximum length of a string literal in PL/SQL is 32,767 characters. As the error "string literal too long" is saying, you're blowing out this limit here:
i_dados := '45000 characters';
You have to break up that string into sections up to 32,767 characters long and concatenate them together, e.g.:
i_dados := 'first 32767 characters' ||
'remaining 12233 characters';
what i need
i need to decrypt password store in database.
I tried sql
https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_crypto.htm#i1001225
sql
DECLARE
input_string VARCHAR2 (200) := 'Secret Message';
encrypted_answer_raw RAW(2000);
output_string VARCHAR2 (200);
encrypted_raw RAW (2000); -- stores encrypted binary text
decrypted_raw RAW (2000); -- stores decrypted binary text
num_key_bytes NUMBER := 256/8; -- key length 256 bits (32 bytes)
key_bytes_raw RAW (32); -- stores 256-bit encryption key
encryption_type PLS_INTEGER := -- total encryption type
DBMS_CRYPTO.ENCRYPT_AES256
+ DBMS_CRYPTO.CHAIN_CBC
+ DBMS_CRYPTO.PAD_PKCS5;
BEGIN
DBMS_OUTPUT.PUT_LINE ( 'Original string: ' || input_string);
key_bytes_raw := DBMS_CRYPTO.RANDOMBYTES (num_key_bytes);
encrypted_raw := DBMS_CRYPTO.ENCRYPT
(
src => UTL_I18N.STRING_TO_RAW (input_string, 'AL32UTF8'),
typ => encryption_type,
key => key_bytes_raw
);
-- The encrypted value "encrypted_raw" can be used here
debug_msg('encrypted_raw'||encrypted_raw);
Decryption code
Code Works
decrypted_raw := DBMS_CRYPTO.DECRYPT
(
src => encrypted_raw,
typ => encryption_type,
key => key_bytes_raw
);
output_string := UTL_I18N.RAW_TO_CHAR (decrypted_raw, 'AL32UTF8');
Code Doesn't works
encrypted_answer_raw:=utl_raw.cast_to_raw('989628CCF16292A73FEB63D4694C8129');
decrypted_raw := DBMS_CRYPTO.DECRYPT
(
src => encrypted_answer_raw,
typ => encryption_type,
key => key_bytes_raw
);
output_string := UTL_I18N.RAW_TO_CHAR (decrypted_raw, 'AL32UTF8');
DBMS_OUTPUT.PUT_LINE ('Decrypted string: ' || output_string);
END;
Error
Error report -
ORA-28817: PL/SQL function returned an error.
ORA-06512: at "SYS.DBMS_CRYPTO_FFI", line 67
ORA-06512: at "SYS.DBMS_CRYPTO", line 44
ORA-06512: at line 25
28817. 00000 - "PL/SQL function returned an error."
*Cause: A PL/SQL function returned an error unexpectedly.
*Action: This is an internal error. Enable tracing to find more
information. Contact Oracle customer support if needed.
*Document: NO
989628CCF16292A73FEB63D4694C8129 is database enrypted password stored in db.
any help is most welcome.
I suspect that instead of doing
encrypted_answer_raw := utl_raw.cast_to_raw('989628CCF16292A73FEB63D4694C8129');
you may want to do
encrypted_answer_raw := hextoraw('989628CCF16292A73FEB63D4694C8129');
I believe the problem is that the password is not really 989628CCF16292A73FEB63D4694C8129, but rather –(Ěńb’§?ëcÔiL) (displayed in win1250 codepage), despite your Oracle client software showing raw columns as hexa strings.
As a sidenote...
All those comments under your question, stating that you should store+compare password hashes instead of encrypting+decrypting them, are valid.
I am facing raw variable length too long issue when select the BLOB(Stored JSON string) filed value from the table.
Query:
select utl_raw.cast_to_varchar2(dbms_lob.substr(TRANSACTION_DATA)) from PS_ISA_INB_PAYLOAD_LOG;
This is my SP i have used to insert the JSON object into BLOB Field:
create or replace PROCEDURE SDIX_TICK_LOG
(
ORGANIZATIONNAME IN VARCHAR2
, TRANSACTION_TYPE IN VARCHAR2
, TRANSACTION_DATA IN BLOB
, TRANSACTION_STATUS IN VARCHAR2
) AS
l_r RAW(32767);
l_blob blob;
l_clob clob :='"ItemMasterTransfer":[{"ORACLE_UNIQUE_REC_ID":"123assd4434","CUSTOMER_ID":"PMC","ORGANIZATION_CODE":"BMftrdsM","ITEM":"696738","INVENTORY_ITEM_ID":"0000000000000000000000000000546","ORGANIZATION_ID":" ","SUBINVENTORY_CODE":"000000000000000000","LOCATOR_ID":" ","ISA_MATERIAL_GROUP":" ","TAX_GROUP":" ","CATEGORY_ID":"1956","NOUN":" ","MODIFIER":" ","MANUFACTURER_ID":" ","MFG_ITEM_ID":" ","UNIT_OF_MEASURE":"BOX","ITEM_TYPE":"P","STOCK_ENABLED_FLAG":"Y","INVENTORY_ITEM_STATUS_CODE":"A","LIST_PRICE_PER_UNIT":"0","FULL_LEAD_TIME":"0","MAX_MINMAX_QUANTITY":"10","MIN_MINMAX_QUANTITY":"10","SAFETY_LEVEL":"0","REPLENISH_TO_ORDER_FLAG":"N","UTILIZ_CD":"","CURRENCY_CD":"USD","DESCRIPTION":"","ATTRIBUTE1":" ","ATTRIBUTE2":" ","ATTRIBUTE3":" ","ATTRIBUTE4":" ","ATTRIBUTE5":" ","ATTRIBUTE6":" ","ATTRIBUTE7":" ","ATTRIBUTE8":" ","ATTRIBUTE9":" ","ATTRIBUTE10":" ","TRANSACTION_STATUS":" ","TRANS_STATUS_DESCRIPTION":" "},{"ORACLE_UNIQUE_REC_ID":"123assd4434","CUSTOMER_ID":"PMC","ORGANIZATION_CODE":"BMftrdsM","ITEM":"696738","INVENTORY_ITEM_ID":"0000000000000000000000000000546","ORGANIZATION_ID":" ","SUBINVENTORY_CODE":"000000000000000000","LOCATOR_ID":" ","ISA_MATERIAL_GROUP":" ","TAX_GROUP":" ","CATEGORY_ID":"1956","NOUN":" ","MODIFIER":" ","MANUFACTURER_ID":" ","MFG_ITEM_ID":" ","UNIT_OF_MEASURE":"BOX","ITEM_TYPE":"P","STOCK_ENABLED_FLAG":"Y","INVENTORY_ITEM_STATUS_CODE":"A","LIST_PRICE_PER_UNIT":"0","FULL_LEAD_TIME":"0","MAX_MINMAX_QUANTITY":"10","MIN_MINMAX_QUANTITY":"10","SAFETY_LEVEL":"0","REPLENISH_TO_ORDER_FLAG":"N","UTILIZ_CD":"","CURRENCY_CD":"USD","DESCRIPTION":"","ATTRIBUTE1":" ","ATTRIBUTE2":" ","ATTRIBUTE3":" ","ATTRIBUTE4":" ","ATTRIBUTE5":" ","ATTRIBUTE6":" ","ATTRIBUTE7":" ","ATTRIBUTE8":" ","ATTRIBUTE9":" ","ATTRIBUTE10":" ","TRANSACTION_STATUS":" ","TRANS_STATUS_DESCRIPTION":" "},{"ORACLE_UNIQUE_REC_ID":"123assd4434","CUSTOMER_ID":"PMC","ORGANIZATION_CODE":"BMftrdsM","ITEM":"696738","INVENTORY_ITEM_ID":"0000000000000000000000000000546","ORGANIZATION_ID":" ","SUBINVENTORY_CODE":"000000000000000000","LOCATOR_ID":" ","ISA_MATERIAL_GROUP":" ","TAX_GROUP":" ","CATEGORY_ID":"1956","NOUN":" ","MODIFIER":" ","MANUFACTURER_ID":" ","MFG_ITEM_ID":" ","UNIT_OF_MEASURE":"BOX","ITEM_TYPE":"P","STOCK_ENABLED_FLAG":"Y","INVENTORY_ITEM_STATUS_CODE":"A","LIST_PRICE_PER_UNIT":"0","FULL_LEAD_TIME":"0","MAX_MINMAX_QUANTITY":"10","MIN_MINMAX_QUANTITY":"10","SAFETY_LEVEL":"0","REPLENISH_TO_ORDER_FLAG":"N","UTILIZ_CD":"","CURRENCY_CD":"USD","DESCRIPTION":"","ATTRIBUTE1":" ","ATTRIBUTE2":" ","ATTRIBUTE3":" ","ATTRIBUTE4":" ","ATTRIBUTE5":" ","ATTRIBUTE6":" ","ATTRIBUTE7":" ","ATTRIBUTE8":" ","ATTRIBUTE9":" ","ATTRIBUTE10":" ","TRANSACTION_STATUS":" ","TRANS_STATUS_DESCRIPTION":" "}],"Organization":"PMC Biogenix","SharedSecret":"sTc1QowIu5Iy1Qt8iilnmQ==","TimeStamp":"09/28/2018 00:19:21","RowsSent":"1"}';
l_amt integer := dbms_lob.lobmaxsize;
l_dest_offset integer := 1;
l_src_offset integer := 1;
l_csid integer := dbms_lob.default_csid;
l_ctx integer := dbms_lob.default_lang_ctx;
l_warn integer;
BEGIN
dbms_lob.createTemporary( l_blob, false );
dbms_lob.convertToBlob( l_blob,
l_clob,
l_amt,
l_dest_offset,
l_src_offset,
l_csid,
l_ctx,
l_warn );
INSERT INTO PS_ISA_INB_PAYLOAD_LOG Values(ORGANIZATIONNAME,TRANSACTION_TYPE,l_blob,SYSDATE,TRANSACTION_STATUS);
END SDIX_TICK_LOG;
Your problem lies here: DBMS_LOB.SUBSTR()
DBMS_LOB is using VARCHAR2 internally, and VARCHAR2 has limit of 2000 chars. Your blob has the size of 2829 chars, therefore it is too long to be processed by DBMS_LOB.SUBSTR() at once.
You can test this by these commands:
Take only first 2000 chars from BLOB:
select utl_raw.cast_to_varchar2(dbms_lob.substr(TRANSACTION_DATA), 2000, 1) from PS_ISA_INB_PAYLOAD_LOG;
OK.
Take 2001 chars from BLOB:
select utl_raw.cast_to_varchar2(dbms_lob.substr(TRANSACTION_DATA, 2001, 1)) from PS_ISA_INB_PAYLOAD_LOG;
Error report -
SQL Error:
ORA-06502: PL/SQL: numeric or value error: raw variable length too long
ORA-06512: at line 1
06502.00000 - "PL/SQL: numeric or value error%s"
Is that possible to select entire BLOB Field value?
Basically, no. You'll need a PL/SQL function similar to the one you've already described, except this time, it will go BLOB-to-CLOB. You can call that from SQL, if it returns a CLOB or a VARCHAR2(4000).
As a side note, I question why you're taking JSON, which is character data, and storing it as a BLOB, then wanting to get character data back. Why not just store it as a CLOB in the first place?