Zum Inhalt springen

[SQL & C#] GetDate() als deafault in NOT NULL Collumn


Kosinator

Empfohlene Beiträge

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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....

Link zu diesem Kommentar
Auf anderen Seiten teilen

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, ...

Link zu diesem Kommentar
Auf anderen Seiten teilen

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...

Link zu diesem Kommentar
Auf anderen Seiten teilen

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....

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

@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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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. :D

Dim

Link zu diesem Kommentar
Auf anderen Seiten teilen

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ß

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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]

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...