ORA - 00972 : identifier too long - oracle

I am getting error (ORA - 00972 : identifier too long) while creating the view.
Please find the view statement.
create or replace view ELVW_ATM_REC_HANDOFF_1
(Rectype
,Recseq
,Record_Type
,Record_Sequence
,MESSAGE_TYPE
,PAN
,PROCESSING_CODE
,TRANSACTION_AMOUNT
,TRANSACTION_CURRENCY_CODE
,SETTLEMENT_AMOUNT
,SETTLEMENT_CURRENCY_CODE
,Billing_AMOUNT
,Billing_CURRENCY_CODE
,Transaction_DATE
,Settlement_Date
,TRACE
,REFERENCE_NUMBER
,Switch_Log_ID
,AUTHORIZATION_NUMBER
,RESPONSE_CODE
,Host_Error_Code
,TERMINAL_ID
,Acceptor_ID
,ACQUIRING_INSTITUTION_CODE
,REV_FLAG
,Original_Trace_Number
,From_Account
,To_Account)
as
select * from
(select 'FT'
,'count'
,'DT'
,rownum
,msg_type
,pan,proc_code
,txn_amt
,txn_ccy_code
,setl_amt
,setl_ccy_code
,bill_amt
,bill_ccy_code
,trans_dt_time
,setl_date
,stan,trn_ref_no
,'iso field 60'
,'isofield 38'
,resp_code
,error_code
,term_id
,'ISOmessage42'
,acq_ins_id
,decode(substr(msg_type,1,1),4,reverse(msg_type),msg_type)
,'ISOfield90'
,from_acc
,to_acc
from swtb_txn_log)
It seems error occurs at the decode function. if i comment it. its working fine. Please find the below code
create or replace view ELVW_ATM_REC_HANDOFF_1(Rectype,Recseq,Record_Type,Record_Sequence,MESSAGE_TYPE,PAN,PROCESSING_CODE,TRANSACTION_AMOUNT,TRANSACTION_CURRENCY_CODE,SETTLEMENT_AMOUNT,SETTLEMENT_CURRENCY_CODE,Billing_AMOUNT,Billing_CURRENCY_CODE,Transaction_DATE,/*Transaction_TIME,*/Settlement_Date,TRACE,REFERENCE_NUMBER,Switch_Log_ID,AUTHORIZATION_NUMBER,RESPONSE_CODE,Host_Error_Code,TERMINAL_ID,Acceptor_ID,ACQUIRING_INSTITUTION_CODE,/*REV_FLAG,*/Original_Trace_Number,From_Account,To_Account) as
select * from (select 'FT','count','DT',rownum,msg_type,pan,proc_code,txn_amt,txn_ccy_code,setl_amt,setl_ccy_code,bill_amt,bill_ccy_code,trans_dt_time,/*trans_dt_time,*/setl_date,stan,trn_ref_no,'iso field 60',
'isofield 38',resp_code,error_code,term_id,'ISOmessage42',acq_ins_id,/*decode(substr(msg_type,1,1),4,reverse(msg_type),msg_type),*/'ISOfield90',from_acc,to_acc from swtb_txn_log)
I have checked the length of the column name. Its less than 30 characters. Looking forward for your help.

Try giving an alias (that is shorter than 30 characters) to the DECODE function.
Example:
DECODE( ...stuff... ) MYALIAS

True, all of the column names in the view spec are less than thirty characters.
Howver, your view includes a inline query:
select * from ( select ...
This may be the problem. Because it may be trying to work out at identifier for DECODE() statement at that intermediate point. I say "may" because I can't reproduce this on my 10g box: defining column names for the view solves the ORA-01948.
Regardless, you can fix the problem simply by giving your DECODE() column an alias which is of an acceptable length.

Related

ORA-01722: invalid number When I try to execute an store procedure. Oracle error

I know ORA-01722 occurs when I try to convert an invalid character to number. For example: "a123". In this case I only try to make a where condition, where the parameter is the ID of the table and the parameter is defined based on table type.
PROCEDURE SP_CPR_AGRUPAR_COMPRA(ID_SOLICITUD IN cpr_solicitud.id%type, ID_GRUPO IN cpr_solicitud.ID_GRUPO%type ) AS
BEGIN
UPDATE cpr_solicitud
SET ID_GRUPO=ID_GRUPO
WHERE id=ID_SOLICITUD;
END SP_CPR_AGRUPAR_COMPRA;
I try to format the ID_SOLICITUD with TO_NUMBER function but the error continue. Something like this:
UPDATE cpr_solicitud
SET ID_GRUPO=ID_GRUPO
WHERE id=TO_NUMBER(ID_SOLICITUD);
I did a test passing directly the information and it works.
UPDATE cpr_solicitud SET ID_GRUPO = 18 WHERE id = 942000;
I did many test and the conclusion is that the error is related to the ID_SOLICITUD parameter. I don't why but if I pass the ID_GRUPO and I leave the ID_SOLICITUD it works.
It's works:
UPDATE cpr_solicitud
SET ID_GRUPO=ID_GRUPO
WHERE id=1
It's not works:
UPDATE cpr_solicitud
SET ID_GRUPO=1
WHERE id=TO_NUMBER(ID_SOLICITUD);
As stated in the documentation:
If a SQL statement references a name that belongs to both a column and either a local variable or formal parameter, then the column name takes precedence.
Caution: When a variable or parameter name is interpreted as a column name, data can be deleted, changed, or inserted unintentionally.
In your code,
SET ID_GRUPO=ID_GRUPO
clearly falls into that warning, as #Bob hinted. Every row that matched the filter would be updated with it's current value (i.e. nothing changes), not the value passed into the procedure. As you've confirmed in a comment that the table has a column called ID_SOLICITUD too, so does:
WHERE id=ID_SOLICITUD;
You are getting the error because it is implicitly converting the column value from ID_SOLICITUD - which is presumably not numeric - to a number so it can be compared with id. The ID_SOLICITUD parameter value is not being used, so its data type isn't relevant. You are effectively doing:
UPDATE cpr_solicitud
SET cpr_solicitud.ID_GRUPO=cpr_solicitud.ID_GRUPO
WHERE cpr_solicitud.id=cpr_solicitud.ID_SOLICITUD;
which clearly isn't what you intended. If you run that statement on its on you'll get the same error.
You can either prefix the variable names with the object they actually belong to:
PROCEDURE SP_CPR_AGRUPAR_COMPRA(ID_SOLICITUD IN cpr_solicitud.id%type, ID_GRUPO IN cpr_solicitud.ID_GRUPO%type ) AS
BEGIN
UPDATE cpr_solicitud
SET ID_GRUPO=SP_CPR_AGRUPAR_COMPRA.ID_GRUPO
WHERE id=SP_CPR_AGRUPAR_COMPRA.ID_SOLICITUD;
END SP_CPR_AGRUPAR_COMPRA;
or (more simply and safely, perhaps) change the names, e.g. with a simple prefix:
PROCEDURE SP_CPR_AGRUPAR_COMPRA(p_ID_SOLICITUD IN cpr_solicitud.id%type, p_ID_GRUPO IN cpr_solicitud.ID_GRUPO%type ) AS
BEGIN
UPDATE cpr_solicitud
SET ID_GRUPO=p_ID_GRUPO
WHERE id=p_ID_SOLICITUD;
END SP_CPR_AGRUPAR_COMPRA;

How to use REGEXP_REPLACE to remove parameters from function?

Image Here
I have a column that stores C# codes, how do I remove the last 3 parameters of the "FunctionA"? Note that the column contains multiple functions, but I only need to replace "FunctionA" using PL/SQL, I know REGEXP_REPLACE might do the trick, but I can't seem to find a way to match/replace it.
Before:
Test=FunctionA(varID, 1234,"", A.B,"","","last");
Test=FunctionA(varID, 9876,"", C.D);
Test=FunctionB(varID, 5555,"", E.F,"","","last");
After:
Test=FunctionA(varID, 1234,"", A.B);
Test=FunctionA(varID, 9876,"", C.D);<- should not affect this
Test=FunctionB(varID, 5555,"", E.F,"","","last");<- should not affect this
Try finding this pattern:
(,[^,]*,[^,]*,[^,]*\);)$
And then replace with just );. Here is a sample query:
SELECT
REGEXP_REPLACE ('Test=FunctionA(varID, 1234,"", A.B,"","","last");',
'(,[^,]*,[^,]*,[^,]*\);)$', ');') AS output
FROM dual
WHERE col LIKE 'Test=FunctionA(%'
Test=FunctionA(varID, 1234,"", A.B);
Demo
Edit: I added a WHERE clause which checks the function name.

how acess the report column value in oracle-apex?

I need the "elabora prenotazione" button to be shown only when the column "stato prenotazione" is "IN SOSPESO"
I tried to set a condition but I don't know how to pick the column value
If I understand your question, this could help:
For the source of your report:
SELECT
CASE
WHEN stato_prenotazione = 'in sospeso' THEN 'elabora prenotazione'
ELSE ''
END name_of_column,
prenotazione,
username,
nome,
cognome,
viaggio,
stato_viaggio,
data_prenota,
stato_prenotazione,
numero_ospiti
FROM your_table
Then set the column "name_of_column" to type: link, and fill the target.
Wrap a condition around a call to apex_page.get_url within your SQL, so it will only produce a link when relevant
Example of function in use, sans condition:
https://azureoutput.wordpress.com/2017/10/18/custom-hyperlink-in-interactive-report/
Use this to make the button look prettier, and maybe get some other ideas
https://www.grassroots-oracle.com/2015/12/tutorial-include-action-button-in-report.html
See this in regard to escaping special characters, otherwise you'll just see HTML in your report
https://www.grassroots-oracle.com/2017/01/escape-special-characters-apex-demo.html
This could be resolved by a simple case statement as #sara mentioned.
something like:
select (case stato_prenotazione when 'in sospeso' then 'elabora prenotazione' end) as your_column
I would not keep else condition so that the column will simply contain null value if the condition is not met.

How to get record data from locate?

In VFP 6 I have a table called "cars" and inside a button I want to find an ID based on the name. What did I do wrong?
... code
SELECT cars
LOCATE FOR ALLTRIM(UPPER(name)) = variable_read_from_textbox
IF NOT FOUND()
messagebox("not found")
ELSE
messagebox(cars.id_car)
ENDIF
Running the code works ok when the name is not found but when it is found it errors out.
Thanks!
Your code is right in general. Slight modification for safety and fix for error:
SELECT cars
* this implies an exact match, regardless of set exact, and makes casing same
* remember this wouldn't use an index unless there is an index with the same signature
LOCATE FOR ALLTRIM(UPPER(name)) == ALLTRIM(UPPER(m.variable_read_from_textbox))
IF NOT FOUND()
messagebox("not found")
ELSE
messagebox(transform(cars.id_car))
ENDIF
As far as I remember, in VFP6, messagebox() was not yet capable transforming the value to string for you and expects a string (you didn't tell what the error is but that should be it).
A little caution about your search.
ALLTRIM(UPPER(name))
will NOT use an index, unless there is an index with key "ALLTRIM(UPPER(name))". If there is, it would be used, but such an index is actually useless because of the alltrim(). A better index would simply be:
Upper(name)
and then your search would look like:
variable_read_from_textbox = ALLTRIM(UPPER(m.variable_read_from_textbox))
SET EXACT ON
SELECT cars
LOCATE FOR UPPER(name) = m.variable_read_from_textbox
IF NOT FOUND()
...

pg: exec_params not replacing parameters?

First time using pg gem to access postgres database. I've connected successfully and can run queries using #exec, but now building a simple query with #exec_params does not seem to be replacing parameters. I.e:
get '/databases/:db/tables/:table' do |db_name, table_name|
conn = connect(db_name)
query_result = conn.exec_params("SELECT * FROM $1;", [table_name])
end
results in #<PG::SyntaxError: ERROR: syntax error at or near "$1" LINE 1: SELECT * FROM $1; ^ >
This seems like such a simple example to get working - am I fundamentally misunderstanding how to use this method?
You can use placeholders for values, not for identifiers (such as table and column names). This is the one place where you're stuck using string interpolation to build your SQL. Of course, if you're using string wrangling for your SQL, you must be sure to properly quote/escape things; for identifiers, that means using quote_ident:
+ (Object) quote_ident(str)
Returns a string that is safe for inclusion in a SQL query as an identifier. Note: this is not a quote function for values, but for identifiers.
So you'd say something like:
table_name = conn.quote_ident(table_name)
query_result = conn.exec("SELECT * FROM #{table_name}")

Resources