mittelgroße Recordset Frage
-
Hi Leute ich hab unten stehenden Sourcecode, in dem eine Temporäre Tabelle angelegt wird. Ich komm aber nicht an den zweiten Datensatz. Bin mir sicher ihr findet das mit einmal hin schauen aber mich haut es da jedes mal auf die Fresse.
Hier der Code:CString CACRSQLSet::CountTeile(CString Bedingung, bool IOTeile) { CString strAnzahl ="0"; CDatabase db; db.Open( _T("ACR"),FALSE,true,_T("ODBC;UID=anyusr;PWD=anyusr"),false); CRecordset Set(&db); db.ExecuteSQL(SQL_CREATE_TMP); // erzeugt TMP Tabelle db.ExecuteSQL(SQL_FILL_TMP); // füllt TMP Tabelle Set.Open(CRecordset::dynaset , SQL_CNT_IO_NIO_TEILE, CRecordset::readOnly); if(!Set.IsEOF()) { Set.GetFieldValue("ANZAHL", strAnzahl); //da will ich danach auch noch den 2. Datensatz haben } Set.Close(); db.ExecuteSQL(SQL_DROP_TMP); return strAnzahl; }
Nicht dass ihr denkt ich hab nichts probiert, folgendes:
if(!Set.IsEOF()) { Set.GetFieldValue("ANZAHL", strAnzahl); Set.MoveNext(); Set.GetFieldValue("ANZAHL",test); }
führt aber zu diesem Fehler:
FEHLER schrieb:
---------------------------
ACRSQL
---------------------------
Ungültiger Cursorstatus.---------------------------
OK
---------------------------
-
Wenn du mehr als einen Datensatz haben willst, mach doch eine while-Schleife.
Außerdem lass mal das db.ExecuteSQL(SQL_DROP_TMP); weg und schau in der Datenbank nach, ob auch alles so aussieht, wie du es dir vorstellst.
Interessant wäre noch, was du da vorhast.
-
OK was ich vorhab ist folgendes:
In dieser TMP-Tabelle stehen nach meinen SQL-Kommandos die Anzahl an IO (In Ordnung) und NIO Motoren drin. wenn jetzt also jemand wissen will wieviele Motoren in der Nachtschicht im Monat Mai produziert worden sind, bekommt er eine Statistik wieviele Tests (IO NIO Gesamt) und wieviele Teile (auch hier IO NIO Teile) daraus errechnen sich dann gewisse Sätze. Vielleicht wolltest du das aber eigentlich gar nicht wissen, sondern viel mehr was meine SQL-Kommandos machen.
Dazu siehe hier:#define SQL_CREATE_TMP "Create table #tmp_Auswertung (Zaehler int, MotorNummer char (10))" #define SQL_FILL_TMP "INSERT INTO #tmp_Auswertung ( Zaehler, MotorNummer) SELECT Max(dbo.TRWErgebnisse.Zaehler) AS MaxOfZaehler, dbo.TRWErgebnisse.MotorNummer FROM dbo.TRWErgebnisse WHERE " + Bedingung + " GROUP BY dbo.TRWErgebnisse.MotorNummer" #define SQL_CNT_IO_NIO_TEIL "SELECT Count (DISTINCT #tmp_Auswertung.MotorNummer) AS ANZAHL, dbo.TRWErgebnisse.ErrCode FROM dbo.#tmp_Auswertung INNER JOIN dbo.TRWErgebnisse ON dbo.#tmp_Auswertung.Zaehler = dbo.TRWErgebnisse.Zaehler AND dbo.#tmp_Auswertung.MotorNummer = dbo.TRWErgebnisse.MotorNummer GROUP BY dbo.TRWErgebnisse.ErrCode" #define SQL_DROP_TMP "Drop table #Tmp_Auswertung"
Werd jetzt gleich mal in die DBrein schauen, hab nur leider kein vernünftiges Tool da (naja außer meines *gg*)
Aber werde das gleich checken. Würde das aber eigenlich so gehen, wie oben wo er mir den Cursorfehler bringt?
While schleife brauch ich nicht weil es immer nur 2 Datensätze sind IO und NIOVielen lieben Dank schon im voraus (*besonders an Estartu_de) aber auch an alle anderen die sich das Problem hier zumindest mal angeschaut haben.
Vielen Dank
-
Mir ist beim Lesen der Befehl SELECT INTO über den Weg gelaufen, ich glaube, INSERT funktioniert so nicht ganz.
Kein vernünftiges Tool?
http://www.microsoft.com/downloads/details.aspx?FamilyId=C039A798-C57A-419E-ACBC-2A332CB7F959&displaylang=en
http://www.asql.biz/DbaMgr/DownLoad2k.shtm (Freeware)
Irgendwo hatte ich noch eines, falls die nix sind, schrei nochmal. Ich habe die allerdings noch nicht erfolgreich testen können, mein Server hat sich immer versteckt.Aber tröste dich, ich arbeite auch zu viel mit Osql.
-
OK ich schau jetzt erst mal dass ich in die DB rein schauen kann, aber ich glaube dass es mit dem SQL an sich vermutlich wahrscheinlich nichts zu tun hat. Denn da hat mir einer geholfen, von dem ich sehr viel gutes halte, so mit DBs und so ist der mega fit. Kleines Zitat:
Hier schimpft man mich
einen SQL-Datenbankadministrator und ich habe mich Ende des letzten und
Anfang diesen Jahres zum MCSA und MCDBA SQL Server 2000 zertifizieren
lassen.
Drum naja ich schau jetzt mal in die DB wie du schon richtig vorgeschlagen hast. Ist vermutlich die sicherste Variante um sehr viel arbeit zu sparen. Wegen den Tools hast du dir das mal angeschaut was ich neulich mal geschrieben hatte? Heißt EMS MS SQL Mangaer riesen geiles Tool das echt alles kann! Leider kostet es was, aber es hält sich in Grenzen. (glaub 350€) leider ist meine Trial abgelaufen.
-
Ich hab hier den Enterprise Manager, deswegen muss ich nicht mehr nach Alternativen gucken.
Nein, das Angucken hab ich noch nicht geschafft, hier is so viel los...Na, von den Titeln her, kann sich dein Kollege echt sehen lassen.
Ich bin noch sehr am Lernen, was T-SQL und auch die Administration betrifft - daher sind die Tips in der Richtung wirklich nur Hinweise.
-
Anscheinend brauchst du für deine DB-Operationen einen Cursor. Setz den letzten Paramter in CDatabase::Open auf TRUE, damit die CursorLib genutzt wird.
-
also ich hab jetzt mal die Tabelle angeschaut die er mir macht. Es war ein kleiner Denkfehler meinerseits drin, ich hab vorhin behauptet er countet IO und NIO wäre richtig wenn mein Fehlercode ein Bit wäre aber es ist ein int hinter dem sich dann wieder spezifische Texte verstecken. Nichts desto trotz sollte es eigentlich gehen da ich für ne Abfrage in der ich counten wollte folgende Tabelle hab:
ANZAHL | ERRCODE
263 | 0
7----| 19
13--.| 21
2----| 22
... --| ...Also halt ohne meine Platzhalter. Wie bekomm ich jetzt doch alle Daten (doch while-Schleife) zur Anzeige? Also halt wie les ich es ein?
-
Statt
if(!Set.IsEOF()) { Set.GetFieldValue("ANZAHL", strAnzahl); //da will ich danach auch noch den 2. Datensatz haben }
einfach
while(!Set.IsEOF()) { Set.GetFieldValue("ANZAHL", strAnzahl); //da will ich danach auch noch den 2. Datensatz haben Set.MoveNext(); }
sollte es sein.
-
*gg* schau mal was ich in der Zeit gemacht hab:
while(!Set.IsEOF()) { Set.GetFieldValue("IO_NIO", strAnzahl); test += strAnzahl; Set.MoveNext(); }
So jetzt aber folgendes
Ich glaub ich steh nicht an der richtige Stelle bzw nicht in der richtigen Tabelle! Ich hab ANZAHL davor schon mal an ner anderen Stelle verwendet und ich glaub darin steht er!
Wie komm ich mit getFieldValue in folgende Tabelle?Set.GetFieldValue("[dbo.#tmp_Auswertung.IO_NIO]", strAnzahl);
So geht es leider nicht!
EDIT: bringt die Meldung
---------------------------
ACRSQL
---------------------------
Ungültiger Feldname oder Feldindex.
---------------------------
OK
---------------------------
-
Das Feld heißt doch ANZAHL und nicht IO_NIO.
-
sorry verwirrend, ich hab es umbenannt da ich vermutet hab dass ich was ganz falsches einlese. In diesem Falle heißt es nun IO_NIO sorry hätte ich wohl erwähnen sollen.
-
AAAAAAAAAAAhhhhh es geht!!
Melde mich nochmal später mit den Ergebnissen.
DANKE DANKE DANKE
-
Also wollte mich ja nochmal mit den Ergebnissen melden, da es mir leider am Freitag nicht mehr gereicht hat hier das Ergebnis:
CString CACRSQLSet::CountTeile(CString Bedingung, int IOTeile) { CString strAnzahl ="0"; CString test =""; CDatabase db; db.Open( _T("ACR"),FALSE,true,_T("ODBC;UID=anyusr;PWD=anyusr"),false); CRecordset Set(&db); if(IOTeile == 0) Set.Open(CRecordset::dynaset , SQL_CNT_ALL_TEILE + Bedingung, CRecordset::readOnly); else { db.ExecuteSQL(SQL_CREATE_TMP); // erzeugt TMP Tabelle db.ExecuteSQL(SQL_FILL_TMP); // füllt TMP Tabelle Set.Open(CRecordset::dynaset , SQL_CNT_IO_NIO_TEILE, CRecordset::readOnly); } if(IOTeile == 2) { while(!Set.IsEOF()) { Set.GetFieldValue("ANZAHL", strAnzahl); test += strAnzahl + " mal Errorcode Nr. "; Set.GetFieldValue("ErrCode",strAnzahl); test += strAnzahl + "\r\n"; Set.MoveNext(); } } else Set.GetFieldValue("ANZAHL", strAnzahl); Set.Close(); if(IOTeile == 1) { db.ExecuteSQL(SQL_DROP_TMP); } if (IOTeile == 2) { db.ExecuteSQL(SQL_DROP_TMP); return test; } return strAnzahl; }
Ich mein die Funktion hatte zu dem Zeitpunkt nicht richtig funktioniert. Aber das noch viel größere Problemwar ich bin in die whileschleife auch bei nem Aufruf rein gelangt bei dem ich es gar nicht wollte
und dadurch hatte ich natürlich immer das falsche Ergebnis drinstehen, da eine ganz andere Funktion mit anderen Ergebnissen rein gekommen ist.
Dann kann ich meine Fehler natürlich nicht finden. Naja aber ich hab es ja geschafftVielen Dank für die Hilfe, denn ohne die Hilfe und vor allem die moralische Uterstützung hätte ich es wahrscheinlich nicht hinbekommen
-
NOch ne kleine Frage vielleicht wie bekomme ich den Feldinhalt als ein int zurück? oder auf jeden Fall mal als Zahlenwert? dieses ewige casten nervt! casten zum rechnen dannzurück zur Ausgabe... wäre schön wenn mir jemand dazu noch was sagen könnte.
Vielen Dank auch schon mal hierfür
-
Entweder mit dieser Version der Funktion:
void GetFieldValue( LPCTSTR lpszName, CDBVariant& varValue, short nFieldType = DEFAULT_FIELD_TYPE );
...frag mich aber nicht, wie man die benutzt.
Oder du machst dir eine eigene CRecordset-Basisklasse, in die du das casten gleich einbaust.
z.B.int n = GetIntValue(); CString str = GetStringValue();
usw.
-
*gg* manchmal sollte man sich einfach mal anschauen was so alles zu ner Funktion angeboten wird.
Vielen Dank.
Um so mehr ich mit der FKT arbeite umso mehr Fragen treten auf. Ich ruf die FKT drei mal hintereinander auf, einmal zähle ich IO einmal NIO und einmal alle. Jetzt mach ich ja jedes mal die DB auf nen Recset auf den Recset zu und dann die DB zu. Das ist doch bescheurt, oder? Kann man irgendwie mehrere Sachen zurück geben?? 3 Strings z.B. ich will nicht alles in einen kopieren und danach wieder auseinander schneiden.
-
öhm moment nicht weiter denken ich probier einfach mal ne open DB FKT zu machen und ne close und dann kann ich ja open dann abfrage 1 dann 2 dann 3 dann 4 (auch noch dazu gekommen) und dann close. Sollte ja eigentlich gehen.