webForumDet fria alternativet

Fel i databasklass

PHP

10 svar · 1 357 visningar · startad av Jester73

Medlem sedan mars 2012121 inlägg
Frågan#1

Hej

Varför får jag ett 1064 fel från MySQL DB på denna kod

function sentmtrl(){
    $dbops=new database();
    $wdate=time()-(57*24*60*60);
    $Y=date("Y",$wdate);
    $M=date("m",$wdate);
    $warning=$Y."-".$M."-01";
    ?>
    <div class="container">
        <div class="page-header">
            <h1>Sent bokföringsmaterial</h1>
        </div>
    <table class="table table-striped table-hover">
        <thead>
            <tr>
                <th class="col-md-10">Kund</th>
                <th class="col-md-2">Bokförd Period</th>
            </tr>
        </thead>
        <tbody>
        <?php
        $sql = "SELECT K.Kund_ID, K.Namn, K.Kundnr FROM tblKund AS K WHERE K.Kund_ID NOT IN (SELECT KundID FROM tblLBokf WHERE Period>='" . $warning ."') AND K.Avslutad = FALSE ORDER BY K.Kundnr";
        $res=$dbops->dbselect($sql);
        //foreach($res as $rows){
            print "<tr>\n";
            print "<td><a href=\"material.php?action=2\">" . $res['Kundnr'] . " - " . $res['Namn'] ."</a>\n";
            print "</td>\n";
            $sql2="SELECT MAX(Period) AS Per FROM tblLBokf WHERE KundID=".$res['Kund_ID'];
                    $subres=$dbops->dbselect($sql2);
                    foreach($subres as $subrow){
                    print "<td>\n";
                    if ($subrow->Per){
                            periodFormat($subrow->Per);
                    }
                    else {
                            print "Uppgift saknas";
                    }
                    }
                    print "</td>\n";
                    print "</tr>\n";
        //}
    print "</tbody>\n";    
    print "</table>\n";
    print "</div>\n";
    
    
}

Databasklassen ser ut så här

class database {
    static $connect=FALSE;
    
    function __construct() {
        
        if(self::$connect===FALSE){
            self::$connect=new mysqli(DBHOST,DBUSER,DBPASSW,DBASE)or die("Kan inte ansluta");
            
        }
        
        if(self::$connect->connect_error){
            die("F&aring;r ej kontakt med databasen");
                
        }
    }

    private function excqry($qry){
        if(!$res=self::$connect->query($qry)){
            die('Query error: ' . self::$connect->errno . '-' . self::$connect->error);
        }
        return $res;
    }
    
    function dbselect($sql){ 
        $result = self::excqry($sql);
        $results = array(); 
        while($row=$result->fetch_assoc()){ 
            $results[]=$row;     
        } 
        return $results; 
        
    }
    
}

Frågan fungerar om jag kör den i phpMyAdmin och det fungerade när jag returnerade arrayn som object. Men då måste jag iterera genom arrayn istället för ta fram värdena direkt.....om ni förstår vad jag menar

Medlem sedan jan. 2005953 inlägg
#2

mysqli::query() returnerar ett objekt av typen mysqli_result. Du kan inte komma åt värdena på det sättet du försöker göra nu, eftersom att resultatet inte är en array.

Du skulle kunna ändra din excqry()-metod så att den ser ut ungefär så här:

private function excqry($qry) {
    if (!$res=self::$connect->query($qry)) {
        die('Query error: ' . self::$connect->errno . '-' . self::$connect->error);
    }
    if ($res->num_rows == 1) {
        // Resultatet innehåller bara en rad, returnera som en array
        return $res->fetch_assoc();
    }
    // Annars, returnera hela mysqli_result-objektet
    return $res;
}
Medlem sedan mars 2012121 inlägg
#3

Hej

Jo, men gör jag inte det i funktionen dbselect?

function dbselect($sql){ 
        $result = self::excqry($sql);
        $results = array(); 
        while($row=$result->fetch_assoc()){ 
            $results[]=$row;     
        } 
        return $results; 
        
    }

Det fungerade om jag bytte ut $result->fetch_assoc() mot ...fetch_object().
Vad är skillnaden?

Men har jag förstått ditt svar rätt så måste jag returnera svaret på olika sätt beroende på om det är 1 post som hämtas eller flera eller inte ens någon.

Tack på förhand!

Medlem sedan jan. 2005953 inlägg
#4

Aha, ska erkänna att jag inte läste igenom koden så noggrant, så hade helt missat det. Problemet är att dbselect() alltid returnerar en multidimensionell array, men du vill behandla den som en endimensionell array i det här fallet. Då är det alltså i dbselect() du får lägga kollen hur många rader som returneras. Är det bara en rad, returnera $result->fetch_assoc(), annars returnera $result->fetch_all() (som kan ersätta din while-loop i dbselect()). Alternativt så struntar du i att särbehandla de fallen där det bara är en rad i resultatet och returnerar alltid $result->fetch_all(), men du kan du inte göra som du gör nu och försöka behandla det som en endimensionell array.

Medlem sedan mars 2012121 inlägg
#5

Hej

Får det fortfarande inte att lira men fungerar det att skriva så här?

private function excqry($qry){
        if(!$res=self::$connect->query($qry)){
            die('Query error: ' . self::$connect->errno . '-' . self::$connect->error);
        }
        return $res;
    }
    
    function dbselect($sql){ 
        $result = self::excqry($sql);
      
        if ($result->num_rows == 1) {    
            return $result->fetch_assoc();
        }
        elseif($result->num_rows > 1){
            return $res->fetch_all();
        }
        else {
            return $result;
        }

Anledningen till funktionen excqry är bara att just den programsnutten är ju gemensam för övriga funktioner så som delete m.m.

Tack på förhand!

Medlem sedan jan. 2005953 inlägg
#6

Du har angett fel variabelnamn här:

elseif($result->num_rows > 1){ 
            return $res->fetch_all(); 
        }

Det ska vara $result->fetch_all();

Edit:
Anropa fetch_all() med följande argument: MYSQLI_ASSOC

elseif($result->num_rows > 1){ 
            return $result->fetch_all(MYSQLI_ASSOC); 
        }
Medlem sedan mars 2012121 inlägg
#7

Tack, verkar var min grej på det här forumet. Hälften av mina frågor bottnar i att jag inte har rätt namn på variablerna... :)

Dock så fungerar det fortfarande inte.
När jag kör nedan kod så slänger MySQL iväg 1064 fel utan någon vägledning vad som är fel i frågan.
Jag har kört den mot databasen via phpMyAdmin så frågan "bör" fungera :)

function sentmtrl(){
    $dbops=new database();
    $wdate=time()-(57*24*60*60);
    $Y=date("Y",$wdate);
    $M=date("m",$wdate);
    $warning=$Y."-".$M."-01";
    ?>
    <div class="container">
        <div class="page-header">
            <h1>Sent bokföringsmaterial</h1>
        </div>
    <table class="table table-striped table-hover">
        <thead>
            <tr>
                <th class="col-md-10">Kund</th>
                <th class="col-md-2">Bokförd Period</th>
            </tr>
        </thead>
        <tbody>
        <?php
        $sql = "SELECT K.Kund_ID, K.Namn, K.Kundnr FROM tblKund AS K WHERE K.Kund_ID NOT IN (SELECT KundID FROM tblLBokf WHERE Period>='" . $warning ."') AND K.Avslutad = FALSE ORDER BY K.Kundnr";
        $res=$dbops->dbselect($sql);
        while($res){
            print "<tr>\n";
            print "<td><a href=\"material.php?action=2\">" . $res[Kundnr] . " - " . $res[Namn] ."</a>\n";
            print "</td>\n";
            $sql2="SELECT MAX(Period) AS Per FROM tblLBokf WHERE KundID=".$res[Kund_ID];
                    $subres=$dbops->dbselect($sql2);
                    //foreach($subres as $subrow){
                    print "<td>\n";
                    if ($subres['Per']){
                            periodFormat($subres['Per']);
                    }
                    else {
                            print "Uppgift saknas";
                    }
                    //}
                    print "</td>\n";
                    print "</tr>\n";
        }
    print "</tbody>\n";    
    print "</table>\n";
    print "</div>\n";
    
    
}
Medlem sedan jan. 2005953 inlägg
#8

Är det $sql eller $sql2 som genererar felkoden?

Medlem sedan mars 2012121 inlägg
#9

Skulle säga att det är första frågan.
Klippte ut hela avsnittet som berör fråga 2 och testade och plötsligt blir filen jätteseg att ladda in.

Så här ser databasklassen ut iaf

class database {
    static $connect=FALSE;
    
    function __construct() {
        
        if(self::$connect===FALSE){
            self::$connect=new mysqli(DBHOST,DBUSER,DBPASSW,DBASE)or die("Kan inte ansluta");
            
        }
        
        if(self::$connect->connect_error){
            die("F&aring;r ej kontakt med databasen");
                
        }
    }

    private function excqry($qry){
        if(!$res=self::$connect->query($qry)){
            die('Query error: ' . self::$connect->errno . '-' . self::$connect->error);
        }
        return $res;
    }
    
    function dbselect($sql){
        $result = self::excqry($sql);
      
        if ($result->num_rows == 1) {    
            return $result->fetch_assoc();
        }
        elseif($result->num_rows > 1){
            return $result->fetch_all(MYSQLI_ASSOC);
        }
        else {
            return $result;
        }
    }
    
}

Jag kanske inte kan skriva while satsen så här

function sentmtrl(){
    $dbops=new database();
    $wdate=time()-(57*24*60*60);
    $Y=date("Y",$wdate);
    $M=date("m",$wdate);
    $warning=$Y."-".$M."-01";
    ?>
    <div class="container">
        <div class="page-header">
            <h1>Sent bokföringsmaterial</h1>
        </div>
    <table class="table table-striped table-hover">
        <thead>
            <tr>
                <th class="col-md-10">Kund</th>
                <th class="col-md-2">Bokförd Period</th>
            </tr>
        </thead>
        <tbody>
        <?php
        $sql = "SELECT K.Kund_ID, K.Namn, K.Kundnr FROM tblKund AS K WHERE K.Kund_ID NOT IN (SELECT KundID FROM tblLBokf WHERE Period>='" . $warning ."') AND K.Avslutad = FALSE ORDER BY K.Kundnr";
        $res=$dbops->dbselect($sql);
        while($res){
            print "<tr>\n";
            print "<td><a href=\"material.php?action=2\">" . $res[Kundnr] . " - " . $res[Namn] ."</a>\n";
            print "</td>\n";
            
           
            print "</tr>\n";
        }
    print "</tbody>\n";    
    print "</table>\n";
    print "</div>\n";
    
    
}
Medlem sedan jan. 2005953 inlägg
#10

Hur många rader förväntar du dig i resultatet? Om du förväntar dig exakt 1 rad, då ska du inte ha någon while-loop alls, förväntar du dig flera rader så måste du loopa igenom dem.

1 rad i resultatet:

$res = $dbops->dbselect($sql);
print $res['Kundnr'];

Flera rader i resultatet:

$result = $dbops->dbselect($sql);
foreach ($result as $res) {
    print $res['Kundnr'];
}
Medlem sedan mars 2012121 inlägg
#11

TACK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:birp:birp:birp

Nu funkar "skiten"

Måste läsa på While och Foreach m.m. och lära mig när jag skall använda vad

269 ms totalt · 4 externa anrop · v20260731065814-full.1dc6f849
119 ms — deklarationer (db)
0 ms — hämta statistik (cache)
138 ms — hämta tråd, inlägg och bilagor (db)
128 ms — ändringar (db)