[ODBC] Beim Insert ein NULL einfügen?
-
Hi,
Ich habe ein C++ Programm welches mittels ODBC eine Verbindung zu einer MS SQL Datenbank aufbaut.
Ich benutze CDatabase, CRecordset und CDBVariant.
Wenn ich einen Insert mache tue ich das so:Buffer.Format("INSERT INTO TK_VER (TK_Ver, TK_Ver_P, Ver1, Ver1_P, Ver2, Ver2_P, Patch, Patch_P, Al) VALUES ('%s', %d, '%s', %d, '%s', %d, '%s', %d, '%s')", TK_Ver, TK_Ver_P, Ver1, Ver1_P, Ver2, Ver2_P, Patch, Patch_P, Al); try { db.ExecuteSQL( Buffer ); } catch (CDBException *e) { MessageBox(NULL, e->m_strError, "Nachricht", MB_OK); return false; } return true; }
Nun würde ich gerne bei bestimmten Feldern NULL einfügen. Ich weis das wenn ich die Felder nicht mit angebe das dann dafür NULL eingefügt wird aber will ja nicht für jede Mögliche Kombination nen neues Insert machen. Hoffe ihr versteht mich
MfG schirrmie
-
Warum ausgerechnet NULL ? Mach doch ein komplettes Insert Statement. Du kannst auch leere Variablen übergeben. Dann wird halt der Wert <leer> eingetragen oder bist Du irgendwie auf ein NULL Wert angewiesen. Ich arbeite bei meiner Datenbank gar nicht mit NULL. Ich habe überall Default Werte bei der Tabellenerstellung angegeben.
-
Ich benutze meine eigenen Klassen, dort sieht es so aus:
ODBCStatement stmt(connection, "insert into blah (s1, s2) values (?, ?)"); stmt.bind(1, "Hallo"); stmt.bind(2, "Welt"); stmt.execute(); stmt.bind(1, "Nix da"); stmt.bind(2); // Kein Wert -> NULL wird an den Parameter gebunden. stmt.execute();
Keine Ahnung ob es mit den MFC-Klassen Parameter-Binding gibt.
Wenn du's in reinem SQL machen willst, geht's so:
instert into blah (s1, s2) values ('Nix da', null)
-
Hi,
@ausgeloggt:
Ka was du mit <leer> meinst Ein Feld was "Leer" ist das ist doch NULL, NULL bedeutet doch "Es ist kein Inhalt vorhanden"? Und ja das brauch ich. Ich will kein "Leerstring" oder keine 0 sondern "NIX" also NULLinstert into blah (s1, s2) values ('Nix da', null)
Das sieht ja schon ganz gut aus. Allerdings benutz ich ja einen Formatierten String. Bei mir würde das ja so aussehen.
("instert into blah (s1, s2) values ('%s', '%s')", Buffer1, Buffer2);
Und dachte halt vielleicht hat jemand ne Idee das elegant zu lösen außer für jeden Fall ein neuen Insert zu machen. Ich müsste dann ja Abfragen
if( !strcmp(Buffer1, "") ) ("instert into blah (s1, s2) values (NULL, '%s')", Buffer2); if( !strcmp(Buffer2, "") ) ("instert into blah (s1, s2) values ('%s', NULL)", Buffer1);
Da das aber bei vielen Variablen umständlich und viel ist dacht ich halt jemand hat ne Idee aber anscheinend nicht oder?
MfG schirrmie
-
setz doch die variablen einfach auf "null"
oder schreibe
Buffer.Format()
um, so dass leere strings durch null ersetzt werden...jenz
-
ausgeloggt schrieb:
Warum ausgerechnet NULL ? Mach doch ein komplettes Insert Statement. Du kannst auch leere Variablen übergeben. Dann wird halt der Wert <leer> eingetragen oder bist Du irgendwie auf ein NULL Wert angewiesen. Ich arbeite bei meiner Datenbank gar nicht mit NULL. Ich habe überall Default Werte bei der Tabellenerstellung angegeben.
Wenn man mit einem Feature nicht umgehen kann, dann verwendet man es nicht und begründet man es so, daß es klingt, als wüsste man, worüber man spricht.
Nein im Ernst: Es gibt in der Datenbank einen Unterschied zwischen "keine Angabe" und eine leere Angabe. Das ist ein Feature, was sich nutzen läßt, wenn man weiß, wie es geht.
Prinzipiell ist es aber auch nicht sinnvoll, einen SQL-String so zusammenzusetzen. Bei Datenbanken sollte man immer Hostvariablen verwenden. Sonst baut man ganz schnell Sicherheitslücken durch SQL-Injection ein. Was ist denn, wenn ein String Hochkommata enthält? Dann kommt günstigstenfalls ein SQL-Fehler raus.
Schau Dir einfach die API für Hostvariablen an. Dann findest Du bestimmt auch die Lösung, wie man Null-Werte einfügt. (Das soll jetzt keine Rätselaufgabe sein, sondern ich weiß es selber nicht aus dem Stegreif).
Die Lösung, in Buffer.Format leere Strings durch Null zu ersetzen, ist ungünstig, da dann kein leerer String mehr in die Datenbank geschrieben werden kann.
Tntnet
-
tntnet schrieb:
Wenn man mit einem Feature nicht umgehen kann, dann verwendet man es nicht und begründet man es so, daß es klingt, als wüsste man, worüber man spricht.
Ja, nee iss klar
Das Prinzip ist mir klar, allerdings hätte ich keine Lust meine Results auf NULL zu prüfen. Meine Antwort war vielleicht ein wenig unglücklich ausgedrückt. Ich wollte sagen, dass bei mir sämtliche Daten (Lagerartikel, Positionen, Kunden etc) in Klassen untergebracht sind und die Werte mit einem Default initialisiert werden. Mit NULL zu arbeiten finde ich persönlich unsauber. Feature hin oder her.
:xmas1:
-
Null ist nicht unsauber. Es gibt immer wieder Sachen, die man am besten mit Null abbildet.
Wenn Du schon beim Lager bist, dann nehmen wir doch eine Datenbank, die Lagerartikel verwaltet. Jetzt könntest Du ein Feld haben, welches den Lagerbestand eines Artikels beinhaltet. Wenn der aktuelle Bestand nicht bekannt ist, ist es eher unsauber, das Feld mit dem Wert 0 zu füllen. In dem Fall hätte die Datenbank-Null eine andere Information, als der nummerische Wert 0. Wie Du das im Programm ausdrückst, ist eine andere Sache.
Auch bei optionalen Entititätsbeziehungen ist die Null angebracht, um auszudrücken, daß momentan keine Beziehung besteht.
Häufig sehe ich in der Praxis Datenbanken, wo der Designer "keine Lust" hatte, sich mit Null zu beschäftigen. "keine Lust" ist allerdings eine schlechte Begründung einer Designentscheidung. Das finde ich persönlich unsauber.
Tntnet
-
Jeder so wie er meint, aber ich würde in diesem Beispiel eher ein -1 oder ein anderes Flag für unbekannt setzten. Nur mal um eins klar zu stellen : Ich will Dir hier nicht meinen Programmierstil aufzwingen, ebenso wollte ich hier keinen Flamewar starten