unexpected token error in plsql procedure - stored-procedures

CREATE PROCEDURE EPS.PROCEDURE_OTE_LTE_BIDDER_REPORT
(
IN P_USERID INTEGER,
IN P_AUCTIONID INTEGER,
IN P_REPORT_FLAG VARCHAR(3),
OUT O_ERROR_CODE INTEGER,
OUT OUTPUT_MESSAGE VARCHAR(100),
IN P_LOG_USERID INTEGER
)
LANGUAGE SQL
P1:BEGIN ATOMIC DECLARE SQLCODE INTEGER DEFAULT 0;
DECLARE V_USERID INTEGER;
DECLARE V_AUCTIONID INTEGER;
DECLARE V_REPORT_FLAG_TECHNOCOMMERCIALQUALIFIEDCUSTOMER VARCHAR(3);
DECLARE V_COUNT_TECHNOCOMMERCIALQUALIFIEDCUSTOMER INTEGER;
DECLARE V_REPORT_FLAG_SELECTIVEUSERWISETENDERREPORT VARCHAR(3);
DECLARE V_COUNT_SELECTIVEUSERWISETENDERREPORT INTEGER;
SELECT COUNT(*) INTO V_COUNT_TECHNOCOMMERCIALQUALIFIEDCUSTOMER FROM EPS.TECHNOCOMMERCIALQUALIFIEDCUSTOMER A
WHERE A.AUCTIONID=P_AUCTIONID AND A.USERID=P_USERID;
SELECT COUNT(*) INTO V_COUNT_SELECTIVEUSERWISETENDERREPORT FROM EPS.SELECTIVEUSERWISETENDERREPORT B
WHERE B.AUCTIONID=P_AUCTIONID AND B.USERID=P_USERID;
IF P_REPORT_FLAG = 'Y' THEN
IF V_COUNT_TECHNOCOMMERCIALQUALIFIEDCUSTOMER < 1 THEN
INSERT INTO EPS.TECHNOCOMMERCIALQUALIFIEDCUSTOMER (A.AUCTIONID,A.USERID,A.QUALIFIED) VALUES (P_AUCTIONID,P_USERID,'Y');
ELSE
SET OUTPUT_MESSEGE = 'DATA ALREADY PRESENT';
END IF;
ELSE
IF V_COUNT_TECHNOCOMMERCIALQUALIFIEDCUSTOMER > 0 THEN
DELETE FROM EPS.TECHNOCOMMERCIALQUALIFIEDCUSTOMER C WHERE C.AUCTIONID=P_AUCTIONID AND C.USERID=P_USERID;
ELSE
SET OUTPUT_MESSAGE = 'NO DATA FOUND';
END IF;
END IF;
IF P_REPORT_FLAG = 'Y' THEN
IF V_COUNT_SELECTIVEUSERWISETENDERREPORT < 1 THEN
INSERT INTO EPS.SELECTIVEUSERWISETENDERREPORT AA
( AA.AUCTIONID,
AA.USERID,
AA.TENDERREPORTTYPEID,
AA.STATUS,
AA.CREATEID,
AA.CREATEDATE,
AA.UPDATEID,
AA.UPDATEDATE
)
VALUES
(
P_AUCTIONID,
P_USERID,
103.
'A',
P_LOG_USERID,
CURRENT TIMESTAMP,
NULL,
NULL
);
ELSE
SET OUTPUT_MESSEGE = 'DATA ALREADY PRESENT';
END IF;
ELSE
IF V_COUNT_SELECTIVEUSERWISETENDERREPORT > 0 THEN
DELETE FROM EPS.SELECTIVEUSERWISETENDERREPORT CC WHERE CC.AUCTIONID=P_AUCTIONID AND CC.USERID=P_USERID;
ELSE
SET OUTPUT_MESSAGE = 'NO DATA FOUND';
END IF;
END IF;
END P1
I am getting this error
SQL Error [42601]: An unexpected token "END-OF-STATEMENT" was found following "Y PRESENT'". Expected tokens may include: "
END IF".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.7.85
SQL Error [42601]: An unexpected token "END-OF-STATEMENT" was found following "Y PRESENT'". Expected tokens may include: "
END IF".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.7.85
An unexpected token "END-OF-STATEMENT" was found following "Y PRESENT'". Expected tokens may include: "
END IF".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.7.85
An unexpected token "END-OF-STATEMENT" was found following "Y PRESENT'". Expected tokens may include: "
END IF".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.7.85

It helps to properly use a syntax editor that understands SQL, and take more care with checking your code. A good SQL editor may highlight your mistakes before you try to compile, as would any code review.
On a separate note, you should understand the difference between ANSI SQL PL and Oracle PL/SQL. Your code seems to use ANSI SQL PL syntax, although your mistakes may be mistakes for any flavour of SQL.
Here are some of the obvious syntax mistakes in your code (there may be others):
On the line INSERT INTO EPS.SELECTIVEUSERWISETENDERREPORT AA , the AA should be omitted.
For the same insert statement you have 103., when you might mean 103,.
For the line INSERT INTO EPS.TECHNOCOMMERCIALQUALIFIEDCUSTOMER (A.AUCTIONID,A.USERID,A.QUALIFIED) you probably mean instead
INSERT INTO EPS.TECHNOCOMMERCIALQUALIFIEDCUSTOMER (AUCTIONID,USERID,QUALIFIED)
The same mistake is present for the line with INSERT INTO EPS.SELECTIVEUSERWISETENDERREPORT (do not qualify the column names).
For the line beginning SET OUTPUT_MESSEGE = you probably mean SET OUTPUT_MESSAGE =, and this typo is present on other lines.

Related

Snowflake Store Procedure - Loop through csv files in AWS S3 and COPY INTO tables with same name

I was wondering if someone could help me with the error message I am getting from Snowflake. I am trying to create a stored procedure that will loop through 125 files in S3 and copy into the corresponding tables in Snowflake. The names of the tables are the same names as the csv files. In the example I only have 2 file names set up (if someone knows a better way than having to liste all 125, that will be extremely. helpful) .
The error message I am getting is the following:
syntax error line 5 at position 11 unexpected '1'.
syntax error line 6 at position 22 unexpected '='. (line 4)
CREATE OR REPLACE PROCEDURE load_data_S3(file_name VARCHAR,table_name VARCHAR)
RETURNS VARCHAR
LANGUAGE SQL
AS
$$
BEGIN
FOR i IN 1 to 2 LOOP
CASE i
WHEN 1 THEN
SET file_name = 'file1.csv';
SET table_name = 'FILE1';
WHEN 2 THEN
SET file_name = 'file2.csv';
SET table_name = 'FILE2';
--WILL LIST THE REMAINING 123 WHEN STATEMENTS
ELSE
-- Do nothing
END CASE;
COPY INTO table_name
FROM #externalstg/file_name
FILE_FORMAT = (type='csv');
END LOOP;
RETURN 'Data loaded successfully';
END;
$$;
There are various ways to list the files in a stage (see the post here). You can loop through the resultset and run COPY INTO on each record

ANTLR Parsing rule covering block of text containing the "End"-Token

I am wondering whether there is a possibility for antlr parsing rules to create rules that match Strings containing the endtoken. I'll illustrate this by using an sql-example:
CREATE FUNCTION UFHDBTBL.FH_LIEF_SPERR_SK(pidpack INTEGER)
...
BEGIN ATOMIC
DECLARE sperrsk VARCHAR(2000) DEFAULT '';--
DECLARE erster INTEGER DEFAULT 0;--
FOR satz AS
SELECT sk_name1
FROM UFHDBTBL.FH01TM21 psk, UFHDBTBL.FH01T61 lsk
WHERE psk.id_pack = pidpack
DO
IF erster = 1 THEN
SET sperrsk = sperrsk || '<br>';--
END IF ;--
SET sperrsk = sperrsk || LTRIM(RTRIM(satz.sk_name1));--
IF erster = 0 THEN
SET erster = 1;--
END IF ;--
END FOR;--
RETURN sperrsk;--
END;
Currently, I tried the following parsing-rules to match all the stuff between "BEGIN ATOMIC" and "END;":
'BEGIN' ~('END') 'END'
'BEGIN' .+? 'END'
'BEGIN' (~('END')|~(';'))* 'END'
(The last ; is contained in the "create function rule" so don't worry about it)
Notice, that the block contains the tokens "END" and ";". Since I don't want to create a new token "END;" (which causes many other rules to fail), I hope there is some antlr guy around who's able to help me!
You could use something like the following to match everything until END; without creating a new single token to represent it.
'BEGIN'
( ~'END'
| 'END' ~';'
)*
'END' ';'

Error -104 Unexpected end of command creating a Firebird stored procedure [duplicate]

This question already has an answer here:
Error -104 creating Firebird stored procedure
(1 answer)
Closed 1 year ago.
I want to create a stored procedure in Firebird:
CREATE PROCEDURE CalcPvIncome
( BeginDate date,
EndDate date,
KwPrice decimal (2,2) )
RETURNS ( Total_PV_Production decimal (9,2),
Total_Income decimal (9,2) )
AS
BEGIN
FOR SELECT SUM(ENERGY/1000), SUM((ENERGY/1000) * :KwPrice)
FROM PVPROD
WHERE proddate >= :BeginDate AND proddate <= :Enddate
INTO :Total_PV_Production , :Total_Income
DO
BEGIN
SUSPEND ;
END
END
I get this error:
Engine Code : 335544569
Engine Message : Dynamic SQL Error SQL error code = -104 Unexpected end of command - line 18, column 9
The SQL statement:
SELECT
SUM(ENERGY/1000) AS Total_PV_Production,
sum((ENERGY/1000)*0.55) as Total_Income
FROM
PVPROD
where
proddate >= '12.06.2012' and proddate <= '12.07.2012'
You have to add SET TERM statement before and after the stored procedure. It is used to change the "terminator character". Here's an example:
SET TERM ^ ;
CREATE PROCEDURE CalcPvIncome
( BeginDate date,
EndDate date,
KwPrice decimal (2,2) )
RETURNS ( Total_PV_Production decimal (9,2),
Total_Income decimal (9,2) )
AS
BEGIN
...
END
SET TERM ; ^
Note that default terminator is ^ and also note that you are setting ; as new terminator before and resetting it back to ^ after stored procedure declaration.

How to call plpgsql functions from Ruby on rails?

How to call plpgsql functions from Ruby on Rails application?
This is the function definition:
CREATE OR REPLACE FUNCTION add_org_pincode(i_user_id integer, i_org_id integer, i_amount numeric, i_pincode_id integer)
RETURNS integer AS
$BODY$
Declare
v_org_balance numeric;
Begin
Select o.balance
Into Strict v_org_balance
From organizations o
Left Join organizations d On o.parent_organization_id = d.id
Where o.id = i_org_id
For Update Of o;
--
Insert Into org_balance_transactions(organization_id, balance, amount_added, reason, action_user_id, transaction_id)
Values (i_org_id, v_org_balance, i_amount, 10, i_user_id, i_pincode_id);
--
Update organizations
Set balance = balance + i_amount
Where id = i_org_id;
-- Other error
Return 0;
End;$BODY$
LANGUAGE 'plpgsql' VOLATILE;
So, how do I call add_org_pincode?
Like the others have said, something akin to:
result = connection.execute ("SELECT add_org_pincode(#{user_id}, #{org_id}, #{amount}, #{pincode_id};")
This is an example that I have proven, it might help you...
CREATE LANGUAGE plpgsql;
/**PROMEDIOS**/
CREATE OR REPLACE FUNCTION average(valores NUMERIC[],OUT prom NUMERIC) AS $$
DECLARE
element_count INT4;
sum numeric := 0.0;
BEGIN
element_count := array_upper(valores, 1) - array_lower(valores, 1) +1;
FOR i IN array_lower(valores, 1) .. array_upper(valores, 1)
LOOP
sum := sum + valores[i];
END LOOP;
prom := trunc(sum/element_count,1);
END;
$$ LANGUAGE plpgsql;
Obviously you have to execute this SQL in your database, just add it in your SQL Editor (pointing your database) in PGAdmin, after executing that, this function must be available like this select average(ARRAY[4.5,3.2,7.0]);.
In Rails Console I tried the example like this:
_calificaciones = Calificacion.all(:conditions => ["promedio_parciales != average(array[parcial1,parcial2,parcial3])"])
and it worked fine for me... Good luck...
You can go straight to the ActiveRecord::Base.connection to execute SQL which is what I did for some prototype code...
result = ActiveRecord::Base.connection.execute("SELECT * FROM stock_hourly_performance(#{stock_id})")
I don't know if its the best solution to the problem but it got me up and running.
You can execute raw SQL with:
ActiveRecord::Base.connection.execute('SQL goes here')
Be sure that it is absolutely necessary to bypass ActiveRecord (Rail's ORM).

mysql stored procedure: using declared vars in a limit statement returns an error

I have the following code:
delimiter ;
DROP PROCEDURE IF EXISTS ufk_test;
delimiter //
CREATE PROCEDURE ufk_test(IN highscoreChallengeId INT UNSIGNED)
BEGIN
DECLARE vLoopOrder INT UNSIGNED DEFAULT 5;
DECLARE vLoopLimit INT UNSIGNED DEFAULT 10;
select * from fb_user LIMIT vLoopOrder,vLoopLimit;
END//
delimiter ;
Mysql returns the following error:
ERROR 1064 (42000): 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 'vLoopOrder,vLoopLimit;
END' at line 11
it seems that I cannot use declared variables in a LIMIT statement. is there any other way to overcome this ?
of course this is a simple example, here i could just put static numbers but I need to know if it's possible in any way to use any kind of variables with LIMIT.
Thanks
i use something like:
SET #s = CONCAT('SELECT * FROM table limit ', vLoopOrder ', ', vLoopLimit);
PREPARE stmt1 FROM #s;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;

Resources