I have been working on a series of posts about a library to connect to databases but most of the scenarios I have to resort to some "JOIN" the problem arose when two or more tables had some columns with the same name causing the last one to prevail.
I understand that the problem may lie in a bad database design, but I cannot allow myself to say that it should be redesigned right now, I don't know how much impact a redesign has at this time ... then you have to cover the gap and make sure the patch is good, better than microsoft and windows...
As I have always told you, I am not an expert, but I like to learn and improve continuously, that's why I bring my code to a review on the site.
The code tries to work with queries where it is sought to extract information from tables with JOIN and these do not have any specific parameter, but it avoids the collision of columns with identical names.
I would like to know if this piece of code can have improvements, in its structure and if I have forgotten something (security or standard).
I've gotten to this point:
// Conection to database
function Open_Con_PDO($dbUsing){
try {
$conn = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_PRE . $dbUsing, DB_USERNAME, DB_PASS);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->exec("set names utf8");
return $conn;
} catch (PDOException $e) {
die( $e->getMessage());
}
}
// function to excute the query
function BDquery2($dbquery, $dbUsing) {
$dblink = $this->Open_Con_PDO($dbUsing);
$resultset = $dblink->prepare($dbquery);
$resultset->execute();
$outPut=[];
$rowc =0;
while ($row = $resultset->fetch(PDO::FETCH_NUM)) {
$outPut[$rowc]=[];
foreach($row as $key => $value){
$outPut[$rowc][$key]=[
'ColumnName'=>$resultset->getColumnMeta($key)['name'],
'value'=>$value
];
}
$rowc++;
}
return $outPut;
}
// USage Example:
$dbquery = "SELECT
Master_Producto.*,
Producto_Estructura.*,
Producto_Proveedor.*,
Producto_Precio.*,
FROM Master_Producto
LEFT JOIN(SELECT * FROM Producto_Estructura) AS Producto_Estructura ON ( Master_Producto.Prod_Code = Producto_Estructura.Prod_Code AND Master_Producto.Prod_PF = Producto_Estructura.Prod_PF)
LEFT JOIN(SELECT * FROM Producto_Proveedor) AS Producto_Proveedor ON ( Master_Producto.Prod_Code = Producto_Proveedor.Prod_Code AND Master_Producto.Prod_PF = Producto_Proveedor.Prod_PF)
LEFT JOIN(SELECT * FROM Producto_Precio ORDER BY Prod_DateUpd DESC) AS Producto_Precio ON ( Master_Producto.Prod_Code = Producto_Precio.Prod_Code AND Master_Producto.Prod_PF = Producto_Precio.Prod_PF)";
$result = BDquery2($dbquery,'database_name');
var_dump($result);
output example:
$result=[
10=>[
'ColumnName'='Prod_D_1',
'value'=21
],
...
24=>[
'ColumnName'='Prod_D_1',
'value'=1
],
];
once we have this array / structure, we don't lose the names of the columns or data that usually happens with FETCH_ASSOC.
UPDATE
New Script with last changes:
function BDquery2($dbquery, $dbUsing) {
$dblink = $this->Open_Con_PDO($dbUsing);
$resultset = $dblink->prepare($dbquery);
$resultset->execute();
$outPut=[];
$rowc = 0;
while ($row = $resultset->fetch(PDO::FETCH_NUM)) {
$outPut[$rowc]=[];
foreach($row as $key => $value){
$table = $resultset->getColumnMeta($key)['table'];
$column = $resultset->getColumnMeta($key)['name'];
if(!isset($outPut[$rowc][$table])){
$outPut[$rowc][$table]=[];
}
$outPut[$rowc][$table][$column]=$value;
}
$rowc++;
}
return $outPut;
}
Query Example:
SELECT MasterProducts.*, Prod_Profile.*, Prod_Det_Info.*, Prod_Det_Cost.*, Prod_Det_Price.*, Prod_PriceP.*, Prod_Cost_Prom_Men.*, Prod_Price_Net_Hist.* FROM MasterProducts
LEFT JOIN (SELECT Prod_Profile.* FROM Prod_Profile) AS Prod_Profile ON (Prod_Profile.Prod_Code = MasterProducts.Prod_Code) AND (Prod_Profile.Prod_PF = MasterProducts.Prod_PF)
LEFT JOIN (SELECT Prod_Det_Info.* FROM Prod_Det_Info) AS Prod_Det_Info ON (Prod_Det_Info.Prod_Code = MasterProducts.Prod_Code) AND (Prod_Det_Info.Prod_PF = MasterProducts.Prod_PF)
LEFT JOIN (SELECT Prod_Det_Cost.* FROM Prod_Det_Cost) AS Prod_Det_Cost ON (Prod_Det_Cost.Prod_Code = MasterProducts.Prod_Code) AND (Prod_Det_Cost.Prod_PF = MasterProducts.Prod_PF)
LEFT JOIN (SELECT Prod_Det_Price.* FROM Prod_Det_Price) AS Prod_Det_Price ON (Prod_Det_Price.Prod_Code = MasterProducts.Prod_Code) AND (Prod_Det_Price.Prod_PF = MasterProducts.Prod_PF)
LEFT JOIN (SELECT Prod_PriceP.* FROM Prod_PriceP) AS Prod_PriceP ON (Prod_PriceP.Prod_Code = MasterProducts.Prod_Code) AND (Prod_PriceP.Prod_PF = MasterProducts.Prod_PF)
LEFT JOIN (SELECT Prod_Cost_Prom_Men.* FROM Prod_Cost_Prom_Men) AS Prod_Cost_Prom_Men ON (Prod_Cost_Prom_Men.KeyIdT_CP=(SELECT Prod_Cost_Prom_Men.KeyIdT_CP FROM Prod_Cost_Prom_Men WHERE Prod_Cost_Prom_Men.Prod_Code = MasterProducts.Prod_Code AND Prod_Cost_Prom_Men.Prod_PF = MasterProducts.Prod_PF ORDER BY Prod_Cost_Prom_Men.Prod_DateUpd DESC LIMIT 1))
LEFT JOIN (SELECT Prod_Price_Net_Hist.* FROM Prod_Price_Net_Hist) AS Prod_Price_Net_Hist ON (Prod_Price_Net_Hist.KeyIdT_CP=(SELECT Prod_Price_Net_Hist.KeyIdT_CP FROM Prod_Price_Net_Hist WHERE Prod_Price_Net_Hist.Prod_Code = MasterProducts.Prod_Code AND Prod_Price_Net_Hist.Prod_PF = MasterProducts.Prod_PF ORDER BY Prod_Price_Net_Hist.P_Year DESC, Prod_Price_Net_Hist.P_Month DESC LIMIT 1))
LEFT JOIN (SELECT Prod_Cost_Hist.* FROM Prod_Cost_Hist) AS Prod_Cost_Hist ON (Prod_Cost_Hist.KeyIdT_CP=(SELECT Prod_Cost_Hist.KeyIdT_CP FROM Prod_Cost_Hist WHERE Prod_Cost_Hist.Prod_Code = MasterProducts.Prod_Code AND Prod_Cost_Hist.Prod_PF = MasterProducts.Prod_PF ORDER BY Prod_Cost_Hist.Prod_DateUpd DESC LIMIT 1))
WHERE MasterProducts.Prod_Code IN('00277','01081');
Output Example (with var_dump) but i have cut nodes with more that 10 column with repeated names:
array(16) {
[0]=>
array(8) {
["MasterProducts"]=>
array(15) {
["KeyIdT_MP"]=>
string(3) "277"
["Prod_Code"]=>
string(5) "00277"
["Prod_Mark"]=>
string(4) "0400"
["Prod_Cat"]=>
string(4) "0005"
["Prod_Prov"]=>
string(5) "00293"
["Prod_FT"]=>
string(9) "FT0000204"
["Prod_RS"]=>
string(9) "RS0000008"
["Prod_ST"]=>
string(1) "1"
["Prod_AvalCom"]=>
string(1) "1"
["Prod_OR"]=>
string(1) "1"
["Prod_PF"]=>
string(1) "1"
["Prod_PF_Price"]=>
string(1) "1"
["Prod_DateGen"]=>
string(19) "2016-11-07 12:43:25"
["Prod_DateUpd"]=>
string(19) "2021-09-06 11:31:52"
["Prod_UpdUser"]=>
string(5) "00011"
}
["Prod_Profile"]=>
array(9) {
["KeyIdT_MPP"]=>
string(3) "277"
["Prod_Code"]=>
string(5) "00277"
["Prod_PF"]=>
string(1) "1"
["Prod_CB"]=>
string(13) "8710449002399"
["Prod_ProvCode"]=>
string(6) "802140"
["Prod_Memo"]=>
string(71) "En esta area puede Dejar Mensajes para tener en cuenta en este Proceso."
["Prod_NameS"]=>
string(11) "Pa Bat 9 5m"
["Prod_NameL"]=>
string(27) "Papa Batata 9 5mm 4/5.5lb"
["RRProducts_ProductRelIMAGE"]=>
string(31) "IPROD00277-2-20210906113152.jpg"
}
["Prod_Det_Info"]=>
array(45) {
["KeyIdT_D"]=>
string(3) "277"
["Prod_Code"]=>
string(5) "00277"
["Prod_PF"]=>
string(1) "1"
["Prod_D_1"]=>
string(2) "21"
["Prod_D_2"]=>
string(3) "120"
["Prod_D_3"]=>
string(1) "0"
["Prod_D_4"]=>
string(1) "4"
["Prod_D_5"]=>
string(1) "4"
["Prod_D_6"]=>
string(1) "4"
["Prod_D_7"]=>
string(11) "24840.00000"
["Prod_D_8"]=>
string(1) "M"
["Prod_D_9"]=>
string(8) "10.00000"
["Prod_D_10"]=>
string(2) "Kg" //----> Contains 42 more columns ...
}
["Prod_Det_Cost"]=>
array(37) {
["KeyIdT_D"]=>
string(3) "277"
["Prod_Code"]=>
string(5) "00277"
["Prod_PF"]=>
string(1) "1"
["Prod_CostID"]=>
NULL
["DOC_IDPRProducts"]=>
NULL
["DOC_IDRRProducts"]=>
NULL
["Prod_D_1"]=>
string(1) "2"
["Prod_D_2"]=>
string(1) "2"
["Prod_D_3"]=>
string(6) "1.0247"
["Prod_D_4"]=>
string(1) "0"
["Prod_D_5"]=>
string(7) "0.01000"
["Prod_D_6"]=>
string(7) "0.01000"
["Prod_D_7"]=>
string(7) "0.00000"
["Prod_D_8"]=>
string(7) "0.00000"
["Prod_D_9"]=>
string(7) "8.20000"
["Prod_D_10"]=>
string(4) "5.00" //----> Contains 31 more columns ...
}
["Prod_Det_Price"]=>
array(36) {
["KeyIdT_D"]=>
string(3) "277"
["Prod_Code"]=>
string(5) "00277"
["Prod_PF"]=>
string(1) "1"
["Prod_D_1"]=>
string(1) "1"
["Prod_D_2"]=>
string(1) "1"
["Prod_D_3"]=>
string(1) "1"
["Prod_D_4"]=>
string(1) "1"
["Prod_D_5"]=>
string(1) "1"
["Prod_D_6"]=>
string(1) "1"
["Prod_D_7"]=>
string(1) "1"
["Prod_D_8"]=>
string(1) "1"
["Prod_D_9"]=>
string(1) "1"
["Prod_D_10"]=>
string(1) "1"
["Prod_D_11"]=>
string(1) "1" //----> Contains 45 more columns ...
}
["Prod_PriceP"]=>
array(20) {
["KeyIdT_PP"]=>
string(3) "117"
["Prod_DOC_ID_LPIMPT"]=>
string(12) "LPIMP0000109"
["Prod_Code"]=>
string(5) "00277"
["Prod_PF"]=>
string(1) "1"
["LP_CjxMs"]=>
string(7) "1.00000"
["LP_UnxCj"]=>
string(7) "4.00000"
["LP_UniUNY"]=>
string(2) "Kg"
["LP_Unidad"]=>
string(7) "2.50000"
["LP_FormFac"]=>
string(2) "Cj"
["LP_FormVen"]=>
string(2) "Un"
["LP_Fact"]=>
string(8) "10.02000"
["LP_Price"]=>
string(7) "8.01000"
["LP_PriceUni"]=>
string(7) "2.00250"
["LP_PriceCj"]=>
string(7) "8.01000"
["LP_DateUpd"]=>
string(19) "2021-06-23 17:10:28"
["Date_Rel"]=>
string(19) "2021-06-23 00:00:00"
["Date_Rel_Ext"]=>
string(19) "2021-03-20 00:00:00"
["Date_Rel_Ext_C"]=>
string(1) "3"
["LP_CreatorUser"]=>
string(5) "00017"
["LP_UpdUser"]=>
string(5) "00017"
}
["Prod_Cost_Prom_Men"]=>
array(10) {
["KeyIdT_CP"]=>
string(5) "10282"
["Prod_Code"]=>
string(5) "00277"
["Prod_PF"]=>
string(1) "1"
["Prod_DateUpd"]=>
string(19) "2021-09-11 12:08:22"
["P_Year"]=>
string(4) "2021"
["P_Month"]=>
string(1) "8"
["Prod_Amoun"]=>
string(8) "17664.00"
["Prod_AmounW"]=>
string(8) "17664.00"
["Prod_CostKG"]=>
string(7) "3.26000"
["Prod_CostUN"]=>
string(7) "3.26000"
}
["Prod_Price_Net_Hist"]=>
array(7) {
["KeyIdT_CP"]=>
string(5) "20592"
["Prod_Code"]=>
string(5) "00277"
["Prod_PF"]=>
string(1) "1"
["Prod_DateUpd"]=>
string(19) "2021-09-18 11:23:52"
["P_Year"]=>
string(4) "2021"
["P_Month"]=>
string(1) "8"
["Prod_Price_Net"]=>
string(7) "4.33000"
}
}
}
```
$outPut
is used? perhaps edit and show how that variable is used, as well as describe where$dbUsing
and$dbquery
come from/are defined \$\endgroup\$$result
)... Is the data returned in API results, or are only certain parts of the data used for output? \$\endgroup\$