I get the error message pls-00103 at line 3 and 5 with this part of a trigger Im trying to make. If RENDEZVOUSSTART is after or equal to 6pm (18:00 here) the price multiplicator is 1.5 and the NOTAUXHORAIRE should be 1, in all other cases, the price multiplicator is 1 and NOTAUXHORAIRE is 0.
if to_char (:new.RENDEZVOUSSTART, 'HH24') >= 18
THEN multiplicator := 1.5
and :new.NOTAUXHORAIRE := 1 ;
else multiplicator := 1
AND :new.NOTAUXHORAIRE := 0;
end if;
Error(3,35): PLS-00103: Symbole "=" rencontré à la place d'un des symboles suivants : . ( * # % & = - + ; < / > at in is mod remainder not rem <> or != or ~= >= <= <> and or like like2 like4 likec between || indicator multiset member submultiset Symbole "* inséré avant "=" pour continuer.
Thank you very much everyone! I just started to learn Sql for a business class and Im still a newbie :D
The and is unnecessary:
if to_char (:new.RENDEZVOUSSTART, 'HH24') >= 18 THEN
multiplicator := 1.5;
:new.NOTAUXHORAIRE := 1;
else multiplicator:= 1;
:new.NOTAUXHORAIRE := 0;
end if;
Related
I have series of numbers that add up to nearly 100 (they are percentages), for example:
A
B
C
49.99
9.99
40.01
And I would like to adjust these to get something like:
A
B
C
50.00
10.00
40.00
Constraints :
The numbers count may vary,
The initial sum can be a little over/under 100 (I use a threshold of 0.1 : if the sum is below 99.9 or over 100.1 then I don't adjust),
sometimes there can be no "nice/round" numbers. In that case I want to distribute the missing/exceeding 1/100s in favor of the lowest numbers like so:
A
B
C
D
E
F
G
33.33
16.66
8.33
8.33
9.99
12.50
10.83
33.33
16.66
8.34
8.34
10.00
12.50
10.83
The function I currently use is working great for distributing the missing/exceeding 1.100s in a loop but does not address the 49.99 → 50.00 problem.
The principle it uses is :
multiply all the % by 100 (to get integers)
assign a "weight" to each integer based on the number of trailing zeroes (so that I adjust preferably the non-round numbers):
30 when (int mod 1000)=0
20 when (int mod 100)=0
10 when (int mod 10)=0
5 when (int mod 5) = 0
else 0.
calculate the missing/exceeding 1/100s for the lowest weight
sort the ints to get the lowest ints first (the sort takes the weight into account)
add/substract 1 to each int until I get a sum of 100.
The resulting function will be written in Postgres' Pl/PgSql but I'm mostly interested in knowing if such algorithms exist and how they are named (of course, a link to a working function would be very much appreciated).
I ended up splitting the problem in 2 :
adjust the original shares to get "nicer" numbers (49.99 → 50.00) and
add a few 1/100s here and there to obtain a 100% total.
The result is satisfying, I even integrated a few special values for common fractions (200/3, 100/3, 100/6, 100/12...) so that 3x33.33 don't end up with 33.35, 33.35 and 33.30, less "nice/round" but more fair. Note there is only one loop for the final adjustments. Performance is acceptable : 3.5 sec for 100000 rows.
The following SO question and the included Wikipedia article helped me understand the possible biases and their pros/cons.
Here is the code for those interested :
CREATE OR REPLACE FUNCTION public.normalizeshares_weight(share INT) RETURNS INT AS
$BODY$
SELECT CASE
WHEN share % 10000 = 0 THEN 40
WHEN share % 1000 = 0 THEN 30
WHEN share % 100 = 0 THEN 20
WHEN share % 50 = 0 OR (share = ANY('{6666,3333,1666,833,416}')) THEN 15
WHEN (share % 10 = 0) THEN 10
WHEN share % 5 = 0 THEN 5
ELSE 0 END;
$BODY$ LANGUAGE SQL IMMUTABLE;
CREATE OR REPLACE FUNCTION public.normalizeshares(shares NUMERIC[]) RETURNS NUMERIC(5,2)[] AS
$BODY$
DECLARE
intshares INT[];
adjshares INT[];
weight INT[];
result NUMERIC[];
nb0 INT = 0;
nb5 INT = 0;
nb10 INT = 0;
nb15 INT = 0;
nb20 INT = 0;
nb30 INT = 0;
nb40 INT = 0;
initot INT = 0;
tot INT = 0;
nb INT = 0;
w INT = 0;
diff INT;
each INT;
bestweight INT;
BEGIN
FOR i IN 1..ARRAY_LENGTH(shares,1) LOOP
intshares[i] := FLOOR(COALESCE(shares[i],0)*100);
weight[i] := normalizeshares_weight(intshares[i]);
bestweight := weight[i];
adjshares[i] := intshares[i];
IF normalizeshares_weight(intshares[i]+1) > bestweight THEN adjshares[i] := intshares[i]+1; bestweight := normalizeshares_weight(intshares[i]+1); END IF;
IF normalizeshares_weight(intshares[i]+2) > bestweight THEN adjshares[i] := intshares[i]+2; bestweight := normalizeshares_weight(intshares[i]+2); END IF;
IF normalizeshares_weight(intshares[i]+3) > bestweight THEN adjshares[i] := intshares[i]+2; bestweight := normalizeshares_weight(intshares[i]+3); END IF;
IF normalizeshares_weight(intshares[i]-1) > bestweight THEN adjshares[i] := intshares[i]-1; bestweight := normalizeshares_weight(intshares[i]-1); END IF;
IF normalizeshares_weight(intshares[i]-2) > bestweight THEN adjshares[i] := intshares[i]-2; bestweight := normalizeshares_weight(intshares[i]-2); END IF;
IF normalizeshares_weight(intshares[i]-3) > bestweight THEN adjshares[i] := intshares[i]-2; bestweight := normalizeshares_weight(intshares[i]-3); END IF;
tot := tot + adjshares[i];
initot := initot + intshares[i];
weight[i] := bestweight; -- normalizeshares_weight(adjshares[i]); already calculated
IF weight[i]=0 THEN nb0 := nb0 + 1;
ELSIF weight[i]=5 THEN nb5 := nb5 + 1;
ELSIF weight[i]=10 THEN nb10 := nb10 + 1;
ELSIF weight[i]=15 THEN nb15 := nb15 + 1;
ELSIF weight[i]=20 THEN nb20 := nb20 + 1;
ELSIF weight[i]=30 THEN nb30 := nb30 + 1;
ELSIF weight[i]=40 THEN nb40 := nb40 + 1;
END IF;
result[i] := (intshares[i]::NUMERIC / 100)::NUMERIC(5,2);
END LOOP;
IF tot=10000 THEN
-- RAISE NOTICE 'adjtot=100.00 : %',adjshares::numeric[];
FOR i IN 1..ARRAY_LENGTH(shares,1) LOOP
result[i] := (adjshares[i]::NUMERIC / 100)::NUMERIC(5,2);
END LOOP;
ELSIF (initot=10000) OR (ABS(10000-tot)>90) THEN
-- RAISE NOTICE 'No adj needed, initot=%, tot=%',initot,tot;
ELSE
IF nb0 > 0 THEN nb := nb0; w := 0;
ELSIF nb5 > 0 THEN nb := nb5; w := 5;
ELSIF nb10 > 0 THEN nb := nb10; w := 10;
ELSIF nb15 > 0 THEN nb := nb15; w := 15;
ELSIF nb20 > 0 THEN nb := nb20; w := 20;
ELSIF nb30 > 0 THEN nb := nb30; w := 30;
ELSIF nb40 > 0 THEN nb := nb40; w := 40;
END IF;
diff := 10000 - tot;
each := diff/nb+diff/abs(diff);
-- RAISE NOTICE 'nb=%, w=%, diff=%, tot=%, adj=%',nb,w,diff,tot,adjshares::numeric[];
FOR i IN 1..ARRAY_LENGTH(shares,1) LOOP
IF weight[i]=w THEN
IF diff=0 THEN
ELSIF nb=1 THEN
adjshares[i] := adjshares[i] + diff;
ELSIF nb>1 THEN
adjshares[i] := adjshares[i] + each;
diff := diff - each;
END IF;
nb := nb -1;
END IF;
result[i] := (adjshares[i]::NUMERIC / 100)::NUMERIC(5,2);
END LOOP;
END IF;
RETURN result;
END;
$BODY$ LANGUAGE plpgsql IMMUTABLE;
And a few results :
% select normalizeshares('{49.99,9.99,40.01}');
normalizeshares
---------------------
{50.00,10.00,40.00}
% select normalizeshares('{33.33,16.66,8.33,8.33,9.99,12.5,10.83}');
normalizeshares
-------------------------------------------
{33.33,16.66,8.33,8.33,10.00,12.50,10.85}
I am trying to simulate the below code. However, it shows the error " found '0' definitions of operator "", cannot determine exact overloaded matching definition for "" ". I have had attached the required packages to my code. please guide me with this error. Thank you in advance.
library IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;
USE IEEE.std_logic_arith.all;
USE IEEE.math_real.all;
library IEEE_proposed;
use IEEE_proposed.fixed_pkg.all;
entity test_zp is
end;
Architecture ARCHofZP of test_zp is
TYPE matrix IS ARRAY ( NATURAL RANGE <>, NATURAL RANGE <> ) OF INTEGER RANGE 0 TO 500;
SIGNAL kernel : matrix ( 1 TO 3 , 1 TO 3 ) := ((1,0,0),(0,1,0),(1,0,1));
SIGNAL image1 : matrix ( 1 To 6 , 1 TO 6 ) := ((25,100,75,49,130,15),(50,80,0,70,100,34),(20,5,10,20,30,0),(45,60,50,12,24,32),(34,37,53,55,21,90),(45,65,55,78,20,16));
FUNCTION batchnorm (outimg : matrix ( 1 To 8 , 1 TO 8 ) ) RETURN matrix IS
VARIABLE sum1 : INTEGER RANGE 0 TO 500;
VARIABLE SD1,SD,mean,ave,sum : UFIXED (10 downto -2):= "00000000";
VARIABLE batchnorm_mat : matrix (outimg'RANGE(1), outimg'RANGE(2));
CONSTANT alpha,beta : UFIXED (1 downto -2):= "0010";
BEGIN
R1 : FOR i IN outimg'RANGE(1) LOOP
C1 : FOR j IN outimg'RANGE(2) LOOP
sum1 := sum1 + outimg(i,j);
END LOOP;
END LOOP;
mean := sum1 / outimg'LENGTH;
ave := to_ufixed(23,10,-2);
R2 : FOR i IN outimg'RANGE(1) LOOP
C2 : FOR j IN outimg'RANGE(2) LOOP
SD1 := ((to_ufixed(outimg(i,j),10,-2)-ave)/to_ufixed(outimg'LENGTH,10,-2)) + SD1;
END LOOP;
END LOOP;
SD := SD1 ** (2);
R3 : FOR i IN batchnorm_mat'RANGE(1) LOOP
C3 : FOR j IN batchnorm_mat'RANGE(2) LOOP
batchnorm_mat(i,j) := ((to_ufixed(outimg(i,j),10,-2) - ave)/(SD)) * alpha + beta ;
END LOOP;
END LOOP;
RETURN batchnorm_mat; -- return batch normalized outimg matrix named batchnorm_mat
END FUNCTION batchnorm;
begin
outimg <= zero_padding( kernel , image1 );
end Architecture ARCHofZP;
I am trying to write a signal generator with VHDL and state machine approach. it needs to have two processes in an entity and I am doing everything just as same as the course I've passed but I am getting some errors around my process and I think something must be wrong with it. this is the code
entity pulse_generator is
port(clk : in std_logic;
output: out std_logic);
end pulse_generator;
architecture Behavioral of pulse_generator is
type state is (one, two, three, four);
signal nxt, pre: state;
begin
--upper
p1: process(clk)
begin
if (falling_edge(clk))then
pre <= nxt;
end if
end process p1;
--lower
p2: process(pre)
variable count: integer range 0 to 500;
begin
case pre is
when one =>
output <= '0';
count := count+1;
if (count = 300)then
nxt <= two;
count := 0;
else nxt <= one;
end if;
when two =>
output <= '1';
count := count+1;
if (count = 400)then
nxt <= three;
count := 0;
else nxt <= two;
end if;
when three =>
output <= '0';
count := count+1;
if (count = 500)then
nxt <= four;
count := 0;
else nxt <= three;
end if;
when four =>
output <= '1';
count := count+1;
if (count = 200)then
nxt <= one;
count := 0;
else nxt <= four;
end if;
end case;
end process p2;
end Behavioral;
and these are the errors
ERROR:HDLCompiler:806 - Line 19: Syntax error near "end".
ERROR:HDLCompiler:806 - Line 22: Syntax error near "process".
ERROR:HDLCompiler:806 - Line 23: Syntax error near "variable".
ERROR:HDLCompiler:806 - Line 59: Syntax error near "process".
ERROR:HDLCompiler:806 - Line 61: Syntax error near "Behavioral"
what am I doing wrong?
i am trying to find difference of two numbers from set of number available in file. "read.txt" contain numbers as
5
15
25
36
98
654
256
20
354
and i want output as 10 10 11 62 556 398 236 334
but i am getting in my output file "realout.txt" as 0
0
10
11
556
236
236
236
236
236
236
i don't know why every time at starting position 0 is printed and at the end number is repeated 5 times more..please help me to solve this problem my code is here.
library IEEE;
library std;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
use IEEE.MATH_REAL.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_TEXTIO.ALL;
use std.textio.all; --include package textio.vhd
entity testvhdl is
end testvhdl;
architecture Behavioral of testvhdl is
constant MAX : integer := 256*256-1;
SIGNAL rstb : std_logic := '0';
SIGNAL clk : std_logic := '0';
SIGNAL a : std_logic_vector(7 downto 0) := (others=>'0');
--Outputs
SIGNAL sum : std_logic_vector(7 downto 0);
--period of clock,bit for indicating end of file.
signal endoffile : bit := '0';
signal d1,d2,intt,n: integer:=0;
signal aa,ab,ac: integer:=0;
signal linenumber : integer:=1;
--signal dbus: std_logic_vector(7 downto 0) := x"00";
--------------------------------------------------------------------------------------------
function CONV_STDLV8bit_2INT(ARG: std_logic_vector (7 downto 0))
return integer is
variable int: integer:=0;
variable tmp: std_logic_vector(7 downto 0);
begin
int :=0;
tmp := ARG;
for i in 0 to 7 loop
if (tmp(i) ='1') then
int := int+(2**i);
else
int := int+0;
end if;
end loop;
return int;
end CONV_STDLV8bit_2INT;
--------------------------------------------------------------------------------------------
function CONV_INT2STDLV(ARG: INTEGER; SIZE: INTEGER)
return STD_LOGIC_VECTOR is
variable result: STD_LOGIC_VECTOR (SIZE-1 downto 0):=x"00";
variable temp: integer:= 0;
begin
temp := ARG;
for i in 0 to SIZE-1 loop
if ((temp mod 2) = 1) then
result(i) := '1';
else
result(i) := '0';
end if;
if temp > 0 then
temp := temp / 2;
elsif (temp > integer'low) then
temp := (temp - 1) / 2; -- simulate ASR
else
temp := temp / 2; -- simulate ASR
end if;
end loop;
return result;
end CONV_INT2STDLV;
--------------------------------------------------------------------------------------------
constant PERIOD : time := 20 ns;
constant DUTY_CYCLE : real := 0.5;
constant OFFSET : time := 30 ns;
begin
-- Instantiate the Unit Under Test (UUT)
--uut: imadder PORT MAP(
-- rstb => rstb,
-- clk => clk,
-- a => a,
-- b => b,
-- sum => sum
-- );
CLOCK: PROCESS -- clock process for clk
BEGIN
WAIT for OFFSET;
CLOCK_LOOP : LOOP
clk <= '0';
WAIT FOR (PERIOD - (PERIOD * DUTY_CYCLE));
clk <= '1';
WAIT FOR (PERIOD * DUTY_CYCLE);
END LOOP CLOCK_LOOP;
END PROCESS;
tb: PROCESS
BEGIN
rstb <='0';
wait for 60ns;
rstb <='1';
wait for 1312us; -- will wait forever
END PROCESS;
reading : process
file infile : text is in "real.txt"; --declare input file 1987
file outfile : text is out "realout.txt"; --declare output file 1987
--file infile2 : text is in "img2.txt"; --declare input file 1987
variable inline,inline2 : line; --line number declaration
variable dataread1 : integer;
variable dataread2 : integer;
variable buff_out : line; --line number declaration
-- variable aa,ab,ac: integer:=0;
begin
wait until clk = '0' and clk'event;
if(n < 10) then
if (not (endfile(infile))) then --checking the "END OF FILE" is not reached.
readline(infile, inline);
readline(infile, inline2);
read(inline, dataread1);
read(inline2, dataread2);
d1 <= dataread1;
d2 <= dataread2;
-- if n mod 5 = 0 then
aa <= abs(d1 - d2);
-- a <= CONV_INT2STDLV(aa,8);
--
-- n <= n+1;
-- elsif (d1 > aa) then
-- ab <= d1 - aa;
-- ac <= ac+ab;
-- aa <= d1;
--
-- else
-- ab <= aa - d1;
-- ac <= ac+ab;
-- aa <= d1;
--
-- end if;
-- d1 <= ac;
--readline(infile2, inline2);
--read(inline2, dataread1);
--d2 <=integer(dataread1);
--b <= CONV_INT2STDLV(d2,8);
else
a<=x"00";
--b<=x"00";
end if;
else
endoffile <='1'; --set signal to tell end of file read file is reached.
end if;
-- end process reading;
--write process #negative edge
--writing : process
-- begin
-- wait until clk = '0' and clk'event;
if(endoffile='0') then --if the file end is not reached.
--intt <= CONV_STDLV8bit_2INT(aa);
if(linenumber > 0) then
n <= n+1;
--if(linenumber>11) then
write(buff_out, aa);
writeline(outfile, buff_out);-- write line to output_image text file.
--end if;
end if;
linenumber <= linenumber + 1;
else
null;
end if;
end process reading;
end Behavioral;
--WRITE (buf, string'("hello"));
--WRITELINE(fileptr,buf);
--WRITE (buf, bit_vector'(" 010111 "));
--WRITELINE(fileptr,buf);
--http://myfpgablog.blogspot.in/2011/12/memory-initialization-methods.html
-- constant MEM_DEPTH : integer := 2**ADDR_WIDTH;
-- type mem_type is array (0 to MEM_DEPTH-1) of signed(DATA_WIDTH-1 downto 0);
-- impure function init_mem(mif_file_name : in string) return mem_type is
-- file mif_file : text open read_mode is mif_file_name;
-- variable mif_line : line;
-- variable temp_bv : bit_vector(DATA_WIDTH-1 downto 0);
-- variable temp_mem : mem_type;
-- begin
-- for i in mem_type'range loop
-- readline(mif_file, mif_line);
-- read(mif_line, temp_bv);
-- temp_mem(i) := signed(to_stdlogicvector(temp_bv));
-- end loop;
-- return temp_mem;
-- end function;
-- constant mem : mem_type := init_mem("mem_init_vhd.mif");
...i don't know why every time at starting position 0 is printed and at the end number is repeated 5 times more..please help me to solve this problem my code is here.
Besides the wild context clauses and all the extraneous noise there are two things observably wrong here. First you proposed input data set for real.txt has an odd number of lines (elements - integers). Second you are misapplying the BIT signal endofile:
reading :
process
file infile : text is in "real.txt";
file outfile : text is out "realout.txt";
variable inline,inline2 : line;
variable dataread1 : integer;
variable dataread2 : integer;
variable buff_out : line;
begin
wait until clk = '0' and clk'event;
if(n < 10) then
if (not (endfile(infile))) then
readline(infile, inline);
readline(infile, inline2);
read(inline, dataread1);
read(inline2, dataread2);
d1 <= dataread1;
d2 <= dataread2;
aa <= abs(d1 - d2);
else
a<=x"00";
end if;
else
endoffile <='1';
end if;
if(endoffile='0') then
if(linenumber > 0) then
n <= n+1;
write(buff_out, aa);
writeline(outfile, buff_out);
end if;
linenumber <= linenumber + 1;
else
null;
end if;
end process reading;
This is what your design with less than 20 integers on separate lines looks like:
As you can see from the waveform that results in the last value being repeated (the falling edge of the following clocks).
I added the 720 so it wouldn't get an integer read fail assertion.
The first two zeros are from not holding off output when rstb is true and a pipeline delay loading d0, d1 on a falling clock edge and then assigning aa on the next clock edge. There isn't a pipeline signal to qualify aa as valid for output.
endofile will never get written to a '1' where that assignment is unless your data set is big enough. n is counting input pairs of integers (pairs of lines):
So endofile should be fixed (on two counts, it's not set when an end of file condition is actually encountered, and the second readline is assumed to have been successful).
There's a third thing wrong, with enough data from real.txt you're missing the last absolute difference value in realout.txt, which says that pipeline signal specifying aa is valid should have a hold over as well as a hold off.
It might be easier to fix this by troubleshooting waveforms.
For the portion of your code not commented out the context clause should look like this:
library IEEE;
use ieee.std_logic_1164.all;
use std.textio.all;
I have the following code.
CREATE OR REPLACE procedure BEFOR_VIP_RESET.CP_UPDATE_DTL_YHJ_SUM
is
cursor cur IS SELECT TRIM(DC.INV_NUM) INV_NUM,
SUM(DC.REDEEMVALUE) SUM_REDEEMVALUES
FROM DINV_COUPON DC
GROUP BY DC.INV_NUM;
INT_COUNT_DINV_COUPON_BY_INV number;
begin
for RUR1 in cur LOOP
BEGIN
SELECT COUNT(*) INTO INT_COUNT_DINV_COUPON_BY_INV
FROM DINV_DTL_YHJ DDY
WHERE TRIM(DDY.INV_NUM) = TRIM(RUR1.INV_NUM);
IF (INT_COUNT_DINV_COUPON_BY_INV != 0)
THEN
UPDATE DINV_DTL_YHJ D_D_Y
SET D_D_Y.REDEEMWAY = (RUR1.SUM_REDEEMVALUES/INT_COUNT_DINV_COUPON_BY_INV); --this error
END IF;
END;
END LOOP;
end CP_UPDATE_DTL_YHJ_SUM;
Error message:
ORA-06550: line 12, column 27:
PLS-00103: Encountered the symbol "END" when expecting one of the following:
. ( * # % & = - + ; < / > at in is mod remainder not rem
<an exponent (**)> <> or != or ~= >= <= <> and or like
When I debug I find INT_COUNT_DINV_COUPON_BY_INV and RUR1.INV_NUM have the right value.
When I change:
UPDATE DINV_DTL_YHJ D_D_Y
SET D_D_Y.REDEEMWAY = (RUR1.SUM_REDEEMVALUES/INT_COUNT_DINV_COUPON_BY_INV);
to
UPDATE DINV_DTL_YHJ D_D_Y
SET D_D_Y.REDEEMWAY = 66;
I also have the same error message.
It looks as if you forgot a WHERE clause on your UPDATE statement. Was this intentional?
Maybe something like:
WHERE TRIM(DDY.INV_NUM) = TRIM(RUR1.INV_NUM);