oracle open cursor with string variable gives me errors - oracle

I have problems with opening cursor with string variable
here is my oracle database code
FUNCTION f_get_cursor(p_date_to_forecast VARCHAR) RETURN SYS_REFCURSOR AS
v_cursor SYS_REFCURSOR;
v_groupby_stmt VARCHAR(200) := 'GROUP BY '
|| CASE WHEN p_date_to_forecast = 'HOLIDAY' THEN
'DAY, ' ELSE '' END
|| 'TNI, FRMP, LR, HH;';
v_select_stmt VARCHAR2(1000) := 'SELECT WEEKDAY, TNI, FRMP, LR, HH,
AVG(Coalesce(VOLUME, 0)) AS AverageVolume
FROM (SELECT v.TNI, v.FRMP, v.LR, v.DAY,
v.HH, v.VOLUME, CASE WHEN
hd.HOLIDAY_DATE is not null
then ''HOLIDAY''
ELSE trim(to_char(v.DAY, ''Day''))
END AS WEEKDAY
FROM v_nem_rm16 v
LEFT JOIN DBP_ADMIN.DBP_HOLIDAY hd
ON v.DAY = hd.HOLIDAY_DATE
WHERE v.STATEMENT_TYPE !=''FORCAST'')
WHERE WEEKDAY = ''' || p_date_to_forecast
|| '''' || ' ' || v_groupby_stmt;
BEGIN
OPEN v_cursor FOR v_select_stmt;
return v_cursor;
END;
I am just trying to open cursor based on the parameter "p_date_to_forcast", which is just string of the name of the week like "Saturday, Tuesday..and so on" and return the cursor.
When I run the query, I got this error
00911. 00000 - "invalid character"
*Cause: identifiers may not start with any ASCII character other than
letters and numbers. $#_ are also allowed after the first
character. Identifiers enclosed by doublequotes may contain
any character other than a doublequote. Alternative quotes
(q'#...#') cannot use spaces, tabs, or carriage returns as
delimiters. For all other contexts, consult the SQL Language
Reference Manual.
*Action:
What is the problem and How can I fix it???
thanks

Have you tried this
for r_cur in your_cursor_name(Your_parameter) Loop
-- your working --
End loop;

Related

Error code ORA-00933 for my stored procedure

I get the following error message in a stored procedure that I created:
ORA-00933: SQL command not properly ended
ORA-06512: at line 11
I have tried Googling it, but could not find anything applicable as it tells my to try to eliminate any 'ORDER BY'.
declare
cursor a_tab is
select table_name
from all_tables
where owner = 'OFFERINGWORKSPACE'
and (TABLE_NAME like 'EBA_%' or TABLE_NAME = 'SURVEY_2.0');
v_tab_name varchar2(500);
begin
open a_tab;
loop
fetch a_tab into v_tab_name;
exit when a_tab%notfound;
EXECUTE IMMEDIATE 'delete ' || v_tab_name;
end Loop;
close a_tab;
open a_tab;
Loop
fetch a_tab into v_tab_name;
Exit when a_tab%notfound;
EXECUTE IMMEDIATE 'insert into ' || v_tab_name || '(select * from OFFERINGWORKSPACE.'||v_tab_name ||')';
End Loop;
Close a_tab;
End;
There is a clue in your cursor query:
... TABLE_NAME = 'SURVEY_2.0');
The period in that breaks the database object naming rules:
Nonquoted identifiers can only contain alphanumeric characters from your database character set and the underscore (_). Database links can contain periods (.) and "at" signs (#).
so that table name must be a quoted identifier. You therefore need to quote it in your statements:
EXECUTE IMMEDIATE 'delete "' || v_tab_name || '"';
and
EXECUTE IMMEDIATE 'insert into "' || v_tab_name
|| '"(select * from OFFERINGWORKSPACE."'||v_tab_name ||"')';
db<>fiddle showing the errors from those commands (simplified to one schema, and static SQL), and how adding the double quotes fixes them.

DB Links as Parameters in a Function

I'm creating a function that accepts two parameters. And one of my parameter will serve as the database link for my statement. I've tried concatenating it. How will I be able to achieve this?
It shows this error
ORA-00923: FROM keyword not found where expected ORA-06512 at
"NOINK.CHECK_SECOND_REF_DIE", line 13.
Below is the code.
drop function check_second_ref_die;
create or replace function check_second_ref_die(lotNumber in VARCHAR2, db_link in VARCHAR2)
return varchar2
is
row_count NUMBER;
sql_statement VARCHAR2(300);
BEGIN
sql_statement := 'SELECT COUNT(*) FROM wcrepo.WCR_WAFER_REFERENCE#lepftds.itg.ti.com
WHERE waferconfigfile = (SELECT waferconfigfile FROM program_setup_rev#' || db_link ||
'WHERE device = (SELECT device FROM noink.lot WHERE lot_num = ' ||lotNumber || ')
AND setup_cnt=0) AND status =' || 'Approved' || 'AND ref_die_type =' || 'Secondary';
execute immediate sql_statement into row_count;
IF (row_count != 0) THEN
RETURN 'TRUE';
ELSE
RETURN'FALSE';
END IF;
END;
This is the code when I try to call the function
SELECT CASE
WHEN check_second_ref_die ('8019572', 'rfabtwdb.dal.make.ti.com') = 'TRUE'
THEN 'EXISTS' ELSE 'NOT EXISTS'
END
AS RESULT
FROM DUAL
AND status =' || 'Approved' || 'AND
This is wrong. Remove the concatenation operators and we have ...
AND status =ApprovedAND
... which is not valid SQL. To reference string literals you need to escape single quotes. The simplest way is to use two of them:
AND status =''Approved'' AND
You'll need to fix all the string literals in your code.
Dynamic SQL is hard because it turns compilation errors into runtime errors. You can make it easier to debug your code by including some simple instrumentation. If your code had this line before the EXECUTE IMMEDIATE you could have seen the executed statement and probably spotted the bloomer for yourself.
dbms_output.put_line(v_sql);

01735. 00000 - "invalid ALTER TABLE option"

I am getting the following error:
00000 - "missing right parenthesis"
when I execute my procedure:
CREATE OR REPLACE PROCEDURE ALTER_TABLE_COLUMN_NOT_NULL(
var_tabname IN VARCHAR2,
var_clname IN VARCHAR2,
var_defvalue IN VARCHAR2 )
IS
l_isnull VARCHAR2(1);
BEGIN
SELECT isnull INTO l_isnull FROM USER_TAB_COLUMNS
WHERE TABLE_NAME = var_tabname AND COLUMN_NAME = var_clname;
IF l_isnull = 'Y' THEN
EXECUTE IMMEDIATE 'ALTER TABLE ' || var_tabname ||
' MODIFY COLUMN (' || var_clname ||
' DEFAULT ' || var_defvalue || ' NOT NULL)';
END IF;
END;
I know that according to the error, the right parenthesis is missing. I tried many ways of rewriting it, but I can't manage to fix it.
I am executing my procedure the following way:
BEGIN
ALTER_TABLE_COLUMN_NOT_NULL('FIRSTNAME', 'PRICE', '-');
END;
Writing dynamic SQL is hard, because compilation errors become runtime errors.
In this case I think the problem is that MODIFY COLUMN is wrong syntax. It's just MODIFY.
You may also run into some problems with your default of '-'. If price is a number that will fail because - is an invalid number. If price is a string you'll need to escape the passed value with additional quotes.
But probably you want to make this generic, so you need to write some more sophisticated handling which tests for datatype of the target column and formats default value appropriately.
"Can u give me a hint or any link how one can determine the datatype of a passed value in plsql?"
It's not the passed value which matters, it's the datatype of the modified column. You can get that from the USER_TAB_COLUMNS view which you're already querying.
Print your query to make sure it written correctly
DBMS_OUTPUT.PUT_LINE('ALTER TABLE ' || var_tabname || ' MODIFY COLUMN (' || var_clname || ' DEFAULT ' || var_defvalue || ' NOT NULL)');

How to handle dynamic variable string value in single line

This is my PL/SQL block. When i execute it the result of 'V_QUERY' variable breaks into two lines like:
'%[CDATA[/documents/%/4min.png
/%'.
How can i get it in one line like below: enter image description here
'%[CDATA[/documents/%/4min.png/%'
.
declare
cursor c1 is
select rtrim(ltrim(substr(typesettings, 7), '"'), '"') as typesettings
from trashentry
where rownum < 2;
v_query varchar2(32767);
begin
for r1 in c1
loop
v_query := '''%[CDATA[/documents/%/' || r1.typesettings || '/%''';
dbms_output.put_line(v_query);
end loop;
end;
Most likely you need to trim chr(10) from the end of typesettings. It may not hurt to trim chr(13) as well, on the chance it may be present too.
Assuming there aren't any double-quotes in your input string that you need to keep, you can achieve several things at once: Instead of rtrim(ltrim(...)) (which should be a trim(...) anyway, it does the same thing and is simpler and only calls one function instead of two), you could use translate:
select translate(substr(typesettings, 7), 'x"' || chr(10) || chr(13), 'x') as typesettings
.......
Notice the x in the last two parameters; it doesn't really do anything, it just works around a limitation of the translate function (which in turn is due to Oracle's treatment of empty strings as NULL). In this example, translate will replace every x in the input string with x, and every occurrence of ", chr(10) and chr(13) will be simply deleted.

ORA-06550: line 3, column 2: PLS-00103: Encountered the symbol "1" when expecting one of the following:

I get this error message:
ORA-06550: line 3, column 2: PLS-00103: Encountered the symbol "1"
when expecting one of the following:
begin function pragma procedure subtype type current cursor delete exists prior
For this code in oracle apex web application:
declare
1_address varchar2(4000);
1_url varchar2(32000);
1_response varchar2(3200);
begin
1_address := :P3_STREET || ',' || :P3_CITY;
if :P3_STATE is not null then
1_address := 1_address || ',' || :P3_STATE;
end if;
if :P3_COUNTRY is not null then
1_address := 1_address || ',' || :P3_COUNTRY;
end if;
1_address := replace(1_address, ' ', '+');
1_url := 'http://maps.google.com/maps/geo?q=' || 1_address || '&' ||
'output=c sv' || '&' || 'key=' || :API_KEY;
1_response := utl_http.request(1_url, APEX_APPLICATION.G_PROXY_SERVER);
:P3_RESPONSE := 1_response;
:P3_LOCATION := substr(1_response, instr(1_response, ',', 1, 2) + 1);
end;
I would like to integrate google maps to my application.
I followed this instruction, but it doesn't work.
Anybody have idea for solution?
Oracle naming conventions require (see here):
Nonquoted identifiers must begin with an alphabetic character from your database character set. Quoted identifiers can begin with any character.
The same also applies to PL/SQL variable names (see here):
Variable names can be composed of letters, dollar signs, underscores,
and number signs.
No other characters can be used.
A variable name must start with a letter, after which any combination
of the allowed characters can be used.
The maximum length for a variable name is 30 characters.
Variable names, like those of keywords and other identifiers, are not
case sensitive.
So, change the name of your variables to something that is acceptable to Oracle. In other words, don't start them with 1.

Resources