jeeroy
Goto Top

Schleife für freien Namen?

Hey Leute,
ich möchte eine Schleife bauen indem auf der Datenbank durchsucht wird welcher Computername frei ist.
Alle PC's fangen mit "TRYL" an und sollen durch meine Plattform eingetragen werden.

Wie oben schon geschrieben stehe ich da auf dem Schlauch.

Nochmal genaue erklärung.

Es sollen PC-Namen, die mit "TRYL" anfangen in die Datenbank eingetragen werden.
Hinter "TRYL" soll eine dreistellige nummer.

Sie sollen strukturiert eingetragen werden, sprich der "TRYL001" als erstes und der "TRYL999" als letztes.
Falls dazwischen schon welche vorhanden sind Bsp: "TRYL034" soll er das erkennen und die nächste zahl nehmen.

Hab leider keine Ahnung wie genau ich machen soll, könnt ihr mir vielleicht helfen?

Grüße
Kommentar vom Moderator Biber am 12.05.2011 um 00:05:44 Uhr
Wie oben schon geschrieben stehe ich da auf dem Schlauch.
Bin ich blind oder hab ich Alzheimer?

Content-ID: 166081

Url: https://administrator.de/contentid/166081

Ausgedruckt am: 23.11.2024 um 01:11 Uhr

kopie0123
kopie0123 11.05.2011 um 16:33:03 Uhr
Goto Top
Hallo,

ganz simple, auch nicht optimalste Lösung:

Schleife von 001-999 durchgehen
überprüfen ob aktuelle Zahl schon exisitert -> nächster
existiert nicht -> eintragen


Ist nicht optimal, aber ist mir so spontan eingefallen face-smile

Gruß
Jeeroy
Jeeroy 11.05.2011 um 16:35:49 Uhr
Goto Top
Hey Stinger,

danke für deine Fixe Antwort.
Werde ich leider erst morgen testen können. Gebe dann bescheid ;)

Falls jemanden noch was anderes einfällt, nur zu.
Antworten, werde ich allerdings morgen erst.

Grüße
kopie0123
kopie0123 11.05.2011 um 16:40:28 Uhr
Goto Top
Weniger Datenbankabfragen:

Einmal alle Datensätze sortiert holen und dann schauen, wo die Lücken sind face-smile
Jeeroy
Jeeroy 12.05.2011 um 09:28:38 Uhr
Goto Top
Hey Stinger,

ja da hast du recht.

und wie genau funktioniert so eine Schleife, bin was schleifen angeht nicht sehr fit, sry.
Grüße
Jeeroy
Jeeroy 12.05.2011 um 13:27:20 Uhr
Goto Top
Ok, nach ein bissl rumfriemeln und nach vielen Fehlermeldungen habe ich nun eine Lösung gefunden ;)

$i = 0;
$num = 1;
$computername_abfrage = "";  
			
	while($num >= 1)  {
	$i++;
		if ($i >= 100) { $computername_abfrage = $computername."".$i; }  
		if ($i < 100) { $computername_abfrage = $computername."0".$i; }  
		if ($i < 10) { $computername_abfrage = $computername."00".$i; }  
	$abfrage = mysql_query("select * from computername a where a.computername = '$computername_abfrage'");  
	$num = mysql_num_rows($abfrage);
	}
Danke für deine Hilfe!
Guenni
Guenni 12.05.2011 um 15:07:17 Uhr
Goto Top
Hi Jeeroy,

wenn zwischen TRYL001 und TRYL999 schon Einträge sind, kannst du dein strukturiertes Eingeben eh' vergessen.

Du kannst in einer Datenbank nicht einfach einen (G)orilla zwischen (A)ffe und (Z)ebra einfügen. Dafür kannst du Daten sortieren lassen.


Wenn das Script prüfen soll, ob ein Name schon vergeben ist, dann lass' das Script doch einfach per Zufall einen neuen Namen generieren,

falls ein Name schon vorhanden ist. Dann brauchst du keine weitere Prüfungen, sondern nur ein Formular mit einem Button "NEU": Ein Klick,

und schon ist der neue Name da. Wen interessiert denn schon, ob eine durchnummerierte Reihenfolge existiert.


<?php
//Diese PC-Namen existieren in der Tabelle. Diese müssen natürlich mittels Abfrage erstmal in einem Array gespeichert werden
$pc_arr=array(0 => "TRYL001", 1 => "TRYL012", 2 => "TRYL013", 3 => "TRYL004", 4 => "TRYL005", 5 => "TRYL016");  

//PC-Namen mit Startwert belegen
$pc_name="TRYL001";  

//Schleife läuft, solange ein Name bereits im Array vorhanden ist.
while(in_array($pc_name, $pc_arr)){
 //rand(1, 999);
 //Zum Testen nur Zufallswerte von 1 bis 20
 $nr=rand(1, 20);
 
 //%d gibt einen Integerwert aus, %03d füllt den Wert mit max. drei Nullen
 $pc_name=sprintf("TRYL%03d",$nr);  
}
//Zum Testen den neuen PC-Namen ins Array schreiben. 
//Es wird nie ein Name eingetragen, der schon vorhanden ist.
array_push($pc_arr,$pc_name);

//Namen ausgeben
echo "Neuer Eintrag: $pc_name";  

//Array ausgeben
echo "<pre>";  
print_r($pc_arr);
echo "</pre>";  
?>

Ist vielleicht nur meine Meinung, aber ich mach's mir immer so einfach wie möglich.

Gruß
Günni


@Biber:

Bin ich blind oder hab ich Alzheimer?

Doa sacht der Ulkbär: "Dü bis' blind" Überleg!!!!! "Och nee, schuldijung, des wor joa de Maulwurf. Doa wird's wohl Alzheimer sein."
Jeeroy
Jeeroy 12.05.2011 um 19:52:42 Uhr
Goto Top
Hey günni, danke für deine Antwort.

Jedoch muss ich dazu sagen, das meine variante sehrwohl auch funktioniert, wenn da schon einträge vorhanden sind.

Aus dem einfachen grunde, da ich mit meiner $abfrage, nachprüfe, ob der pc schon vorhanden ist, bzw ich lasse mir die Anzahl an vorhandenen PC's mit exact den namen, den ich Abfrage ausgebe.

$abfrage = mysql_query("select * from computername a where a.computername = '$computername_abfrage'");   
$num = mysql_num_rows($abfrage); 

Beträg die Anzahl an vorhandenen PC's nun genau 1 oder aus unatürlichen gründen vielleicht auch mehr, läuft er weiter in der schleife, pakt nochmal bei der dreistelligen zahl eine 1 dazu und überprüft erneut, bis schließlich bei $num = 0 rauskommt und wir einen pc namen haben, der noch nicht vergeben ist.

while($num >= 1)  { 
$i++;

Grüße
Guenni
Guenni 13.05.2011 um 05:39:52 Uhr
Goto Top
Hi Jeeroy,

Jedoch muss ich dazu sagen, das meine variante sehrwohl auch funktioniert, wenn da schon einträge vorhanden sind.

Ich habe nicht gesagt, dass dein Script nicht funktioniert, sondern dass du, wenn bereits Einträge da sind, keine Datensätze

dazwischen "fummeln" kannst, damit das Ganze "strukturiert" wird. Jedenfalls hatte ich den Satz . . .

Sie sollen strukturiert eingetragen werden, sprich der "TRYL001" als erstes und der "TRYL999" als letztes.

. . . so verstanden (oder auch mißverstanden).


Dann sollen die Einträge von 1 bis 999 gehen. Wenn schon 850 Einträge da sind, dann weißt du schon, dass dein Script

850 Abfragen macht, bevor es die 851 als "nicht vorhanden" findet?

Gruß
Günni
Jeeroy
Jeeroy 13.05.2011 um 08:40:21 Uhr
Goto Top
Hey Günni,

jetzt muss ich als Anfänger mit Datenbanken mal fragen: Ist das schlimm wenn die Datenbank so oft Abfragen werden muss (zum Beispiel 850), ich meine spürt man das als anwender?
Ich arbeite momentan ja noch mit xampp und da das Local läuft kann ich das noch nicht nachprüfen, sonst müsste ich sie vielleicht echt umschreiben, so wie du meintest.

Was du mit datensätze dazwischen fummeln meinst, verstehe ich noch nicht ganz, ich will ja nur, dass er die von 001 nach 999 aufzählend einordnet.

Entschuldige, wenn ich dich falsch verstanden habe:

Ich habe nicht gesagt, dass dein Script nicht funktioniert

Grüße
Biber
Biber 13.05.2011 um 09:30:18 Uhr
Goto Top
Moin jeeroy,

Zitat von @Jeeroy:
jetzt muss ich als Anfänger mit Datenbanken mal fragen: Ist das schlimm wenn die Datenbank so oft Abfragen werden muss (zum
Beispiel 850), ich meine spürt man das als anwender?
Ja, Konstrukte wie dieses sollten tunlichst vermieden werden.

Der Ablauf bei jeder einzelnen Abfrage ist
  • es wird (im PHP) ein String zusammengefrickelt
  • dieser wird weitergereicht mit den Worten "Hey, das ist nicht nur ein String, sondern auch ein syntaktisch gültiges SQL-Statement"
  • der Türsteher, dem das gesagt wird, Karl-Heinz Parser, vertraut niemals blind darauf, sondert macht jedesmal wieder einen Syntaxcheck des Statements
  • wenn er das Statement durchlässt, dann aber ohne Strassenschuhe - es wird schon teilweise von menschenlesbar in maschinenlesbar übersetzt
  • dieses abgespeckte Paket wird vom Client an den Datenbankserver geschickt (oder sagen wir "gemailt", das spiegelt eher die zeitliche Dimension wieder)
  • Beim Datenbankserver poppt dann eine Meldung hoch "Sie haben Mail..."
  • Wenn der Server grad Zeit hat, dann liest er das, bearbeitet diese Mail, also sucht den angefragten Satz und antwortet - in deinem Fall ja nur mit "Hab einen Satz/hab keinen Satz"
  • Dein Client erhält die Antwort und reagiert darauf

Wie du erahnen kannst, geht relativ gesehen die wenigste Zeit für die eigentliche Abfrage drauf für "sucht den angefragten Satz".
Die meiste Zeit wird verdaddelt für Paket einpacken, Paket transportieren, Paket auspacken, Antwortpaket schnüren, zurückschicken, transportieren und wieder auspacken.

Deshalb wenn es irgendwie geht: EINE Abfrage, ALLE Sätze holen und dann dieses Gesamtpaket in Ruhe (wenn es denn im Client-Hauptspeicher ist) analysieren.

Grüße
Biber
Guenni
Guenni 13.05.2011 um 10:25:32 Uhr
Goto Top
Hi Jeeroy,

ich habe mir mit phpMyAdmin eine Tabelle mit 2 Spalten und 6 Datensätzen anzeigen lassen. phpMyAdmin (auch lokal) zeigte eine Abfragezeit von 0,03 Sek. an, was ja nicht viel ist.

Multipliziere ich das mit 850, ergibt das aber schon 25,5 Sek.. Jetzt läuft dein Script natürlich auf dem Server, aber ich denke, einen Unterschied wird man schon merken, ob man

eine Abfrage macht und die Ergebnisse be-/verarbeitet oder ob man 850 Abfragen macht und jedes Ergebnis be-/verarbeitet.

Du kannst ja mal folgendes machen. Du fügst in dein(e) Script(e) folgende Funktion ein:

<?php>
function microtime_float() {
 list($usec, $sec) = explode(" ", microtime());  
 return ((float)$usec + (float)$sec);
}
?>

Wenn du versch. Varianten erstellt hast, kannst du dann die Zeit messen, wie lange eine Funktion läuft:

<?php>
$start=microtime_float();
Funktionsaufruf();
$ende=microtime_float();
echo "Gebrauchte Zeit: ".($ende-$start);  
?>

Deine 3 if-Abfragen (wie groß ist $i) in deinem Script kannst du übrigens auch abkürzen (Wieder ein paar Anweisungen weniger). Die Funktion sprintf gibt einen formatierten String zurück.

Damit kannst du dein Präfix (TRYL) und die folgende Nummer (001 - 999) in einem Zug an eine Variable übergeben:

$computername=sprintf("TRYL%03d", $i);

Erklärung:

% - ist der Platzhalter für $i, also für eine Variable
03 - füllt mit 1 - 3 Nullen auf
d - die übergebene Variable ist ein Integerwert


Was du mit datensätze dazwischen fummeln meinst, verstehe ich noch nicht ganz, ich will ja nur, dass er die von 001 nach 999 aufzählend einordnet.


Mit "Datensätze dazwischen fummeln" meinte ich folgendes: Deine Tabelle enthält z.B.: TRYL001, TRYL002, TRYL003, TRYL006, TRYL008.

Jetzt läuft dein Script bis TRYL003 und "merkt" nun: TRYL004 fehlt. Wenn du nun TRYL004 in die Tabelle einträgst, so ist das ein neuer Datensatz, der natürlich ans Ende der Tabelle

eingetragen wird, die dann so aussieht: TRYL001, TRYL002, TRYL003, TRYL006, TRYL008, TRYL004. Das Datenbanksystem prüft nicht, ob ein Datensatz irgendwo zwischen gehört. Darf!! es auch

nicht. Stell' dir mal vor, zu jedem TRYL??? gäbe es noch eine Detailtabelle (Hardwareausstattung, Software etc. . . .). Woher soll das Datenbanksystem "wissen", welche Details zu welchem

"TRYL???" gehören, um alle Tabellen entsprechend umzuschreiben?


Gruß
Günni
Jeeroy
Jeeroy 13.05.2011 um 12:32:56 Uhr
Goto Top
Hey Biber und Günni,

danke für eure weiteren anmerkungen, die haben mir für mein Verständnis schon mal sehr weitergeholfen!

@Biber: Wenn ich dich nun richtig verstanden habe, willst du mir damit sagen, dass meine Abfrage zwar sehr schnell geschieht, jedoch dadurch, dass sie so oft stattfinden muss sich mit der anzahl multipliziert und der ganze prozess somit viel zeit auf sich nimmt, wie Günni meinte:

Multipliziere ich das mit 850, ergibt das aber schon 25,5 Sek..

Dementsprechend, lieber eine Abfrage, die größer ist, dafür allerdings alles beinhaltet und somit höchstens 2 oder 3 Abfragen in anspruch nimmt.


@günni: Was du nun mit zwischenfummeln meintest, leuchtet mir sehr gut ein und du hast recht, an dem Computernamen hängen weitere Informationen die in weiteren Spalten geschrieben werden, zum Beispiel Standort, Seriennummer usw.

Ich werde, vielleicht heute noch, sonst Montag ein Script zusammenbasteln, was eure tipps beinhaltet.
Ich kann dieses dann ja gerne nochmal Posten, falls ihr dazu dann noch verbesserungsvorschläge habt.

@Biber und Günni: Ich danke euch für eure Tipps und Aufklärung, wie halt geschrieben, befasse mich damit noch nicht allzu lange.

Grüße
Jeeroy
Jeeroy 19.05.2011 um 18:06:08 Uhr
Goto Top
Hey,

es hat zwar eine weile gedauert, da ich noch soviel anderes um die Ohren hatte, aber ich habe mein Script nun umgeschrieben und mich an das Script von Günni gestützt.
Es funktioniert einwandfrei, das einzige was ich bissl doof fand ist, dass er immer ein Zufallswert nimmt und nicht fortlaufend zählt, aber das macht das Ergebnis ja nicht schlechter.

<!---BEGINN - Seitendefinierte Variablen----------------------------------------> 
<? 
	$pc = "TRYL";  
	$res = mysql_query("SELECT * FROM `computername` WHERE computername.computername like '".$pc."%'");        /*SQL Abfrage durchführen */  
	$anzahl = mysql_num_rows($res);
	$j = 0;
	$pc_name = $pc."001";  
?>		
<!----ENDE - Seitendefinierte Variablen----------------------------------------> 
		
	<!---BEGINN - Schleife zur Ausgabe von freiem PC Name---------------------->
	<?
		// wenn kein PC Name in diesem Standort existiert, wird Automatisch $pc_name als array eintrag genommen
		if($anzahl == 0) {
			$pc_arr = $pc_name;
		}
		else {
		// Alle vorhandenen PC-Namen werden ausgelesen und in den $pc_arr ARRAY geschrieben.
		while($dsatz = mysql_fetch_assoc($res)) {
		$pc_arr[$j] = $dsatz["COMPUTERNAME"];  
		// j wird immer um +1 erhöht
		$j++;
		}}
		
		//Schleife läuft, solange ein Name bereits im Array vorhanden ist. 
		while(in_array($pc_name, $pc_arr)) {
			// Es wird ein Zufallswert zwischen 1 und 999 genommen
			$nr = rand(1, 999);
			//%d gibt einen Integerwert aus, %03d füllt den Wert mit max. drei Nullen 
			$pc_name = sprintf($pc."%03d",$nr);  
		}
		//Es wird nie ein Name eingetragen, der schon vorhanden ist. 
		array_push($pc_arr,$pc_name);
		
		echo "Neuer Eintrag: $pc_name";  
		?>
	
	<!-----ENDE - Schleife zur Ausgabe von freiem PC Name---------------------->


Eine Frage noch dazu, da die Schleife ja solange läuft, bis ein PC-Name gefunden wurde, der noch nicht eingetragen ist, was passiert, wenn alle PC-Namen von 001 - 999 vergeben sind, dann würde die Schleife ja endlos suchen,...?

Grüße
Guenni
Guenni 22.05.2011 um 01:28:17 Uhr
Goto Top
Hi Jeeroy,

Es funktioniert einwandfrei, das einzige was ich bissl doof fand ist, dass er immer ein Zufallswert nimmt und nicht fortlaufend zählt, . . .

Dann müsstest du, wie du es bereits gemacht hast, die Nummer tatsächlich fortlaufend erhöhen.

Eine Frage noch dazu, da die Schleife ja solange läuft, bis ein PC-Name gefunden wurde, der noch nicht eingetragen ist, was passiert,
wenn alle PC-Namen von 001 - 999 vergeben sind, dann würde die Schleife ja endlos suchen,...?

Im Script die erlaubte, höchste Anzahl festlegen und prüfen, ob diese erreicht wurde. Wenn ja, Meldung ausgeben, wenn nein, den neuen Namen

eintragen.


<html>
<head>
<title>Untitled</title>
</head>
<body>
<?php
$conn=mysql_connect("localhost","guenni","guenni");  
mysql_select_db("test2");  
/*
* Wenn das Formular gesendet wurde
*/
if(isset($_POST['cmd'])){  
 $query="select pcnr from pcname order by pcnr";  
 $result=mysql_query($query,$conn);
/*
* PC-Namen in einem Array speichern
*/
 $pc_arr=array();
 while($row=mysql_fetch_array($result,MYSQL_ASSOC)){
  $pc_arr=$row['pcnr'];  
 }
/*
* Anzahl speichern, Höchstwert festlegen
*/
 $anz=count($pc_arr);
 $max=999;
/*
* Startwert
*/
 $pcname="TRYL001";  
 $nr=0;
/*
* Solange neue Nummer erzeugen, wie ein PC-Name schon vergeben ist und
* $anz kleiner als $max ist
*/
 while(in_array($pcname,$pc_arr) and $anz < $max){
  $nr++;
  $pcname=sprintf("TRYL%03d",$nr);  
 }
 /*
 * Wenn Anzahl und Maximalwert gleich sind, Meldung ausgeben
 */
 if($anz>=$max){
  echo "Es konnte kein neuer Name angelegt werden";  
	/*
	* Ansonsten neuen Namen eintragen
	*/
 }else{
           $query="insert into pcname(pcnr) values('$pcname')";  
           mysql_query($query,$conn);
         }
}
?>
<form action="" method="post">  
<input type="submit" name="cmd" value="Neue Nummer">  
</form>
<?php
$query="select pcnr from pcname order by pcnr";  
$result=mysql_query($query,$conn);
$pc_arr=array();
while($row=mysql_fetch_array($result,MYSQL_ASSOC)){
 $pc_arr=$row['pcnr'];  
}
if(count($pc_arr)==0) exit;
echo "<pre>";  
print_r($pc_arr);
echo "</pre>";  
?>
</body>
</html>

Gruß
Günni