[mysql] Vreemd probleem met stored function

Pagina: 1
Acties:
  • 137 views sinds 30-01-2008
  • Reageer

Acties:
  • 0 Henk 'm!

  • cyberstalker
  • Registratie: September 2005
  • Niet online

cyberstalker

Eersteklas beunhaas

Topicstarter
Ik heb een probleem met een stored function in MySQL. Het vreemde is dat ik een werkende query toevoeg aan een werkende functie en het geheel een NIET werkende functie is.

De volgende functie werkt:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
DROP FUNCTION `get_wage`//
CREATE FUNCTION `get_wage`(
    mPid INT,
    score_count INT,
    work_date DATE,
    score_set VARCHAR(31),
    personid INT(11)
)
RETURNS decimal(6,2)
READS SQL DATA
DETERMINISTIC
get_wage_body: BEGIN
    DECLARE prev_start_value, start_value INT(11);
    DECLARE prev_fee, fee DECIMAL(6, 2);
    DECLARE prev_repeat_every, repeat_every TINYINT(4);
    DECLARE bonus_value DECIMAL(6, 2);
    DECLARE bonus_total DECIMAL(6, 2) DEFAULT 0.00;
    DECLARE EOF BOOL DEFAULT FALSE;
    DECLARE bonus_cursor
    CURSOR FOR
        SELECT
            amount,
            value,
            recursive
        FROM
            mBonus
        WHERE
            fk_mPid     =   mPid        AND
            startdate   <=  work_date   AND
            (
                enddate     >=  work_date   OR
                enddate     =   '0000-00-00'
            )                           AND
            amount      <=  score_count AND
            setMember   =   score_set
        ORDER BY
            amount;

    DECLARE extra_bonus_cursor
    CURSOR FOR
        SELECT
            amount,
            value,
            recursive
        FROM
            mExtraBonus
        WHERE
            fk_mPid     =   mPid        AND
            startdate   <=  work_date   AND
            (
                enddate     >=  work_date   OR
                enddate     =   '0000-00-00'
            )                           AND
            amount      <=  score_count AND
            setMember   =   score_set
        ORDER BY
            amount;

    DECLARE CONTINUE HANDLER
        FOR NOT FOUND
        SET EOF := TRUE;

    DECLARE EXIT HANDLER
        FOR SQLEXCEPTION
        sql_exception: BEGIN
            CLOSE bonus_cursor;
            CLOSE extra_bonus_cursor;
        END;

    OPEN bonus_cursor;
    OPEN extra_bonus_cursor;

    FETCH bonus_cursor INTO
        start_value,
        fee,
        repeat_every;

    IF (NOT EOF) THEN
        bonus_loop: LOOP
            SET prev_start_value    =   start_value;
            SET prev_fee            =   fee;
            SET prev_repeat_every   =   repeat_every;

            FETCH bonus_cursor INTO
                start_value,
                fee,
                repeat_every;

            IF (EOF) THEN
                IF (prev_repeat_every > 0) THEN
                    SET bonus_value         =   CEIL((score_count - prev_start_value + 1) / prev_repeat_every) * prev_fee;
                ELSE
                    SET bonus_value         =   prev_fee;
                END IF;
                SET bonus_total         =   bonus_total + bonus_value;
                LEAVE bonus_loop;
            END IF;

            IF (prev_repeat_every > 0 && score_count >= start_value) THEN
                SET bonus_value         =   CEIL((start_value - prev_start_value) / prev_repeat_every) * prev_fee;
            ELSEIF (prev_repeat_every > 0 && score_count < start_value) THEN
                SET bonus_value         =   CEIL((score_count - prev_start_value + 1) / prev_repeat_every) * prev_fee;
            ELSE
                SET bonus_value         =   prev_fee;
            END IF;

            SET bonus_total         =   bonus_total + bonus_value;
        END LOOP;
    END IF;

    SET EOF := FALSE;

    FETCH extra_bonus_cursor INTO
        start_value,
        fee,
        repeat_every;

    IF (NOT EOF) THEN
        extra_bonus_loop: LOOP
            SET prev_start_value    =   start_value;
            SET prev_fee            =   fee;
            SET prev_repeat_every   =   repeat_every;

            FETCH extra_bonus_cursor INTO
                start_value,
                fee,
                repeat_every;

            IF (EOF) THEN
                IF (prev_repeat_every > 0) THEN
                    SET bonus_value         =   CEIL((score_count - prev_start_value + 1) / prev_repeat_every) * prev_fee;
                ELSE
                    SET bonus_value         =   prev_fee;
                END IF;
                SET bonus_total         =   bonus_total + bonus_value;
                LEAVE extra_bonus_loop;
            END IF;

            IF (prev_repeat_every > 0 && score_count >= start_value) THEN
                SET bonus_value         =   CEIL((start_value - prev_start_value) / prev_repeat_every) * prev_fee;
            ELSEIF (prev_repeat_every > 0 && score_count < start_value) THEN
                SET bonus_value         =   CEIL((score_count - prev_start_value + 1) / prev_repeat_every) * prev_fee;
            ELSE
                SET bonus_value         =   prev_fee;
            END IF;

            SET bonus_total         =   bonus_total + bonus_value;
        END LOOP;
    END IF;

    CLOSE bonus_cursor;
    CLOSE extra_bonus_cursor;

    RETURN bonus_total;
END//


Nu wil ik een query toevoegen en de som van bonus_total en deze waarde teruggeven. Het enige wat ik verander is dat ik een extra variabele declareer om dit in op te slaan, een query draai (nadat alle cursors gesloten zijn) en het totaal teruggeef ipv enkel bonus_total. De functie wordt dan totaal het volgende:

SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
DROP FUNCTION `get_wage`//
CREATE FUNCTION `get_wage`(
    mPid INT,
    score_count INT,
    work_date DATE,
    score_set VARCHAR(31),
    personid INT(11)
)
RETURNS decimal(6,2)
READS SQL DATA
DETERMINISTIC
get_wage_body: BEGIN
    DECLARE prev_start_value, start_value INT(11);
    DECLARE prev_fee, fee DECIMAL(6, 2);
    DECLARE prev_repeat_every, repeat_every TINYINT(4);
    DECLARE base_wage DECIMAL(6, 2);
    DECLARE bonus_value DECIMAL(6, 2);
    DECLARE bonus_total DECIMAL(6, 2) DEFAULT 0.00;
    DECLARE EOF BOOL DEFAULT FALSE;
    DECLARE bonus_cursor
    CURSOR FOR
        SELECT
            amount,
            value,
            recursive
        FROM
            mBonus
        WHERE
            fk_mPid     =   mPid        AND
            startdate   <=  work_date   AND
            (
                enddate     >=  work_date   OR
                enddate     =   '0000-00-00'
            )                           AND
            amount      <=  score_count AND
            setMember   =   score_set
        ORDER BY
            amount;

    DECLARE extra_bonus_cursor
    CURSOR FOR
        SELECT
            amount,
            value,
            recursive
        FROM
            mExtraBonus
        WHERE
            fk_mPid     =   mPid        AND
            startdate   <=  work_date   AND
            (
                enddate     >=  work_date   OR
                enddate     =   '0000-00-00'
            )                           AND
            amount      <=  score_count AND
            setMember   =   score_set
        ORDER BY
            amount;

    DECLARE CONTINUE HANDLER
        FOR NOT FOUND
        SET EOF := TRUE;

    DECLARE EXIT HANDLER
        FOR SQLEXCEPTION
        sql_exception: BEGIN
            CLOSE bonus_cursor;
            CLOSE extra_bonus_cursor;
        END;

    OPEN bonus_cursor;
    OPEN extra_bonus_cursor;

    FETCH bonus_cursor INTO
        start_value,
        fee,
        repeat_every;

    IF (NOT EOF) THEN
        bonus_loop: LOOP
            SET prev_start_value    =   start_value;
            SET prev_fee            =   fee;
            SET prev_repeat_every   =   repeat_every;

            FETCH bonus_cursor INTO
                start_value,
                fee,
                repeat_every;

            IF (EOF) THEN
                IF (prev_repeat_every > 0) THEN
                    SET bonus_value         =   CEIL((score_count - prev_start_value + 1) / prev_repeat_every) * prev_fee;
                ELSE
                    SET bonus_value         =   prev_fee;
                END IF;
                SET bonus_total         =   bonus_total + bonus_value;
                LEAVE bonus_loop;
            END IF;

            IF (prev_repeat_every > 0 && score_count >= start_value) THEN
                SET bonus_value         =   CEIL((start_value - prev_start_value) / prev_repeat_every) * prev_fee;
            ELSEIF (prev_repeat_every > 0 && score_count < start_value) THEN
                SET bonus_value         =   CEIL((score_count - prev_start_value + 1) / prev_repeat_every) * prev_fee;
            ELSE
                SET bonus_value         =   prev_fee;
            END IF;

            SET bonus_total         =   bonus_total + bonus_value;
        END LOOP;
    END IF;

    SET EOF := FALSE;

    FETCH extra_bonus_cursor INTO
        start_value,
        fee,
        repeat_every;

    IF (NOT EOF) THEN
        extra_bonus_loop: LOOP
            SET prev_start_value    =   start_value;
            SET prev_fee            =   fee;
            SET prev_repeat_every   =   repeat_every;

            FETCH extra_bonus_cursor INTO
                start_value,
                fee,
                repeat_every;

            IF (EOF) THEN
                IF (prev_repeat_every > 0) THEN
                    SET bonus_value         =   CEIL((score_count - prev_start_value + 1) / prev_repeat_every) * prev_fee;
                ELSE
                    SET bonus_value         =   prev_fee;
                END IF;
                SET bonus_total         =   bonus_total + bonus_value;
                LEAVE extra_bonus_loop;
            END IF;

            IF (prev_repeat_every > 0 && score_count >= start_value) THEN
                SET bonus_value         =   CEIL((start_value - prev_start_value) / prev_repeat_every) * prev_fee;
            ELSEIF (prev_repeat_every > 0 && score_count < start_value) THEN
                SET bonus_value         =   CEIL((score_count - prev_start_value + 1) / prev_repeat_every) * prev_fee;
            ELSE
                SET bonus_value         =   prev_fee;
            END IF;

            SET bonus_total         =   bonus_total + bonus_value;
        END LOOP;
    END IF;

    CLOSE bonus_cursor;
    CLOSE extra_bonus_cursor;

    SELECT
        `mProject`.`stdHours`           *
        `wages`.`wage`
    INTO
        base_wage
    FROM
        `wages`
    JOIN
        `person`
    ON
        `wages`.`age`                   =   years(person.birthdate, work_date)  AND
        `person`.`pid`                  =   personid
    JOIN
    (
        `mWageTable2project`,
        `mProject`
    )
    ON
        `wages`.`group_id`              =   `mWageTable2project`.`fk_mWTid`     AND
        `mWageTable2project`.`fk_mPid`  =   `mProject`.`mPid`                   AND
        `mProject`.`mPid`               =   project_id;

    RETURN base_wage + bonus_total;
END//


De fout die ik krijg is 'ERROR 1326 (24000): Cursor is not open'. Dit probleem treedt op in MySQL #5.0.27-standard-log en #5.0.42-standard-log.

Wat doe ik hier verkeerd?

Ik ontken het bestaan van IE.


Acties:
  • 0 Henk 'm!

  • Padschild
  • Registratie: September 2004
  • Laatst online: 28-11-2020
Voor zover ik weet probeer je iets te closen wat al geclosed is, of je gebruikt iets wat je in die functie closed?

Acties:
  • 0 Henk 'm!

  • cyberstalker
  • Registratie: September 2005
  • Niet online

cyberstalker

Eersteklas beunhaas

Topicstarter
Padschild schreef op maandag 09 juli 2007 @ 19:34:
Voor zover ik weet probeer je iets te closen wat al geclosed is, of je gebruikt iets wat je in die functie closed?
Dat is dus het vreemde. Ik voeg een query in die wel werkt in een aparte functie. De query werkt niet met cursors en laat de cursors in de functie verder compleet met rust. Ik zie het probleem dus zelf niet.

Ik ontken het bestaan van IE.


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Wat doet dat sterretje op regel 156?

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

Verwijderd

MySQL:
1
2
3
4
5
6
7
DECLARE base_wage DECIMAL(6, 2); 

...

SELECT   ...  INTO  base_wage 

RETURN base_wage + bonus_total; 


base_wage gebruik je in je query zonder quotes, referenceert dit dan niet naar je gedeclareerde DECIMAL ipv een tabel?

edit: aah, je wilt het resultaat in die decimal proppen. Werkt dat opzich al?

krozz56 brabbelt waarschijnlijk maar wat

[ Voor 21% gewijzigd door Verwijderd op 10-07-2007 16:18 ]


Acties:
  • 0 Henk 'm!

  • Padschild
  • Registratie: September 2004
  • Laatst online: 28-11-2020
Krijg je trouwens niet een error erbij op welke regel dit gebeurt? Of werkt dat niet zo?

Acties:
  • 0 Henk 'm!

  • cyberstalker
  • Registratie: September 2005
  • Niet online

cyberstalker

Eersteklas beunhaas

Topicstarter
Snake schreef op dinsdag 10 juli 2007 @ 14:57:
Wat doet dat sterretje op regel 156?
Vermenigvuldigen :) .
Verwijderd schreef op dinsdag 10 juli 2007 @ 15:56:
MySQL:
1
2
3
4
5
6
7
DECLARE base_wage DECIMAL(6, 2); 

...

SELECT   ...  INTO  base_wage 

RETURN base_wage + bonus_total; 


base_wage gebruik je in je query zonder quotes, referenceert dit dan niet naar je gedeclareerde DECIMAL ipv een tabel?

edit: aah, je wilt het resultaat in die decimal proppen. Werkt dat opzich al?

krozz56 brabbelt waarschijnlijk maar wat
De query werkt. Als ik dit in een aparte functie stop werkt het prima en kan ik naderhand gewoon base_wage returnen :) .
Padschild schreef op dinsdag 10 juli 2007 @ 18:16:
Krijg je trouwens niet een error erbij op welke regel dit gebeurt? Of werkt dat niet zo?
Was het maar zo :{ . Dat is ook wat het debuggen van functies & procedures zo vervelend maakt.

Ik ontken het bestaan van IE.


Acties:
  • 0 Henk 'm!

  • cyberstalker
  • Registratie: September 2005
  • Niet online

cyberstalker

Eersteklas beunhaas

Topicstarter
Opgelost. Spelfoutje in een van de namen :) .

Ik ontken het bestaan van IE.

Pagina: 1