Kosinator Geschrieben 11. August 2009 Teilen Geschrieben 11. August 2009 Hallo, ich habe ein Problem mit einer Tabelle und bin auch nach zwei Stunden googlen und forsten nicht auf die Lösung gekommen, vllt. ist es trivieler als ich denke und ich hane irgendwo nen Fehler... Also bitte ich euch mal kurz über den Code zu schauen und mir zu sagen, warum mein TableAdapter (der standartTableAdapter) beim update ne "NoNullAllowed-Exception" wirft. Tabellendefinition (in c# beim DB update): string[] sSQLArr = new string[] { "CREATE TABLE [dbo].[tbAnrufe](" + "[gdAnruf] [uniqueidentifier] ROWGUIDCOL NOT NULL CONSTRAINT [DF_tbAnrufe_gdAnruf] DEFAULT (newid())," + "[gdKomm] [uniqueidentifier] NOT NULL," + "[gdAdrStamm] [uniqueidentifier] NOT NULL," + "[AnrufDatum] [datetime] NOT NULL DEFAULT (getdate())," + "[AnrufTel] [nchar](20) COLLATE Latin1_General_CI_AS NOT NULL," + "[Benutzer] [int] NOT NULL," + "[BenutzerTel] [nchar](20) COLLATE Latin1_General_CI_AS NOT NULL," + "[Status] [bit] NOT NULL," + "[DauerInMinuten] [int] NOT NULL," + "CONSTRAINT [PK_tbAnrufe] PRIMARY KEY CLUSTERED ([gdAnruf] ASC)" + "WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]) ON [PRIMARY]", }; wichtig hier: "[AnrufDatum] [datetime] NOT NULL DEFAULT (getdate())," (Dann DataSet, Tableadapter (Standard, VS 2k8) und der Code mit dem Update-befehl(gekürzt): foreach (TAPILibWrapper.TelData teldata in m_TAPITelList) { DS_Telefonate.tbAnrufeRow rw = dsTel.tbAnrufe.NewtbAnrufeRow(); rw.gdAnruf = teldata.GdTelData; rw.gdKomm = teldata.GdAnrufer; rw.gdAdrStamm = teldata.GdAdrStammTel; //rw.AnrufDatum = teldata.AnrufZeit; rw.AnrufTel = teldata.TelNr; rw.Benutzer = Properties.Settings.Default.AktBenutzer; rw.BenutzerTel = "nummer"; rw.Status = teldata.Status; rw.DauerInMinuten = 0; dsTel.tbAnrufe.AddtbAnrufeRow(rw); } m_tbaAnrufe.Update(dsTel.tbAnrufe); rw.AnrufDatum wird nicht gesetzt (soll ja von der DB "gefüllt werden" (hat übrigens den Grund, dass ich mehrere Clients habr und daher die "Serverzeit" (der Zeit des PCs auf dem die DB läuft) eintragen muss, da ich nicht davon ausgehen kann, dass die Clients zeitsyncron laufen. noch n paar Properties von der Tabelle (tbAnrufe) im DataSet: Column AnrufDatum (rest ist in Ordnung): AllowDBNull = false; AutoIncrement = false; DataType System.DateTime; DefaultValue = <DBNull> NullValue = (Throw exeption) ReadOnly = false; Unique = false; ______________________________________________ Ich meine ja, dass das Problem daran liegt, dass ich keinen Wert übergebe, somit ein DBNull - wert gefüllt werden möchte, was ja nicht geht, da der TableAdapter (oder das DataSet, oder der AddRow-Befehl, was auch immer, nen Wert erwartet), aber genau diesen muss ich ja von der DB füllen lassen.... Habe auch schon (mehrmals) versucht, NULL zuzulassen, aber dann steht in der DB einfach NULL statt GetDate(), also das "speicherDatum" drin Hoffe Ihr könnt mir helfen. Gruß, Kosi p.s.: poste ne url zu diesem Thread auch im c# (.Net) Forum, hat ja auch was damit zu tun. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TDM Geschrieben 11. August 2009 Teilen Geschrieben 11. August 2009 [COLOR="Red"]"[/COLOR][AnrufDatum] [datetime] NOT NULL DEFAULT (getdate()),[COLOR="Red"]"[/COLOR] + Ist es gewollt, dass "getdate" in der DB aufgerufen werden soll? Ist die Funktion da? Case-sensitive beachtet? Was ist es denn für eine DBS? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Kosinator Geschrieben 11. August 2009 Autor Teilen Geschrieben 11. August 2009 Ist es gewollt, dass "getdate" in der DB aufgerufen werden soll? Ist die Funktion da? Case-sensitive beachtet? Was ist es denn für eine DBS? Erstmal danke für die Antwort, Ja, GetDate() soll von der DatenBank verrichtet werden (mit DateTime.Now bekomme ich zwar die Zeit beim Client, aber da diese asyncron laufen (systemzeit ist !=) kriege ich spätestens bei Anrufweiterschaltung, wenn nicht schon bei der Datenhaltung Probleme), da bin ich "sicherer" wenn ich mich an der Serverzeit (der Systemzeit des PCs auf dem der SQL2k5-server läuft) orientiere, da die "absoluter ist" (nein, ich werde keine Zeitsyncronisaton zwischen den Clients erwarten können, oder mit die gute alte "internetzeit" bei jeden Anruf holen oder so)... Die Korrekte Schreibweise ist GetDate() (eigendlich finde ich ja bei SQL alles groß nach genfer konvention, also GETDATE(), aber zum ersten ist SQL nicht case sensitiv, zum zweiten hat den code das "server mamagement studio" erzeugt und zum dritten bekomme ich bei einer nicht vorhandenen (oder falsch geschreibenen sql-prozedur (falls das so heisst) ne andere Exception (früher schon), also das ist nicht die Fehlerquelle... Die Funktion Liefert SQL, d.h. da habe ich nicht mit viel zu tun, wie gesagt, ich nutze Sie an anderen Stellen auch (GetDate() in der WHERE - Klausel z.B.) und da machts keine Probleme. DBS ? Datenbankstruktur? Naja, ich kenne zwar das fachvokabular nur mäßig, aber eine soganannte "relationelle Datenbank" (Etwa 30 Tabellen und vllt. 5 DB-Views, Tabellengröße von 5 Rows bis 50Tausend Rows, Collunms von 2 bis 20 etwa, primary Keys meist GUIDs, teilweise Rendundante Infos, aber dann zweckmäßig, also gewollt) Noch zur Info, ich arbeite zur Zeit an der Tapi (vllt schon aufgefallen^^) und versuche halt eine Übersicht über alle Gespräche zu machen (haben kein TicketSystem für unseren Support, da nur 12-Mann-Firma, und ein Nachhalten, bzw. Überblicken der GEführten Telefonate ist sowohl für uns als auch für unsete Kunden (mit Tapi-Modul) interesannt. Jetzt habe ich wieder soo viel geschrieben.... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
0815FIA Geschrieben 11. August 2009 Teilen Geschrieben 11. August 2009 versuchs mal mit: DEFAULT 'getdate()' Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TDM Geschrieben 11. August 2009 Teilen Geschrieben 11. August 2009 Ja, GetDate() soll von der DatenBank verrichtet werden Ok. Die Korrekte Schreibweise ist GetDate() (eigendlich finde ich ja bei SQL alles groß nach genfer konvention, also GETDATE(), aber zum ersten ist SQL nicht case sensitiv, zum zweiten hat den code das "server mamagement studio" erzeugt Ja, daher die Frage nach der DBS. Bei manchen ist es vielleicht case-sensitiv, im Standard aber nicht. (Sicher ist sicher, SQL-Sachen sollte man eh immer groß schreiben, deswegen hatte ich mich gewundert.) und zum dritten bekomme ich bei einer nicht vorhandenen (oder falsch geschreibenen sql-prozedur (falls das so heisst) ne andere Exception (früher schon), also das ist nicht die Fehlerquelle... Auch wieder wahr... Die Funktion Liefert SQL, d.h. da habe ich nicht mit viel zu tun, wie gesagt, ich nutze Sie an anderen Stellen auch (GetDate() in der WHERE - Klausel z.B.) und da machts keine Probleme. Was passiert, wenn du das NOT NULL rauslässt? Ich mein, das System weiß ja, dass es ein Default gibt und wenn das halt nicht explizit beim Einfügen einer Zeile angegeben wird, dann ist es NULL folglich wird automatisch auf DEFAULT gesprungen. DBS ? Datenbankstruktur? Datenbanksoftware, Datenbanksystem. Also Oracle, MS-Server, MySQL, ... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Kosinator Geschrieben 11. August 2009 Autor Teilen Geschrieben 11. August 2009 versuchs mal mit: DEFAULT 'getdate()' Hallo und danke für den Tip, hat aber nicht geholfen, mein default in der DB (SQL 2005 übrigens), ist nun ('getdate()'), glaube das ist eher schlimmer als (getdate()) nicht besser, aber es kommt immernoch die exception "AnrufDatum lässt keine nullen zu".... Werde jetzt wiedermal ne Kombination versuchen: SQL - (ganz ohne NULL, also weder NOT NULL noch NULL) und c# - die Collumn - AllowDBNULL = true: vllt. habe ich ja erfolg... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Kosinator Geschrieben 11. August 2009 Autor Teilen Geschrieben 11. August 2009 Türlich nicht Was passiert. Die DatenBank setzt nicht den Default (GetDate()), sondern einfach den NULL-Wert, da dieser ja jetzt erlaubt ist (scheinbar ist weder NULL noch NOT NULL in der Tabellendefinition das selbe (gleiche?, bin kein Deutschspezialist) wie NULL. Das bringt mich auch nicht weiter, da ich ja das anlagedatum der Row loggen möchte (SQL-serverZeit) Ich kann doch nicht der einzige mit dem Problem sein... Naja, schön weitergooglen.... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
0815FIA Geschrieben 11. August 2009 Teilen Geschrieben 11. August 2009 oh man... ich esel -.- Also wenn du T-SQL nutzt, dann weder die klammern, noch quotes einfach DEFAULT GETDATE() Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Kosinator Geschrieben 11. August 2009 Autor Teilen Geschrieben 11. August 2009 Ich werds probieren, kann ich aber erst morgen machen (im eigendlichen Projekt) danke schonmal, das klang sehr zuversichtlich (wobei der Create Table - skript aus dem Server management studio dann echt blöd ist (der macht die Klammern, also (getdate())...)...) Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Kosinator Geschrieben 12. August 2009 Autor Teilen Geschrieben 12. August 2009 Nein, leider immer noch nicht... Erstmal mein RowAdd befehl aus C#: private void button2_Click(object sender, EventArgs e) { DS_TelefonTest.tbAnrufeRow rw = dsTel.tbAnrufe.NewtbAnrufeRow(); rw.gdAnruf = Guid.NewGuid(); rw.gdOwner = Guid.NewGuid(); rw.gdAdrStamm = Guid.NewGuid(); rw.AnrufTel = "08005678111"; rw.Benutzer = 2; rw.Status = 1; rw.DauerInMinuten = 0; rw.HopBenutzer = -1; rw.Hop2Benutzer = -1; rw.Hop3Benutzer = -1; //rw.AnrufDatum = DateTime.Now; dsTel.tbAnrufe.AddtbAnrufeRow(rw); tba.Update(dsTel.tbAnrufe); } Also, ich habe zwei Möglichkeiten, die beide nicht funktionieren: 1. DB - NOT NULL DEFAULT GETDATE() // bzw. CURRENT_TIMESTAMP, ist = und c# CollumnDefinition im DataSet: AllowDBNull = false; DefaultValue = <DBNull> Ergebnis: NoNullAlloedException in AnrufDatum 2. DB - NULL DEFAULT GETDATE() // bzw. CURRENT_TIMESTAMP, ist = und c# CollumnDefinition im DataSet: AllowDBNull = true; DefaultValue = <DBNull> Ergebnis: NULL einträge in der DB, nicht GetDate() Was ich möchte ist hoffentlich klar: Das (Server)Datum des Row-Inserts als AnrufDatum haben... Danke nochmal für alls die sich mühe geben und gruß Kosi Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Kosinator Geschrieben 12. August 2009 Autor Teilen Geschrieben 12. August 2009 So ein Mist, laut msdn gibt es wohl keine Möglichkeit beim Insert die GETDATE() der DB die entsprechende Spalte füllen zu lassen Dann werde ich wohl zur Datenbank rennen müssen, mir die "Serverzeit" holen und dann eintragen (nicht Methode überschreiben)... Hoffentlich gibts nicht zu viel traffic wenns bei zehn Leuten oder mehr gleichzeitig klingelt... Danke für eure Bemühungen nochmal, wenn es doch eine bessere Lösung gibt, nehme ich sie gerne in Augenschein. Gruß, Kosi p.s.: Seltsam das SQL das nicht kann, finde ich zumindest. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
dr.dimitri Geschrieben 12. August 2009 Teilen Geschrieben 12. August 2009 Dann werde ich wohl zur Datenbank rennen müssen, mir die "Serverzeit" holen und dann eintragen (nicht Methode überschreiben)... Du kannst doch einfach den Datumsaufruf direkt in den Insert schreiben. Mal das oracle Äquivalent dazu: insert into tabelle (col1,col2,col3) values('Wert1','Wert2',sysdate) Dim Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Kosinator Geschrieben 12. August 2009 Autor Teilen Geschrieben 12. August 2009 @dr.dimitri Nein, kann ich nicht. Ich möchte ja nicht die SystemZeit (DateTime.Now (c#)) des Clients eintragen, sondern die SystemZeit des Servers, an dem die Row eingetragen wurde (auf dem die DB läuft), da ich davon ausgehen kann, dass die Client-SystemZeiten nicht syncronisiert sind, und ich sonst probleme mit der Rufweiterschaltung und Gesprächsdauer bekomme (geht um Tapi, sprich Telefone und so). Und die muss ich mir vorher holen. Mag jemand wissen wie? hier: public static DateTime GetServerDate() { DateTime serverDate = new DateTime(); using (SqlCommand command = new SqlCommand(@"SELECT GETDATE()", new SqlConnection(Properties.Settings.Default.MyConnectionString))) { command.Connection.Open(); using (SqlDataReader reader = command.ExecuteReader()) { reader.Read(); serverDate = reader.GetDateTime(0); reader.Close(); } command.Connection.Close(); } return serverDate; } Türlich ohne Try - Open - Catch ex - Finally - close, meine Connections gehen immer, buhahaha. Gruß, Kosi Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TDM Geschrieben 12. August 2009 Teilen Geschrieben 12. August 2009 Auch wenns vielleicht unsauber ist: Mit einem Trigger könnte man das doch nachprogrammieren. :floet: Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
dbwizard Geschrieben 12. August 2009 Teilen Geschrieben 12. August 2009 Du kannst doch einfach den Datumsaufruf direkt in den Insert schreiben. Mal das oracle Äquivalent dazu: insert into tabelle (col1,col2,col3) values('Wert1','Wert2',sysdate) Dim Client. Er hat alles im Client :-). Vielleicht solltest du deine Signatur fetter drucken .... gruss Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
dr.dimitri Geschrieben 12. August 2009 Teilen Geschrieben 12. August 2009 Ich möchte ja nicht die SystemZeit (DateTime.Now (c#)) des Clients eintragen, sondern die SystemZeit des Servers Deshalb solltest Du ja auch die Funktion der Datenbank hineinschreiben. Mein Beispiel würde die Serverzeit einfügen. Client. Er hat alles im Client :-). Vielleicht solltest du deine Signatur fetter drucken .... Ja manche machen es sich eben gerne etwas schwerer. Dim Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Kosinator Geschrieben 12. August 2009 Autor Teilen Geschrieben 12. August 2009 Also, Ich werde als Azubi nicht ServerFunktionen in die DB implementieren, wenn es dort noch keine gibt, zumal ich nicht weiß wie ich das aus C# nach SQL 2005 machen würde. (ich glaube du meinst doch (z.B. bei SQL server 2005 [DBName].[Programmierbarkeit].[Funktionen] und da irgendwo) Datenbankfunktionen. Aber theoretich ist das möglicherweise der elegantere und effizientere Weg, das gebe ich zu (effizien, naja, ich kenne den Overhead von DB-spezifischen, selbstgeschrtriebenen Funktionen nicht). Gruß Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
dr.dimitri Geschrieben 12. August 2009 Teilen Geschrieben 12. August 2009 Du musst überhaupt nichts implemetieren. Die Datumsfunktion (und noch viele, viele andere) sind bereits fix und fertig in der Datenbank dabei. Du musst sie einfach nur benutzen wie Du auch eine fertige C# Funktion benutzt. Schau einfach in der Doku nach wie die Datumsfunktion genau heißt und binde sie dann so in deinen INSERT ein wie ich es exemplarisch gemacht habe - fertig. Dim Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Kosinator Geschrieben 13. August 2009 Autor Teilen Geschrieben 13. August 2009 Nope, Insert mit GetDate() geht nicht, genau das ist ja mein Grundproblem, hier eine msdn Seite zu dem Problem. Also DEFAULT GETDATE() (oder auch DEFAULT CURRENT_TIMESTAMP, ist das gleiche (oder selbe?) in SQL 2005) tuts einfach nicht, das war ja das erste was ich versucht habe^^ (Den InsertBefehl macht meine TableBindingSource automatisch (VS2008-c#-generiert), etwa so: int result = 0; if ((this._tbAnrufeTableAdapter != null)) { global::System.Data.DataRow[] updatedRows = dataSet.tbAnrufe.Select(null, null, global::System.Data.DataViewRowState.ModifiedCurrent); updatedRows = this.GetRealUpdatedRows(updatedRows, allAddedRows); if (((updatedRows != null) && (0 < updatedRows.Length))) { result = (result + this._tbAnrufeTableAdapter.Update(updatedRows)); allChangedRows.AddRange(updatedRows); } } Wobei das eigendliche this._tbAnrufeTableAdapter.Update(updateRows) dann ein .Net ding ist, in das ich ohgne weiteres nicht reinsehen kann... Wenn du mir erklären könntest wie der Befehl lautet (deiner meinung nach) dann kann ich dir sagen ob, oder ob nicht er funktioniert). Gruß. p.s.: Ja, ich finde es auch seltsam, dass SQL 2005 GetDate() als Default-Insert nicht akzeptiert p.p.s.: Auf der verlinkten MSDN seite wird vorgeschlagen, entweder die GetDate() Funktion zu überschreiben (overhead riesig), oder sich die Serverzeit eben vorm Update zu holen (mache ich), oder eine eigen Funktion zu basteln, innerhalb der DB (möchte ich nicht) [falls ich das nicht falsch verstanden habe] Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.