I am fighting an error which is stopping my stored procedure from working:
"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF (SELECTED_PROJECT_LOBSELECTION = 'Copy the Whole Project') THEN SET lob' at line 1:"
Here is a portion of my IF/ELSEIF statement:
IF (SELECTED_PROJECT_LOBSELECTION = 'Copy the Whole Project') THEN
SET lobInsertStmt = ' AND p.PROJECTION_PROJECT_NME = ' || SELECTED_PROJECT_NAME
|| ' AND p.PROJECTION_PROJ_CATG_NME = ' || SELECTED_PROJECT_CATG
|| ' AND p.FINANCIAL_PROJECTION_YEAR_NUM = ' || CAST(SELECTED_PROJECT_YEAR AS int)
|| ' AND g.MODEL_GROUP_SNAPSHOT_TSP = ' || SELECTED_SNAPSHOT_TIMESTAMP;
What am I doing incorrectly and why won't my compare work? Thanks!
UPDATE:
My issue wasn't an IF/THEN compare. It was how the IN params were being read. Here is the solution to that:
IF (SELECTED_PROJECT_LOBSELECTION = 'Copy the Whole Project') THEN
SET lobInsertStmt = ' AND p.PROJECTION_PROJECT_NME = ''' || SELECTED_PROJECT_NAME || ''''
|| ' AND p.PROJECTION_PROJ_CATG_NME = ''' || SELECTED_PROJECT_CATG || ''''
|| ' AND p.FINANCIAL_PROJECTION_YEAR_NUM = ' || TRIM(CAST(SELECTED_PROJECT_YEAR AS int))
|| ' AND g.MODEL_GROUP_SNAPSHOT_TSP = ''' || SELECTED_SNAPSHOT_TIMESTAMP || '''';
Now, I am receiving an SQLSTATE of 07005 which is: "The cursor 'cursor-name' could not be used as specified because the prepared statement named in the declaration for the cursor was not a SELECT statement."
How can I do the insert with a stored procedure without the cursor?
Here is additional code:
REPLACE PROCEDURE "SCHEMA"."PROCEDURE_NAME" (
IN "SELECTED_PROJECT_NAME" VARCHAR(256) CHARACTER SET LATIN,
IN "SELECTED_PROJECT_CATG" VARCHAR(256) CHARACTER SET LATIN,
IN "SELECTED_PROJECT_YEAR" VARCHAR(4) CHARACTER SET LATIN,
IN "SELECTED_SNAPSHOT_TIMESTAMP" VARCHAR(28) CHARACTER SET LATIN,
IN "SELECTED_PROJECT_TYPE" VARCHAR(6) CHARACTER SET LATIN,
IN "SELECTED_PROJECT_LOBSELECTION" VARCHAR(256) CHARACTER SET LATIN,
IN "SELECTED_LOB_NUMBERS" VARCHAR(256) CHARACTER SET LATIN,
IN "COPY_TO_PROJECT_NAME" VARCHAR(256) CHARACTER SET LATIN,
IN "REQUESTER_ID" VARCHAR(8) CHARACTER SET LATIN,
OUT "TEST_OUT" VARCHAR(5000) CHARACTER SET LATIN,
OUT "SQLSTATE_OUT" VARCHAR(5) CHARACTER SET LATIN,
OUT "SQLCODE_OUT" INTEGER)
DYNAMIC RESULT SETS 1
P1: BEGIN
DECLARE lobInsertStmt varchar(500);
DECLARE mystmt varchar(5000);
DECLARE CURSOR_C CURSOR WITH RETURN FOR PREPSTMT;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SET SQLCODE_OUT = SQLCODE;
SET SQLSTATE_OUT = SQLSTATE;
SET TEST_OUT = mystmt;
END;
IF (SELECTED_PROJECT_LOBSELECTION = 'Copy the Whole Project') THEN
SET lobInsertStmt = ' AND p.PROJECTION_PROJECT_NME = ''' || SELECTED_PROJECT_NAME || ''''
|| ' AND p.PROJECTION_PROJ_CATG_NME = ''' || SELECTED_PROJECT_CATG || ''''
|| ' AND p.FINANCIAL_PROJECTION_YEAR_NUM = ' || TRIM(CAST(SELECTED_PROJECT_YEAR AS int))
|| ' AND g.MODEL_GROUP_SNAPSHOT_TSP = ''' || SELECTED_SNAPSHOT_TIMESTAMP || '''';
-- Other ElseIFs
END IF;
SET mystmt = 'INSERT INTO D_FAR_WORK_VW.V_COPY_MODEL_PROCESS_WORK'
|| ' SELECT reqt.RUN_ID,'''
|| SELECTED_PROJECT_NAME || ''' AS TO_PROJECTION_PROJECT_NME,'
|| ' m.PROJECTION_MODEL_SEQ_ID,'
|| ' m.PROJECTION_MODEL_ROW_SEQ_ID,'
|| ' p.PROJECTION_PROJECT_NME as FROM_PROJECTION_PROJECT_NME, '''
-- More insert code
PREPARE PREPSTMT FROM mystmt;
OPEN CURSOR_C;
SET TEST_OUT = mystmt;
SET SQLSTATE_OUT = SQLSTATE;
SET SQLCODE_OUT = SQLCODE;
END P1;
I answered my question. I removed the cursor and added an execute statement
EXECUTE PREPSTMT;
after the Prepare
Related
I work on a C# project and i created an sql procedure on Iseries (AS400) and Iam getting the following error.
An error occurred while processing the results. - [SQL0802] Data conversion or data mapping error.
This is the code of sql procedure. Can anyone have an idea to help me with this. The scenario is that the usercode, applicationcategory and isfavorite getting as parameters.
Thanks
BEGIN
DECLARE STRING_QUERY VARCHAR ( 2000 ) ;
DECLARE C1 CURSOR WITH RETURN TO CLIENT FOR SQL_STATEMENT ;
IF ISFAVORITE = '0' THEN
SET STRING_QUERY = 'SELECT A.APPLICATIONCATEGORY,C.FOLDEROFPROJECT,' ||
'C.PROJECT,D.PROJECTGRDESCRIPTION,D.PROJECTENDESCRIPTION,' ||
'D.OBJECTNAME,D.OBJECTTYP,' ||
'C.FAVORITE FROM ERPLIB.APPLICATIONDEPARTMENT A ' ||
'INNER JOIN ERPLIB.APPLICATIONUSERDEPARTMENTAUTHIRITY B ' ||
'ON B.USERCODE = ' || P_USERCODE ||
' AND B.APPLICATIONCATEGORY = A.APPLICATIONCATEGORY' ||
' INNER JOIN ERPLIB.APPLICATIONUSERMODULEAUTHORITY C ' ||
'ON C.USERCODE = ' || P_USERCODE ||
' AND C.APPLICATIONCATEGORY = A.APPLICATIONCATEGORY' ||
' AND C.FAVORITE = ''0''' ||
' INNER JOIN ERPLIB.APPLICATIONMODULE D ' ||
'ON D.APPLICATIONCATEGORY = A.APPLICATIONCATEGORY' ||
' AND D.FOLDEROFOBJECT = C.FOLDEROFPROJECT AND ' ||
'D.PROJECT = C.PROJECT ' ||
'WHERE A.APPLICATIONCATEGORY = ''001''' ;
END IF ;
PREPARE SQL_STATEMENT FROM STRING_QUERY ;
OPEN C1 ;
RETURN ;
I had to write this query for an assignement. So we have a database and we are pulling information from it, this is going to work with some back end c# eventually. Is there anything i can do , knowing im going to reuse this, in order to make it better and more adaptable when the day comes when i have to connect it all.
set serveroutput on
DECLARE
LV_DATE HVK_RESERVATION.RESERVATION_START_DATE%TYPE;
LV_SERV VARCHAR(100);
CURSOR LCUR_RES IS
SELECT *
FROM HVK_RESERVATION R
INNER JOIN HVK_PET_RESERVATION PR
ON R.RESERVATION_NUMBER = PR.RES_RESERVATION_NUMBER
INNER JOIN HVK_PET P
ON P.PET_NUMBER = PR.PET_PET_NUMBER
INNER JOIN HVK_OWNER OW
ON OW.OWNER_NUMBER = P.OWN_OWNER_NUMBER
WHERE R.RESERVATION_START_DATE < LV_DATE
AND R.RESERVATION_END_DATE > LV_DATE;
CURSOR LCUR_SERVICE(PET_RES_NUM NUMBER) IS
SELECT *
FROM HVK_SERVICE S
INNER JOIN HVK_PET_RESERVATION_SERVICE PRS
ON PRS.SERV_SERVICE_NUMBER = S.SERVICE_NUMBER
AND PRS.PR_PET_RES_NUMBER = PET_RES_NUM;
BEGIN
LV_DATE := TO_DATE('&logdate', 'yy-mm-dd');
DBMS_OUTPUT.PUT_LINE('Kennel log for ' || '' || LV_DATE);
DBMS_OUTPUT.PUT_LINE('-------------------------------');
FOR I IN LCUR_RES LOOP
DBMS_OUTPUT.PUT_LINE('Run:' || '' || I.RUN_RUN_NUMBER || ' ' ||
'Pet: ' || '' || I.PET_NAME || ' ' ||
I.OWNER_LAST_NAME || ' Pet Reservation: ' || '' ||
I.PET_RES_NUMBER);
DBMS_OUTPUT.PUT_LINE('Reservation start/end ' || ' ' ||
I.RESERVATION_START_DATE || ' ' ||
I.RESERVATION_END_DATE);
DBMS_OUTPUT.PUT('Services : ');
FOR X IN LCUR_SERVICE(I.PET_RES_NUMBER) LOOP
DBMS_OUTPUT.PUT(X.SERVICE_DESCRIPTION || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE('');
FOR LREC_LOG IN (SELECT *
FROM HVK_KENNEL_LOG KL
WHERE KL.PR_PET_RES_NUMBER = I.PET_RES_NUMBER
) LOOP
DBMS_OUTPUT.PUT_LINE('Notes: ' || '' ||
LREC_LOG.KENNEL_LOG_SEQUENCE_NUMBER || ' ' ||
'Log Note: ' || '' || LREC_LOG.KENNEL_LOG_NOTES);
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
END LOOP;
END;
It it supposed to output the run number , reservation number , pet name , and any relate notes.
you can replace DECLARE with CREATE OR REPLACE PROCEDURE my_proc(in_logdate in date) IS.
in that case my_proc will be the name of your procedure.
you should also use a parameter instead of &logdate
so e.g. parameter name in_logdate of type date
...
LV_DATE := in_logdate;
...
I have a script that works with dynamic tables. When executing the below code segment, it gives me error ORA00904: invalid identifier.
IF Database_SYS.Column_Exist (service_tab_, ''KEY_VALUE'') THEN
UPDATE '|| service_tab_ || '
SET key_ref = new_key_ref_,
key_value = ''Test'',
rowversion = SYSDATE
WHERE ROWID = rec_.ROWID;
ELSE
UPDATE '|| service_tab_ || '
SET key_ref = new_key_ref_,
rowversion = SYSDATE
WHERE ROWID = rec_.ROWID;
END IF;
Would be better this one:
BEGIN
IF Database_SYS.Column_Exist (service_tab_, '''' || KEY_VALUE || '''') THEN
EXECUTE IMMEDIATE
'UPDATE ' || service_tab_ || '
SET key_ref = new_key_ref_,
key_value = :val,
rowversion = SYSDATE
WHERE ROWID = :rid'
USING 'TEST', rec_.ROWID;
ELSE
EXECUTE IMMEDIATE
'UPDATE ' || service_tab_ || '
SET key_ref = new_key_ref_,
rowversion = SYSDATE
WHERE ROWID = :rid'
USING rec_.ROWID;
END IF;
END;
I don't think you need '''' || KEY_VALUE || '''', using just Database_SYS.Column_Exist(service_tab_, KEY_VALUE) should be fine if you have properly coded the function.
Try something like this:
EXECUTE IMMEDIATE 'update' || service_tab_ || 'SET key_ref = ' ||new_key_ref_|| ' rowversion = SYSDATE WHERE ROWID = '|| rec_.ROWID;
LEt me know if you get further errors, we can resolve them together in comments.
BEGIN
IF Database_SYS.Column_Exist (service_tab_, '''' || KEY_VALUE || '''') -- 4x': StartString + Quote + ' + EndString doublepipe to concat Strings
THEN
EXECUTE IMMEDIATE -- If you want to Build dynamic SQL you have to throw it into "EXECUTE IMMEDIATE 'myQuery'"
'UPDATE ' || service_tab_ || '
SET key_ref = new_key_ref_,
key_value = ''TEST'',
rowversion = SYSDATE
WHERE ROWID = rec_.ROWID';
ELSE
EXECUTE IMMEDIATE
'UPDATE ' || service_tab_ || '
SET key_ref = new_key_ref_,
rowversion = SYSDATE
WHERE ROWID = rec_.ROWID';
END IF;
END;
Next time you should Build up your script step-by-step. A single Error can be handled better than having a bunch of invalid code..
If the only difference is in updating a column it would be more correct to apply the condition only to a part of the query
DECLARE
V_QUERY VARCHAR2(200);
BEGIN
--
V_QUERY := 'UPDATE '||service_tab_||
' SET key_ref = new_key_ref_,
rowversion = SYSDATE';
--
IF Database_SYS.Column_Exist (service_tab_, 'KEY_VALUE') THEN
V_QUERY := V_QUERY||', key_value = ''Test''';
END IF;
--
V_QUERY := V_QUERY||' WHERE ROWID = rec_.ROWID';
--
EXECUTE IMMEDIATE V_QUERY;
--
END;
i am having a trouble to reassign a value, my teacher told me to use something like
var = var + (rest of the query)
but it aint working at all, here it is my code:
create or replace function recorrertablas()
returns void as
$BODY$
declare cursorx cursor for select id, nombre as nombres from tablas;
declare cursory refcursor;
declare rec record;
declare rec2 record;
declare consulta varchar;
--declare consulta2 varchar;
begin
open cursorx;
loop
fetch cursorx into rec;
exit when not found;
consulta= 'create table ' || rec.nombres;
--consulta2= '';
open cursory for select * from atributos where idtabla = rec.id;
loop
fetch cursory into rec2;
exit when not found;
consulta = consulta + '(' || rec2.id || ', ' || rec2.idtabla || ', ' || rec2.nombre || ', ' ||rec2.tipodedatos ;
if rec2.claveprimaria = 1 then
consulta= consulta +', constraint pk_ ' || rec.nombres || '( ' || rec.id || '));';
else
consulta = consulta +');';
end if;
end loop;
close cursory;
end loop;
execute consulta;
close cursorx;
end;
$BODY$
language plpgsql volatile;
If you need to concatenate things use || operator or concat() function like below.
You've been using this operator, but for some reason you mixed it with +.
SELECT 'string' || 'part2';
or
SELECT concat('string', 'part2');
For your specific case:
consulta = consulta || '(' || rec2.id || ', ' || rec2.idtabla || ', ' || rec2.nombre || ', ' ||rec2.tipodedatos ;
if rec2.claveprimaria = 1 then
consulta= consulta || ', constraint pk_ ' || rec.nombres || '( ' || rec.id || '));';
else
consulta = consulta || ');';
When using || operator if any value evaluates to NULL the whole output will be NULL, but when using concat() function it will omit NULL values and still concatenate other arguments.
I try to make an update table CHECK_COMPRESSER into PROCEDURE and I use EXECUTE IMMEDIATE :
EXECUTE immediate 'update CHECK_COMPRESSER
set NEW_SIZE_MB = '||''''||TABLE_P_ENTRY.NEW_SIZE_MB || '''' ||
' WHERE EXEC_ID = ' || '''' || EXEC_ID || '''' || ' AND TABLE = ' || '''' || TABLE_P_ENTRY.SEGMENT_NAME || '''' || ' AND PARTITION = ' || '''' || TABLE_P_ENTRY.PARTITION_NAME || '''';
dbms_output.put_line shows:
update CHECK_COMPRESSER set NEW_SIZE_MB = '182' WHERE EXEC_ID = '43' AND TABLE = 'MA_CONTACT_COMPRESS' AND PARTITION = 'P_OLD'
but there is an error:
ORA-00936: missing expression ORA-06512: at "SASDBA.COMPRESS_TABLE",
line 50
so, how should I edit this code?
TABLE is a keyword. It can be used as identifier only if quoted: "TABLE".
P.S. PARTITION is the same.