Het negeren van een lege variabelen in een query

Status
Niet open voor verdere reacties.

Earthfighter

Gebruiker
Lid geworden
5 sep 2012
Berichten
28
Beste forumbezoekers,

Op het internet vond ik een manier om een leeg variabel te negeren. De gebruiker selecteert een aantal velden om een rapportage te maken. Het kan gebeuren dat hij een aantal velden leeg laat. Dan is het de bedoeling dat het programma dit herkent en alle records uit de database haalt. Vult hij het wel in dan zoekt het programma alleen de records met die specifieke waarden.

Dit ben ik tegengekomen:
PHP:
$sql = "";
if(!empty($value1))
  $sql = "AND location = '{$value1}' ";
if(!empty($value2))
  $sql .= "AND english_name = '{$value2}'";

$query = "SELECT * FROM moth_sightings WHERE user_id = '$username' {$sql} ";
$result = mysql_query($query) or die(mysql_error());
$r = mysql_numrows($result);

Dit is mijn resultaat tot nu toe:
PHP:
<?php
 $dsn  = "Test";
 $user = "";
 $pass = "";
  $conn  = odbc_connect("$dsn","$user","$pass");

  $value1= '12';
  $value2= 'Quantitative';
  
    if(!empty($value1))
   $sql  = "    P_ID = 				'{$value1}'";
    if(!empty($value2))
   $sql  = " AND  MethodologyType =	'{$value2}'";
    if(!empty($value3))
   $sql .= " AND ClientName = 		'{$value3}'";

$query = "SELECT * FROM NL_Project WHERE {$sql} ";
$result = odbc_exec($conn, $query);

echo "<table border='1' id='customer'>
<tr>
    <th>ID</th>
    <th>methodology</th>
	<th>ClientName</th>
</tr>";

while(odbc_fetch_row($result)) {
   echo "<tr>";
   echo "<td>" .odbc_result($result,1). "</td>";
   echo "<td>" .odbc_result($result,4). "</td>";
   echo "<td>" .odbc_result($result,6). "</td>";
   echo "</tr>";
   }
    echo "</table>";
?>

Nu lukt het me om de eerste variabel in te vullen en de rest leeg te laten.
Nu wil ik alleen de 2de variabel invullen maar dan geeft hij als foutmelding aan dat hij de 'AND' niet snapt in de query. Nu snap ik dat de query dit als foutmelding geeft. Hoe kan ik het zo voor elkaar krijgen dat ik alleen de 2de of 3de variabel invul en de 1ste niet zonder een foutmelding te geven? Moet je perse een vaste variabel invullen? zoals in mijn eerste voorbeeld (Ik bedoel daarmee dat de eerste WHERE altijd gedefinieerd moet worden).
 
Je zou een array kunnen aanmaken waarin je criteria gaat opslaan. Je kunt iets zoals dit proberen:

PHP:
$arr = array();
if(!empty($value1)){
   array_push($arr, "P_ID = '{$value1}'");
}
//.. etc

$sql = "";
if(count($arr) >= 0){
   $sql .= "WHERE " . $arr[0];
   for($i = 1; $i < count($arr); $i++){
      $sql .= " AND " . $arr[$i];
   }
}

$query = "SELECT * FROM NL_Project {$sql} ";

Wat ook een optie is; een WHERE 1=1 ervoor plakken en alles erachter met AND in de query plakken, dan krijg je iets zoals dit:
PHP:
    if(!empty($value1))
   $sql  = " AND P_ID =              '{$value1}'";
    if(!empty($value2))
   $sql  = " AND MethodologyType = '{$value2}'";
    if(!empty($value3))
   $sql .= " AND ClientName =       '{$value3}'";
 
$query = "SELECT * FROM NL_Project WHERE 1=1 {$sql} ";
Of de 2e optie nadelen met zich mee brengt zou je dan even moeten uitzoeken.
 
Laatst bewerkt:
Bedankt voor je snelle reactie. Het werkt nu :) Ik heb je array gebruikt. Snap alleen niet zo goed wat je code nu doet. Waarom zit de functie count erin?
 
Met uitleg:

PHP:
$arr = array(); // Array aanmaken om alle criteria/filteringen in op te slaan
if(!empty($value1)){ // Als de waarde niet leeg is
   array_push($arr, "P_ID = '{$value1}'"); // Voeg een criterium toe aan de lijst van criteria.
}
//.. etc

// Hier gaan we de criteria query opbouwen
$sql = ""; // We beginnen met een lege string, hierin zal de criteria query komen te staan.
if(count($arr) > 0){ // We kijken of er een criterium in de array staat door te controleren op de lengte/aantal van de array, dat moet hoger zijn dan 0 (>= veranderd in >, foutje van mij).
   $sql .= "WHERE " . $arr[0]; // Er is een criterium gevonden in de array, dus maken we een WHERE (omdat dit het 1e criterium is) en stoppen deze in de criteria query.
   for($i = 1; $i < count($arr); $i++){ // Vervolgens loopen we door elk andere criterium heen
      $sql .= " AND " . $arr[$i]; // En voegen we een AND toe aan de criteria query.
   } // Mocht er geen 2e criterium gevonden worden, zal hij alleen de WHERE toevoegen.
}
 
$query = "SELECT * FROM NL_Project {$sql} ";

Dus stel je hebt $value1 en $value3 gevuld met criteria:

[TABLE="width: 200"]$value1|123
$value3|Abc
[/TABLE]

Die prop je in een array:

[TABLE="width: 140"]P_ID = '123'
ClientName = 'Abc'[/TABLE]

Vervolgens krijg je daaruit de sql string:

[TABLE="width: 300"]
WHERE P_ID = '123' AND ClientName = 'Abc'
[/TABLE]
 
Laatst bewerkt:
Nu heb ik de filter toegepast en ben ik de filter steeds meer gaan uitbreiden. Nu zit ik met het probleem dat hij sommige filters niet meer ziet en de volgende error geeft: Division by zero >> Dat snap ik niet helemaal. Als ik precies deze query uitvoer in Microsoft visual studio dan geeft hij wel een resultaat.

De filter Project_Code werkt wel :s
Hier een gedeelte van mijn code waar het volgens mij mis gaat:

PHP:
   if (isset ($_POST["submit"])) {
       $project=					$_POST["projectcode"];
       $methodology=				$_POST["methodology"];
       $client=				        $_POST["client"];
       $clientmarket=				$_POST["clientmarket"];
       $projectstatus=				$_POST["projectstatus"];
       $year=					$_POST["year"];
	   $budget=					$_POST["budget"];
		}

/*The active filter for the query, the most important part of the script--------------------*/ 

$arr = array();

if(!empty($project)){
   array_push($arr, "Project_Code= '{$project}'");
}

if(!empty($methodology)){
   array_push($arr, "DescriptionMethodology= '{$methodology}'");
}

if(!empty($client)){
   array_push($arr, "ClientName= '{$client}'");
}

if(!empty($clientmarket)){
   array_push($arr, "ClientMarket= '{$clientmarket}'");
}

if(!empty($projectstatus)){
   array_push($arr, "Active= '{$projectstatus}'");
}

if(!empty($year)){
   array_push($arr, "(YEAR(NL_Project.enddate)='{$year}')");
}

if(!empty($year)){
   array_push($arr, "BudgetItem='{$budget}'");
}

/*array------------------------------------------------------------------------------*/

 $sql = "";
  if(count($arr) > 0){
   $sql .= "WHERE " . $arr[0];
    for($i = 1; $i < count($arr); $i++){
   $sql .= " AND " . $arr[$i];
  }
 } 

/*First query--------------------------------------------------------------------------------------*/

/*Value=Budget Randvalue=Actual*/
$query = "		SELECT SUM (NL_QuotaBudget.Value) AS Totalbudgetvalue, SUM (NL_Actuals.Randvalue) AS Totalactualvalue
FROM            NL_QuotaBudget INNER JOIN
                NL_Quota ON NL_QuotaBudget.Quota_ID = NL_Quota.Quota_ID INNER JOIN
                NL_Project ON NL_Quota.Project_ID = NL_Project.P_ID LEFT OUTER JOIN
                NL_Actuals ON NL_QuotaBudget.QuotaBudget_ID = NL_Actuals.QuotaBudget_ID {$sql}
				";
$result = odbc_exec($conn, $query);


echo "<table border='1' id='customer'>
<tr>
    <th>Budget</th>
	<th>Actual</th>
	<th>Variance</th>
	<th>Variance%</th>
</tr>";

while(odbc_fetch_row($result)) {
   echo "<tr>";
   echo "<td>" .odbc_result($result,1). "</td>";
   echo "<td>" .odbc_result($result,1). "</td>";
   echo "</tr>";
   echo "<tr>";
   echo "<td>" .(odbc_result($result,1) - odbc_result($result,2)). "</td>";
   echo "</tr>";
   echo "<tr>";
   echo "<td>" .(odbc_result($result,1)-(odbc_result($result,1) - odbc_result($result,2))). "</td>";
   echo "</tr>";
   echo "<tr>";
   echo "<td>" .number_format(((odbc_result($result,1)-(odbc_result($result,1) - odbc_result($result,2)))/odbc_result($result,1)*100),2). "%</td>";
   echo "</tr>";
   }
    echo "</table></br>";
	$totalbudgetvalue= odbc_result($result,1);
 
De fout zit op regel 85:
PHP:
echo "<td>" .number_format(((odbc_result($result,1)-(odbc_result($result,1) - odbc_result($result,2)))/odbc_result($result,1)*100),2). "%</td>";
De waarde odbc_result($result,1) is hier 0 waardoor de deling een foutmelding oplevert.

Je zou even moeten controleren waarom die waarde 0 is, en misschien is het toch wat handiger om de odbc resultaten in variabelen op te slaan om zo te code te verduidelijken. Als je dit doet zal het een stuk overzichtelijker zijn en zullen fouten eerder opvallen.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan