Loop php array stored in one SQL cell - mysql

I have a table which contains body of xml document (like php array):
a:26:{s:4:"HEAD";a:1:{i:0;a:8:{s:5:"BUYER";s:13:"4640014349991";a:5:{s:7:"varGUID";s:3:" ";}s:8:"POSITION";a:17:{i:0;a:14:{s:14:"POSITIONNUMBER";s:1:"1";s:11:"DESCRIPTION";s:67:"Value 0";s:9:"UNITPRICE";s:5:"11.40";}i:1;a:14:{s:14:"POSITIONNUMBER";s:1:"2";s:11:"DESCRIPTION";s:69:"Value 1";s:9:"UNITPRICE";}i:2;}}s:7:"ECONINF";s:46:"Text";}
One cell for one document.
Now I need to found for example all of UNITPRICE which is duplicating, so I should iterate this SQL cell to find all of UNITPRICE. How I can do this?
I am trying to use SUBSTRING_INDEX for this, but it is not working because I think that substring will be show only first value of UNITPRICE in cell:
SELECT d.varName AS "Name 1",
c.varName AS "Name 2",
a.varDocNum AS "Number",
SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(b.`xmlBody`, '"PRODUCTIDBUYER";',-1),'"',2),'"',-1) AS "PRODUCTIDBUYER",
SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(b.`xmlBody`, '"DESCRIPTION";',-1),'"',2),'"',-1) AS "DESCRIPTION",
SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(b.`xmlBody`, '"UNITPRICE";',-1),'"',2),'"',-1) AS "UNITPRICE"
FROM xmls AS a
LEFT JOIN xmls_body AS b ON a.intDocID = b.intDocID
LEFT JOIN adresses AS c ON SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(b.`xmlBody`, '"BUYER";',-1),'"',2),'"',-1)=c.varAdress
LEFT JOIN adresses AS d ON a.varSender=d.varAdress
WHERE a.varRecipient in ('4640014349991')
AND a.intSendTimestamp < UNIX_TIMESTAMP('2020-02-09 23:59:59')
AND a.intSendTimestamp > UNIX_TIMESTAMP('2019-12-09 00:00:00')
AND SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(b.`xmlBody`,'"PRODUCTIDBUYER";',-1),'"',2),'"',-1) IN(
'110324',
'103208'
)
AND c.varName LIKE '%1065%'
OR '%1008%'
UPD:
I've create procedures like:
DELIMITER |
CREATE PROCEDURE prcdProduct()
BEGIN
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(q.`xmlBody`, '"DESCRIPTION";',-1),'"',2),'"',-1) AS "Product" FROM xmls_body AS q;
END
|
DELIMITER ;
but I am getting error:
#1064 - 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 'CALL prcdProduct(),
when I am trying to use stored procedure:
SELECT d.varName AS "Supplier",
c.varName AS "Shop",
a.varDocNum AS "УПД",
CALL prcdProduct(),
...
if I delete CALL I will have error that FUNCTION dbName.prcdProduct does not exist. But this I think because of without CALL we are executing functions, not PROCEDURE

Related

Creating new table from existing select statement

I am creating a new table into database. My code is below
CREATE TABLE Master_data AS
select a.*, COALESCE(b.content_view,0) as content_view, COALESCE(b.headline_view,0) as headline_view
FROM [Britannia_MMx_2021].[dbo].[Sales_20210323] a
left join [Britannia_MMx_2021].[dbo].[Doximity_20220328] b on a.NPI = b.NPI
and a.Year_Mon = b.Date;
I am getting this error
Msg 102, Level 15, State 1, Line 46
Incorrect syntax near '('.
Your SQL snippet displays characteristics of TSQL. In TSQL (e.g. in MS SQL Server) you do not use "create table as" followed by a select statement, instead you use an INTO clause e.g.
SELECT a.*
, COALESCE(b.content_view, 0) AS content_view
, COALESCE(b.headline_view, 0) AS headline_view
INTO Master_data
FROM [Britannia_MMx_2021].[dbo].[Sales_20210323] a
LEFT JOIN [Britannia_MMx_2021].[dbo].[Doximity_20220328] b ON a.NPI = b.NPI
AND a.Year_Mon = b.DATE;
In MySQL you do use CREATE TABLE [ IF NOT EXISTS ] new_table [ AS ]

Problem with syntax when try add trigger in mysql

I need help with my SYNTAX error
I try to add trigger into mysql by still have syntax error.
I will be glad for any help
When I try add this trigger i still have error 1064
Full error response is: Error Code: 1064. 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 '' at line 19 MySQL version is 5.7
CREATE TRIGGER delete_przejazdy_logger AFTER DELETE ON przejazdy FOR EACH ROW
BEGIN
INSERT INTO zmiany (rodzaj, data_modyfikaji, uzytkownik,
id_pasazera, imie_nazwisko, tel_1, tel_2, tel_3, email,
id_odbiorcy, imie_nazwisko2, tel2_1, tel2_2, dokument2,
id_adres_z, kraj_z, miejscowosc_z, adres_z, kod_z, tel_stac_z,
id_adres_do, kraj_do, miejscowosc_do, adres_do, kod_do, tel_stac_do,
data, osob, fotelik, detale, ilosc_bagazu)
(SELECT 1, CURRENT_DATE, SUBSTRING_INDEX(USER(), '#', 1),
pasazerowie.id AS id_pasazera, pasazerowie.imie_nazwisko, pasazerowie.tel_1, pasazerowie.tel_2, pasazerowie.tel_3, pasazerowie.email,
odbiorcy.id AS id_odbiorcy, odbiorcy.imie_nazwisko AS imie_nazwisko2, odbiorcy.tel_1 AS tel2_1, odbiorcy.tel_2 AS tel2_2, odbiorcy.dokument AS dokument2,
adresy_z.id AS id_adres_z, adresy_z.kraj AS kraj_z, adresy_z.miejscowosc AS miejscowosc_z, adresy_z.adres AS adres_z, adresy_z.kod AS kod_z, adresy_z.tel_stac AS tel_stac_z,
adresy_do.id AS id_adres_do, adresy_do.kraj AS kraj_do, adresy_do.miejscowosc AS miejscowosc_do, adresy_do.adres AS adres_do, adresy_do.kod AS kod_do, adresy_do.tel_stac AS tel_stac_do,
OLD.data, OLD.osob, OLD.fotelik, OLD.detale, OLD.ilosc_bagazu
FROM pasazerowie
LEFT JOIN pasazerowie odbiorcy ON OLD.id_odbiorcy = odbiorcy.id
JOIN adresy adresy_do ON OLD.id_adres_do = adresy_do.id
JOIN adresy adresy_z ON OLD.id_adres_z = adresy_z.id
WHERE pasazerowie.id = OLD.id_pasazera);
END;
I add triggers on this same db for logs on creating records and works fine.
Here is the code which works good:
CREATE TRIGGER add_przejazdy_logger AFTER INSERT ON przejazdy FOR EACH ROW
BEGIN
INSERT INTO zmiany (rodzaj, data_modyfikaji, uzytkownik,
id_pasazera, imie_nazwisko, tel_1, tel_2, tel_3, email,
id_odbiorcy, imie_nazwisko2, tel2_1, tel2_2, dokument2,
id_adres_z, kraj_z, miejscowosc_z, adres_z, kod_z, tel_stac_z,
id_adres_do, kraj_do, miejscowosc_do, adres_do, kod_do, tel_stac_do,
data, osob, fotelik, detale, ilosc_bagazu)
(SELECT 2, CURRENT_DATE, SUBSTRING_INDEX(USER(), '#', 1),
pasazerowie.id AS id_pasazera, pasazerowie.imie_nazwisko, pasazerowie.tel_1, pasazerowie.tel_2, pasazerowie.tel_3, pasazerowie.email,
odbiorcy.id AS id_odbiorcy, odbiorcy.imie_nazwisko AS imie_nazwisko2, odbiorcy.tel_1 AS tel2_1, odbiorcy.tel_2 AS tel2_2, odbiorcy.dokument AS dokument2,
adresy_z.id AS id_adres_z, adresy_z.kraj AS kraj_z, adresy_z.miejscowosc AS miejscowosc_z, adresy_z.adres AS adres_z, adresy_z.kod AS kod_z, adresy_z.tel_stac AS tel_stac_z,
adresy_do.id AS id_adres_do, adresy_do.kraj AS kraj_do, adresy_do.miejscowosc AS miejscowosc_do, adresy_do.adres AS adres_do, adresy_do.kod AS kod_do, adresy_do.tel_stac AS tel_stac_do,
NEW.data, NEW.osob, NEW.fotelik, NEW.detale, NEW.ilosc_bagazu
FROM pasazerowie
LEFT JOIN pasazerowie odbiorcy ON NEW.id_odbiorcy = odbiorcy.id
JOIN adresy adresy_do ON NEW.id_adres_do = adresy_do.id
JOIN adresy adresy_z ON NEW.id_adres_z = adresy_z.id
WHERE pasazerowie.id = NEW.id_pasazera);
END;

Stored Procedure With Function giving me errors in Oracle

I have stored procedure and function and I am calling the function in the stored procedure in ORACLE.The function CalculateIncomeTax is what is giving me errors.In MSSQL,this type of update is possible because I have done it before.I called the function in the stored procedure.When I read around the answer I get is to use a package before I cannot use a function to update a table from another table.Please if you have any idea,tell me.The error I get is
table string.string is mutating, trigger/function may not see it
Cause: A trigger (or a user defined plsql function that is referenced in this statement) attempted to look at (or modify) a table that was in the middle of being modified by the statement which fired it.
Action: Rewrite the trigger (or function) so it does not read that table.
This is function
CREATE OR REPLACE function CalculateIncomeTax(periodId NVARCHAR2,
employeeId NVARCHAR2, taxableIncome NUMBER)return NUMBER
AS
IncomeTax NUMBER (18,4);Taxable NUMBER(18,4);
BEGIN
SELECT SUM(CASE WHEN (taxableIncome > T.TAX_CUMMULATIVE_AMOUNT)
THEN (taxableIncome - T.TAX_CUMMULATIVE_AMOUNT)* T.TAX_PERCENTAGE/ 100
ELSE 0.00 END ) INTO IncomeTax
FROM TAX_LAW T JOIN PAY_GROUP P ON P.PAY_FORMULA_ID =T.TAX_FORMULA_ID
JOIN PAYROLL_MASTER PP ON P.PAY_CODE =PP.PAY_PAY_GROUP_CODE
WHERE PP.PAY_EMPLOYEE_ID = employeeId AND PP.PAY_PERIOD_CODE = periodId;
if IncomeTax IS NULL THEN IncomeTax :=0;
end if;
return IncomeTax;
end;/
This is the stored procedure
CREATE OR REPLACE PROCEDURE PROCESSPAYROLLMASTER (periodcode
VARCHAR2) AS BEGIN
INSERT INTO PAYROLL_MASTER
(
PAY_PAYROLL_ID,PAY_EMPLOYEE_ID ,PAY_EMPLOYEE_NAME,PAY_SALARY_GRADE_CODE
,PAY_SALARY_NOTCH_CODE,PAY_BASIC_SALARY,PAY_TOTAL_ALLOWANCE
,PAY_TOTAL_CASH_BENEFIT,PAY_MEDICAL_BENEFIT,PAY_TOTAL_BENEFIT
,PAY_TOTAL_DEDUCTION,PAY_GROSS_SALARY,PAY_TOTAL_TAXABLE,PAY_INCOME_TAX
,PAY_TAXABLE,PAY_PERIOD_CODE,PAY_BANK_CODE,PAY_BANK_NAME,PAY_BANK_ACCOUNT_NO
,PAY_PAY_GROUP_CODE )
SELECT
1,
E.EMP_ID AS PAY_EMPLOYEE_ID ,
E.EMP_FIRST_NAME || ' ' || E.EMP_LAST_NAME AS PAY_EMPLOYEE_NAME,
E.EMP_RANK_CODE,
'CODE',
(SC.SAL_MINIMUM_AMOUNT+( SN.SAL_SALARY_PERCENTAGE *
SC.SAL_MINIMUM_AMOUNT)/100) AS PAY_BASIC_SALARY,
0,
0,
0,
0,
0,
0,
0,
0,
0,
periodcode,
'BANKCODE',
'BANKNAME',
'BANKNUMBER',
'GENERAL'
FROM EMPLOYEE E
LEFT JOIN SALARY_SCALE SC ON SC.SAL_RANK_CODE = E.EMP_RANK_CODE
LEFT JOIN SALARY_NOTCH SN ON SC.SAL_ID = SN.SAL_SALARYSCALE_ID
WHERE E.EMP_RANK_CODE = SC.SAL_RANK_CODE AND E.EMP_STATUS=2;
CALCULATEALLOWANCE(v_payrollId,periodcode);
CALCULATECASHBENEFITS(v_payrollId,periodcode);
CALCULATEDEDUCTIONS(v_payrollId,periodcode);
-- UPDATE PAYROLL PAY_INCOME_TAX
UPDATE PAYROLL_MASTER PM SET PM.PAY_INCOME_TAX = CalculateIncomeTax(PM.PAY_PERIOD_CODE,PM.PAY_EMPLOYEE_ID,PM.PAY_TOTAL_TAXABLE) WHERE PM.PAY_PAYROLL_ID = v_payrollId;
UPDATE PAYROLL_PROCESS set PAY_CANCELLED = 1 WHERE PAY_PAY_GROUP_CODE='GENERAL' AND PAY_PERIOD_CODE=periodcode
AND PAY_ID<>v_payrollId;
COMMIT;
END ;
/
The function is querying the same table you are updating, which is what the error is reporting. As it happens you are not changing the value of the column you're querying, but Oracle doesn't check to that level - not least because there could be, for instance, a trigger that has less obvious side-effects.
The best solution really would be to not have to update at all, and to calculate and set all the value as part of the original insert, by joining to all the relevant tables. But you are already calling other procedures which are, presumably, updating some of the values you're inserting as zeros, including pay_total_taxable.
Unless you're able to reevaluate those as well, you may be stuck with doing a further update. In which case, you could remove the reference to the payroll_master table from the function and instead pass in the relevant data.
I think this is equivalent, though with out the table structures, sample data and what the other procedures are doing it's hard to be sure (so this is untested, obviously):
create or replace function calculateincometax (
p_periodid nvarchar2,
p_employeeid nvarchar2,
p_paypaygroupcode payroll_master.pay_pay_group_code%type,
p_taxableincome number
) return number as
l_incometax number(18, 4);
begin
select coalesce(sum(case when p_taxableincome > t.tax_cummulative_amount
then (taxableincome - t.tax_cummulative_amount) * t.tax_percentage / 100
else 0 end), 0)
into l_incometax
from tax_law t
join pay_group p
on p.pay_formula_id = t.tax_formula_id
where p.pay_code = p_paypaygroupcode;
return l_incometax;
end;
/
and then include the extra argument in your call:
update payroll_master pm
set pm.pay_income_tax = calculateincometax(pm.pay_period_code, pm.pay_employee_id,
pm.pay_pay_group_code, pm.pay_total_taxable)
where pm.pay_payroll_id = v_payrollid;
Although v_payrollid isn't defined in what you've shown, so even that isn't entirely clear.
I've also modified the function argument and local variable names with prefixes to remove potential ambiguity (which you seem to do by removing underscores from the names), removed the unused variable, and added a coalesce() call in place of the separate null check. Those things aren't directly relevant to the approach though.

Next value function error

I get the following error during postgresql execution:
ERROR [HY000] ERROR: you can only use a 'next value(s)' function within a target list
What is wrong with this sql statement:
SELECT TRFCON.ID
,
case when DDDCON.ID_CON = 0
then
NEXT VALUE FOR SEQ_DDD_CON
else
DWHCON.ID_CON
end ID_CON
FROM TTT_CONSUMPTION TTTCON
join DDDDWH_CON DWHCON on TTTCON.ID_ORG = DDDCON.ID_ORG
and TTTCON.ID_PRO = DDDCON.ID_PRO
and TTTCON.ID_REF = DDDCON.ID_REF
The DDL of the sequence is the following:
CREATE SEQUENCE SEQ_DDD_CON AS BIGINT
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
NO CYCLE;
From the docs for CREATE SEQUENCE
Compatibility
CREATE SEQUENCE conforms to the SQL standard, with the following exceptions:
[...]
Obtaining the next value is done using the nextval() function instead of the standard's NEXT VALUE FOR expression.

create mysql views with UNION operator on query

I am trying to create sql view with a UNION operator on it. I tried executing the sql first before embedding it to the view and the result is success. But when I try it to embed on creating a view it returned this error
"Error Code : 1064
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 'UNION
SELECT p.product_media_id AS media_id, p.product_title AS title, p.product' at line 8
"
I also assure that all columns have the same data type.
SQL view:
CREATE
/*[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
[DEFINER = { user | CURRENT_USER }]
[SQL SECURITY { DEFINER | INVOKER }]*/
VIEW `mydbname`.`s_views`
AS
(SELECT c.media_id AS media_id,
c.title AS title,
c.title_slug AS slug,
c.content_one AS description,
c.type AS cat
FROM content_content c
WHERE c.type = 'news'
OR c.type='travel_genius'
AND c.media_id IS NOT NULL
AND c.status = 1
UNION
SELECT p.product_media_id AS media_id,
p.product_title AS title,
p.product_title_slug AS slug,
p.product_description AS description,
'product' AS cat
FROM p_views p
WHERE p.product_media_id IS NOT NULL);
It is a bug in MySQL. It is the parenthesis that is triggering it:-
http://bugs.mysql.com/bug.php?id=21614