DELIMITER $$
DROP
PROCEDURE IF EXISTS `db_nam`.ANAL_KTR$$
CREATE PROCEDURE `db_nam`.ANAL_KTR() BEGIN DECLARE I INT DEFAULT 1;
DROP
TABLE IF EXISTS RESULT;
CREATE TABLE RESULT (
KONTRAHENT CHAR(80),
STY DECIMAL,
LUT DECIMAL,
MAR DECIMAL,
KWI DECIMAL,
MAJ DECIMAL,
CZE DECIMAL,
LIP DECIMAL,
SIE DECIMAL,
WRZ DECIMAL,
PAZ DECIMAL,
LIS DECIMAL,
GRU DECIMAL,
SUMA DECIMAL,
UDZ_PROC DECIMAL(6, 3)
) ENGINE = MEMORY;
DROP
TABLE IF EXISTS TMP;
CREATE TABLE TMP (
ID_KTR INT(8) NOT NULL,
DATA DATE NOT NULL,
WALUTA CHAR(3) NOT NULL,
IDENT INT(8) NOT NULL,
WN_1 DOUBLE(15, 2) NOT NULL,
R_SPRZ DOUBLE(15, 2) NOT NULL,
UPUST DOUBLE(9, 6) NOT NULL,
ID_TOW INT(8) NOT NULL,
ILOSC DOUBLE(17, 6) NOT NULL,
C_DET DOUBLE(15, 4) NOT NULL,
FOREIGN KEY (WALUTA) REFERENCES WAL_LIST(WALUTA),
FOREIGN KEY (ID_KTR) REFERENCES KTR_LIST(ID_KTR),
FOREIGN KEY (ID_TOW) REFERENCES TOW_LIST(ID_TOW),
FOREIGN KEY (IDENT) REFERENCES `2019`.WZ(IDENT)
) ENGINE = MEMORY AS
SELECT
WZ.ID_KTR,
WZ.DATA,
WZ.WALUTA,
WZ.IDENT,
WZ.WN_1,
WZ.R_SPRZ,
WZ.UPUST,
ZAW_WZ.ID_TOW,
ZAW_WZ.ILOSC,
ZAW_WZ.C_DET
FROM
`2019`.WZ,
`2019`.ZAW_WZ
WHERE
WZ.STATUS = 2
AND WZ.IDENT = ZAW_WZ.IDENT
AND WZ.WALUTA IN(
SELECT
WALUTA
FROM
WAL_LIST
)
AND WZ.ID_KTR IN(
SELECT
ID_KTR
FROM
KTR_LIST
)
AND ZAW_WZ.ID_TOW IN(
SELECT
ID_TOW
FROM
TOW_LIST
);
WHILE I <= (
SELECT
MAX(KTR_LIST.ID)
FROM
KTR_LIST
) DO INSERT INTO RESULT(
KONTRAHENT, STY, LUT, MAR, KWI, MAJ,
CZE, LIP, SIE, WRZ, PAZ, LIS, GRU, SUMA,
UDZ_PROC
)
SELECT
(
SELECT
KTR_LIST.NAZWA
FROM
KTR_LIST
WHERE
KTR_LIST.ID = I
),
COUNT_KTR_SUM_WZ(
I,
'2019-01-01',
(
SELECT
LAST_DAY('2019-01-01')
)
),
COUNT_KTR_SUM_WZ(
I,
'2019-02-01',
(
SELECT
LAST_DAY('2019-02-01')
)
),
COUNT_KTR_SUM_WZ(
I,
'2019-03-01',
(
SELECT
LAST_DAY('2019-03-01')
)
),
COUNT_KTR_SUM_WZ(
I,
'2019-04-01',
(
SELECT
LAST_DAY('2019-04-01')
)
),
COUNT_KTR_SUM_WZ(
I,
'2019-05-01',
(
SELECT
LAST_DAY('2019-05-01')
)
),
COUNT_KTR_SUM_WZ(
I,
'2019-06-01',
(
SELECT
LAST_DAY('2019-06-01')
)
),
COUNT_KTR_SUM_WZ(
I,
'2019-07-01',
(
SELECT
LAST_DAY('2019-07-01')
)
),
COUNT_KTR_SUM_WZ(
I,
'2019-08-01',
(
SELECT
LAST_DAY('2019-08-01')
)
),
COUNT_KTR_SUM_WZ(
I,
'2019-09-01',
(
SELECT
LAST_DAY('2019-09-01')
)
),
COUNT_KTR_SUM_WZ(
I,
'2019-10-01',
(
SELECT
LAST_DAY('2019-10-01')
)
),
COUNT_KTR_SUM_WZ(
I,
'2019-11-01',
(
SELECT
LAST_DAY('2019-11-01')
)
),
COUNT_KTR_SUM_WZ(
I,
'2019-12-01',
(
SELECT
LAST_DAY('2019-12-01')
)
),
0,
0;
SET
I = I + 1;
END WHILE;
UPDATE
RESULT
SET
SUMA = STY + LUT + MAR + KWI + MAJ + CZE + LIP + SIE + WRZ + PAZ + LIS + GRU;
DELETE FROM
RESULT
WHERE
SUMA = 0;
INSERT INTO RESULT(
KONTRAHENT, STY, LUT, MAR, KWI, MAJ,
CZE, LIP, SIE, WRZ, PAZ, LIS, GRU, SUMA,
UDZ_PROC
)
SELECT
'##### P O D S U M O W A N I E #####',
SUM(STY),
SUM(LUT),
SUM(MAR),
SUM(KWI),
SUM(MAJ),
SUM(CZE),
SUM(LIP),
SUM(SIE),
SUM(WRZ),
SUM(PAZ),
SUM(LIS),
SUM(GRU),
SUM(SUMA),
0
FROM
RESULT;
UPDATE
RESULT
SET
UDZ_PROC =(
SUMA /(
SELECT
MAX(SUMA)
FROM
RESULT
)* 100
);
SELECT
*
FROM
RESULT
ORDER BY
SUMA DESC;
END$$
DROP
FUNCTION IF EXISTS `db_nam`.COUNT_KTR_SUM_WZ$$ CREATE FUNCTION `db_nam`.COUNT_KTR_SUM_WZ(
KTR_ID SMALLINT, MIN_DATE DATE, MAX_DATE DATE
) RETURNS DECIMAL BEGIN DECLARE SUMA DECIMAL;
SET
SUMA = (
SELECT
SUM(
TMP.ILOSC * IF(
TMP.WALUTA = '',
IF(
UPUST = 0,
TMP.C_DET,
ROUND(
CAST(
TMP.C_DET -(TMP.C_DET * UPUST / 100) AS DECIMAL(10, 4)
),
2
)
),
TMP.WN_1 / TMP.R_SPRZ * TMP.C_DET
)
)
FROM
TMP
WHERE
TMP.ID_KTR =(
SELECT
ID_KTR
FROM
KTR_LIST
WHERE
KTR_LIST.ID = KTR_ID
)
AND TMP.WALUTA =(
SELECT
WALUTA
FROM
KTR_LIST
WHERE
KTR_LIST.ID = KTR_ID
)
AND TMP.DATA >= MIN_DATE
AND TMP.DATA <= MAX_DATE
);
RETURN IFNULL(SUMA, 0);
END$$
CALL `db_nam`.ANAL_KTR() $$
Mam problem z przetworzeniem w/w zapytania do bazy poprzez php'owe "mysqli_multi_query".
Wszystko mam skonfigurowane właściwie, bez specjalnego delimiter'a zapytania wielo-instrukcyjne (z średnikiem) wykonują mi się poprawnie,
natomiast w tym konkretnym przypadku coś jest nie tak.
Dokładnie to samo zapytanie wykonane bezpośrednio z konsoli mysql wykonuje się bez błędów.
Czy ktoś wie w czym tkwi problem z tym delimitterem i jak to naprawić ?
To wygląda na na problem po stronie PHP, a nie bazy danych. Nie znam się na PHP, ale czy tego stringa, którego przekazujesz do mysqli_multi_query nie należałoby wcześniej 'escapować' ?
https://dev.mysql.com/doc/connectors/en/apis-php-mysqli.real-escape-string.html
Zdaje się, że nie potrzebujesz instrukcji delimiter
: https://stackoverflow.com/questions/5311141/how-to-execute-mysql-command-delimiter.
Patryk27 napisał(a):
Zdaje się, że nie potrzebujesz instrukcji
delimiter
: https://stackoverflow.com/questions/5311141/how-to-execute-mysql-command-delimiter.
Zgadza się, dzięki patryk. Wyszperałem że mysqli_multi_query nie akceptuje komendy DELIMITER i się z nią wysypuje. Tworzenie procedur i funkcji jest możliwe bez delimiter'a, ale wtedy każde polecenie utworzenia procedury/funkcji musi być w osobnych zapytaniach. Tak też zrobiłem i działa.