none
Problem beim Datum speichern in SQL Server Tabelle mit Datetime

    Frage

  • Hallo

    ich möche aus einem Access-Formular ein Datum in eine SQL-Server Tabelle speichern.

    Das läuft über eine gespeicherte Prozedure wo der Parameter @datum datetime angegeben ist.

    Die SQL-Server-Tabellen werden via ODBC an das Access-Frontend gebunden.

    Ich habe jetzt folgendes Event. SPAktion soll mir die Daten neu einfügen bzw. ändern. Das funktioniert auch alles, bis auf eben das Datum. Ich weiß nicht, wie ich das vorformatieren kann. Ich habe mal einiges getestet.

    Function DateForSQL(dteDate) As String
    'DateForSQL = "'" & Format(CDate(dteDate), "yyyymmdd") & "'"
    DateForSQL = "'" & Format(CDate(dteDate), "yyyy-mm-dd hh:mm:ss") & "'"
    End Function
    
    Private Sub cmdOK_Click()
        If Validierung = True Then
    
            SPAktion "dbo.spA_ADDUPDATEMerkliste", Me.tfid, DateForSQL(Me.tfdatum), Me.tfInhalt, Me.tfBetriebID, 2
    
            Forms("frmBetrieb").Form.Requery
            Forms("frmBetrieb")("ufoBetriebAktull").Form.Requery
    
            DoCmd.Close acForm, Me.Name
        End If
    End Sub
    Fehler 3146
    Odbc-Aufruf ist fehlgeschlagen

    Hat jemand eine Idee?

    Liebe Grüße, die Luzie!

    Samstag, 29. Oktober 2016 06:45

Antworten

  • Am 30.10.2016 schrieb Luzie:

    Die Eingabe Sql Server Managementstudio funktioniert ohne Fehler, das hatte ich schon probiert.

    Nein, das war nicht was ich meinte. In einer neuen Abfrage schreibst
    Du den Namen deiner SP rein, dahinter von Komma getrennt die einzelnen
    Werte. Jetzt F5 drücken, schon siehst Du die Fehler sehr deutlich.

    Lass dir die Werte der Variablen in Access doch mal ausgeben.
    Debug.print deinAufruf und alle Variablen dazu. Das nimmst Du so wie
    es kommt und wirfst es im SQL Management Studio in eine neue Abfrage.
    Vermutlich fehlt beim Datumswert einfach der Fliegeschiss vorne und
    hinten. So interpretiere ich die Fehlermeldung.

      Fehlerbeschreibung: [Microsoft][SQL Server Native Client 11.0][SQL Server]Falsche Syntax in der Nähe von '.2016'.

            .SQL = "EXEC " & strStoredProcedure & " " & strParameter

    Diesen Teil mit Debug.Print ausgeben lassen, wie genau sieht das aus?

    Wenn ich auf das Datums-Formularfeld ein Datumsformat lege und das Datum über den Kalendar aufrufe, kommt o.g. Fehler. Gebe ich es manuell ein, wird korrekt gespeichert. Ich habe jetzt das Feld getrimmt und das funktioniert.

    Funktioniert jetzt alles?

    @Winfried
    Ich habe mir das Buch Access und SQL Server gekauft, wo ja Bernd Jungbluth als Autor aufgeführt wird. Dort sind auch sehr viele Beispeildateien enthalten mit denen ich vorwiegend arbeite und die echt gut helfen. Ich werde die Geschäftlogik komplett ändern und Datenherkunft nur in ganz vereinzelten Fällen aus den Tabellen direkt holen. Im Buch wurde mehrmals und ausdrücklich auf Lese- und Schreibsperren des SQL Servers hingewiesen, was wohl sehr nervig sein kann. Ich kann das nicht beurteilen. Deshalb habe ich die Abfragen in gespeicherte Prozeduren ausgelagert.

    Das ist ja soweit in Ordnung, bezüglich Schreibsperren mußt Du
    natürlich manuell in Aktion treten und etwas passendes einbauen.

    Servus
    Winfried


    Access-FAQ: http://www.donkarl.com/AccessFAQ.htm Access-Stammtisch: http://www.access-muenchen.de
    NNTP-Bridge für MS-Foren: http://communitybridge.codeplex.com/
    vbeTwister: http://www.vbetwister.com/

    • Als Antwort markiert Luzie Sonntag, 30. Oktober 2016 13:38
    Sonntag, 30. Oktober 2016 11:38

Alle Antworten

  • Hallo Luzie,

    wie das in Access an sich Richtung SQL Server gemacht werden muss, weiß ich nicht. Letztendlich sollte man immer mit dem richtigen Datentyp (in deinem Fall datetime) arbeiten, dann hätte man das Problem gar nicht erst.

    Wenn Du das aber unbedingt als String haben willst, wäre

    yyyyMMdd (bspw. 20161231)

    bzw.

    yyyy-MM-ddThh:mm:ss (bspw. 2016-12-31T23:59:59)

    eigentlich schon passend.

    Da Du anscheinend eine Stored Procedure "spA_ADDUPDATEMerkliste" aufrufst, solltest Du auch mal schauen, was dort eigentlich als Datentyp erwartet wird.

    Poste bitte auch die exakte und vollständige Fehlermeldung.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Samstag, 29. Oktober 2016 08:16
  • Am 29.10.2016 schrieb Luzie:

    Das läuft über eine gespeicherte Prozedure wo der Parameter @datum datetime angegeben ist.

    Die SQL-Server-Tabellen werden via ODBC an das Access-Frontend gebunden.

    Wenn Du ohne eingebundene Tabellen arbeitest, bist Du wesentlich
    flexibler. Bernd Jungbluth hat auf der AEK17 dazu einen Vortrag
    gehalten. http://donkarl.com/Downloads/AEK/ AEK17 >
    http://donkarl.com/Downloads/AEK/AEK17_LogikSQLServer.zip Schau dir
    die Beispiele dazu an, insbesonders die in Access. Damit wird vieles
    klarer und auch wesentlich einfacher.

    Ich habe jetzt folgendes Event. SPAktion soll mir die Daten neu einfügen bzw. ändern. Das funktioniert auch alles, bis auf eben das Datum. Ich weiß nicht, wie ich das vorformatieren kann. Ich habe mal einiges getestet.

    Function DateForSQL(dteDate) As String
    'DateForSQL = "'" & Format(CDate(dteDate), "yyyymmdd") & "'"
    DateForSQL = "'" & Format(CDate(dteDate), "yyyy-mm-dd hh:mm:ss") & "'"
    End Function

    Beispiel aus einer meiner AccessFEs:

    Dim Wartungsvertrag_bis_Datum As Variant
    
    fldGTWartungsvertrag_bis_Datum = DatumFeld(Me[txtfldGTWartungsvertrag_bis_Datum]) 
    
    Public Function DatumFeld(v As Variant) As Variant 
    On Error GoTo Fehler:
    
     'Funktion übergibt "NULL" oder den Feldinhalt mit ' ' außen herum. 
    
    If v = "" Then 
      v = "NULL" 
    ElseIf v = "NULL" Then 
      v = "NULL" 
    ElseIf v = Null Then 
      v = "NULL" 
    ElseIf IsNull(v) Then 
      v = "NULL" 
    Else 
      v = "'" & v & "'" 
    End If 
    DatumFeld = v 
    
    exit_DatumFeld: 
      Exit Function 
    Fehler: Call HandleError(mModName & ".DatumFeld(v As Variant) As Variant") 
      DatumFeld = "" 
      Resume exit_DatumFeld 
    End Function 


    Private Sub cmdOK_Click() If Validierung = True Then SPAktion "dbo.spA_ADDUPDATEMerkliste", Me.tfid, DateForSQL(Me.tfdatum), Me.tfInhalt, Me.tfBetriebID, 2

    Eigene Stored Procedures mit SP beginnen lassen, ist nicht gut. Diesen Präfix verwendet MSFT für die System SPs.

    Forms("frmBetrieb").Form.Requery Forms("frmBetrieb")("ufoBetriebAktull").Form.Requery DoCmd.Close acForm, Me.Name End If End Sub

    Fehler 3146
    Odbc-Aufruf ist fehlgeschlagen

    Du mußt an der Stelle die Fehlerauflistung durchlaufen und jeden Fehler anzeigen.

    Fehler:
            Dim i As Integer
            For i = 0 To Errors.count - 1
                    Call HandleError(Me.Name & ".btnSpeichern_Click()" & Errors(i))
            Next i
            Resume exit_btnSpeichern_Click
    End Sub

    Zusätzlich ist es sehr hilfreich auf dem Backend ein SQL Server
    Management Studio installiert zu haben, damit kannst Du auch debuggen.
    D.h. die SP mit den passenden Werten aufrufen und Step by Step
    durchgehen, dabei siehst Du die Fehler auch sehr gut.

    Servus
    Winfried


    Community Forums NNTP Bridge: http://communitybridge.codeplex.com/
    Access-FAQ: http://www.donkarl.com/AccessFAQ.htm Access-Stammtisch: http://www.access-muenchen.de


    Samstag, 29. Oktober 2016 11:10
  • Hallo

    erstmal Danke für die Antworten.

    Der Datentyp des Feldes ist datetime(2). Dieser Typ wird bei der Migration angelegt. In der Access-Tabelle vorher war er vom Typ datum. Ich habe den jetzt nicht auf datetime geändert. Wenn es natürlich besser ist, werde ich alle Datumstypen in den Tabellen ändern.

    SQL-Server legt folgenden Standardwert an:
    (CONVERT([datetime],CONVERT([varchar],getdate(),(1)),(1)))

    Die Eingabe Sql Server Managementstudio funktioniert ohne Fehler, das hatte ich schon probiert.

    Dies ist die Prozedur

    ALTER PROCEDURE [dbo].[Spa_addupdatemerkliste] @id        INT = 0,
                                                   @datum     DATETIME,
                                                   @inhalt    NVARCHAR(max),
                                                   @betriebid INT = 0,
                                                   @zuordnung INT=2
    AS
      BEGIN
          -- SET NOCOUNT ON added to prevent extra result sets from
          -- interfering with SELECT statements.
          SET NOCOUNT ON;
    
          IF EXISTS(SELECT *
                    FROM   tblAktull
                    WHERE  id = @id)
            BEGIN
                UPDATE tblAktull
                SET    datum = @datum,
                       inhalt = @inhalt,
                       betriebid = @betriebid,
                       zuordnung = @zuordnung
                WHERE  ID = @id
            END
          ELSE
            BEGIN
                INSERT INTO tblAktull
                            (datum,
                             inhalt,
                             betriebid,
                             zuordnung)
                VALUES      (@datum,
                             @inhalt,
                             @betriebid,
                             @zuordnung)
            END
      END 

    Beim Fehlerauslesen wird folgendes angezeigt

    Fehlernummer:       3146
    Fehlerbeschreibung: ODBC-Aufruf fehlgeschlagen.
      Fehler im Backend-System:
      Fehlernummer:       102
      Fehlerbeschreibung: [Microsoft][SQL Server Native Client 11.0][SQL Server]Falsche Syntax in der Nähe von '.2016'.
      Quelle:             ODBC.QueryDef
      Fehlernummer:       3146
      Fehlerbeschreibung: ODBC-Aufruf fehlgeschlagen.
     ...

    Und mit dieser Routine werden die Daten gespeichert bzw. geändert

    Public Sub SPAktion(strStoredProcedure As String, _
            ParamArray varParameter() As Variant)
        Dim db As DAO.Database
        Dim qdf As DAO.QueryDef
        Dim strParameter As String
        Set db = CurrentDb
        Set qdf = db.CreateQueryDef("")
        On Error GoTo Fehler
        strParameter = Param(varParameter)
        With qdf
            .Connect = conPTS
            .ReturnsRecords = False
            .SQL = "EXEC " & strStoredProcedure & " " & strParameter
            .Execute
        End With
        Set db = Nothing
    Ende:
        Exit Sub
    Fehler:
        Fehlerbehandlung "SPAktion", "FehlerAusloesen", Erl
        Resume Ende
    End Sub
    
    Public Function Param(ByVal varParameter As Variant) As String
        Dim strParameter As String
        Dim i As Integer
        For i = LBound(varParameter) To UBound(varParameter)
            Select Case VarType(varParameter(i))
                Case vbString
                    If varParameter(i) = "NULL" Then
                        strParameter = strParameter & ", " & varParameter(i)
                    Else
                        strParameter = strParameter & ", '" & varParameter(i) & "'"
                    End If
                Case 0, 1
                    strParameter = strParameter & ", NULL"
                Case Else
                    strParameter = strParameter & ", " & Replace(CStr(varParameter(i)), ",", ".")
            End Select
        Next i
        If Len(strParameter) > 0 Then
            strParameter = Mid(strParameter, 3)
        End If
        Param = strParameter
    End Function
    
    Private Sub cmdOK_Click()
        If Validierung = True Then
    
            SPAktion "dbo.spA_ADDUPDATEMerkliste", Me.tfid, trim(Me.tfdatum), Me.tfInhalt, Me.tfBetriebID, 2
    
            Forms("frmBetrieb").Form.Requery
            Forms("frmBetrieb")("ufoBetriebAktull").Form.Requery
    
            DoCmd.Close acForm, Me.Name
        End If
    End Sub
    Wenn ich auf das Datums-Formularfeld ein Datumsformat lege und das Datum über den Kalendar aufrufe, kommt o.g. Fehler. Gebe ich es manuell ein, wird korrekt gespeichert. Ich habe jetzt das Feld getrimmt und das funktioniert.

    @Winfried
    Ich habe mir das Buch Access und SQL Server gekauft, wo ja Bernd Jungbluth als Autor aufgeführt wird. Dort sind auch sehr viele Beispeildateien enthalten mit denen ich vorwiegend arbeite und die echt gut helfen. Ich werde die Geschäftlogik komplett ändern und Datenherkunft nur in ganz vereinzelten Fällen aus den Tabellen direkt holen. Im Buch wurde mehrmals und ausdrücklich auf Lese- und Schreibsperren des SQL Servers hingewiesen, was wohl sehr nervig sein kann. Ich kann das nicht beurteilen. Deshalb habe ich die Abfragen in gespeicherte Prozeduren ausgelagert.

    Liebe Grüße, die Luzie!


    • Bearbeitet Luzie Sonntag, 30. Oktober 2016 08:58
    Sonntag, 30. Oktober 2016 08:56
  • Am 30.10.2016 schrieb Luzie:

    Die Eingabe Sql Server Managementstudio funktioniert ohne Fehler, das hatte ich schon probiert.

    Nein, das war nicht was ich meinte. In einer neuen Abfrage schreibst
    Du den Namen deiner SP rein, dahinter von Komma getrennt die einzelnen
    Werte. Jetzt F5 drücken, schon siehst Du die Fehler sehr deutlich.

    Lass dir die Werte der Variablen in Access doch mal ausgeben.
    Debug.print deinAufruf und alle Variablen dazu. Das nimmst Du so wie
    es kommt und wirfst es im SQL Management Studio in eine neue Abfrage.
    Vermutlich fehlt beim Datumswert einfach der Fliegeschiss vorne und
    hinten. So interpretiere ich die Fehlermeldung.

      Fehlerbeschreibung: [Microsoft][SQL Server Native Client 11.0][SQL Server]Falsche Syntax in der Nähe von '.2016'.

            .SQL = "EXEC " & strStoredProcedure & " " & strParameter

    Diesen Teil mit Debug.Print ausgeben lassen, wie genau sieht das aus?

    Wenn ich auf das Datums-Formularfeld ein Datumsformat lege und das Datum über den Kalendar aufrufe, kommt o.g. Fehler. Gebe ich es manuell ein, wird korrekt gespeichert. Ich habe jetzt das Feld getrimmt und das funktioniert.

    Funktioniert jetzt alles?

    @Winfried
    Ich habe mir das Buch Access und SQL Server gekauft, wo ja Bernd Jungbluth als Autor aufgeführt wird. Dort sind auch sehr viele Beispeildateien enthalten mit denen ich vorwiegend arbeite und die echt gut helfen. Ich werde die Geschäftlogik komplett ändern und Datenherkunft nur in ganz vereinzelten Fällen aus den Tabellen direkt holen. Im Buch wurde mehrmals und ausdrücklich auf Lese- und Schreibsperren des SQL Servers hingewiesen, was wohl sehr nervig sein kann. Ich kann das nicht beurteilen. Deshalb habe ich die Abfragen in gespeicherte Prozeduren ausgelagert.

    Das ist ja soweit in Ordnung, bezüglich Schreibsperren mußt Du
    natürlich manuell in Aktion treten und etwas passendes einbauen.

    Servus
    Winfried


    Access-FAQ: http://www.donkarl.com/AccessFAQ.htm Access-Stammtisch: http://www.access-muenchen.de
    NNTP-Bridge für MS-Foren: http://communitybridge.codeplex.com/
    vbeTwister: http://www.vbetwister.com/

    • Als Antwort markiert Luzie Sonntag, 30. Oktober 2016 13:38
    Sonntag, 30. Oktober 2016 11:38
  • ok, jetzt weiß ich, wie Du es meinst.

    Es liegt an dem Fliegenschiss, davon und dahinter.

    Ohne Trim() werden keine Hochkomma gesetzt und das löst wohl den Fehler aus.

    EXEC dbo.spA_ADDUPDATEMerkliste 7, 01.01.2016, 'Hallo Welt', 1123, 2

    Ich habe jetzt die Function Parm() um eine Punkt erweitert.

    Case 7
                If varParameter(i) = "" Then
                    strParameter = strParameter & ", NULL"
                ElseIf varParameter(i) = "NULL" Then
                    strParameter = strParameter & ", NULL"
                ElseIf varParameter(i) = Null Then
                    strParameter = strParameter & ", NULL"
                ElseIf IsNull(varParameter(i)) Then
                    strParameter = strParameter & ", NULL"
                Else
                    strParameter = strParameter & ", '" & varParameter(i) & "'"
                End If
           
    Auf jeden Fall ist jetzt alles gut :)           
    Das ist ja soweit in Ordnung, bezüglich Schreibsperren mußt Du

    natürlich manuell in Aktion treten und etwas passendes einbauen.

    Also ein Teilprojekt ist jetzt fertig. Die Datenherkunft geht nur noch über ein Recordset mit Select auf eine SP bein Laden des Formulars. Jede Aktion muss mit einem Event ausgelöst werden, wie am Beispiel oben. Wenn eine Datenherkunft auf die Tabelle ausgelöst wird, dann nur ganz kurz z.B. beim Entern eines Kombinationsfeldes. Sperren habe ich jetzt noch keine gehabt. Meinst Du das mit "Manuell in Aktion treten"?

    Liebe Grüße, die Luzie!


    • Bearbeitet Luzie Sonntag, 30. Oktober 2016 13:37
    Sonntag, 30. Oktober 2016 13:36
  • Am 30.10.2016 schrieb Luzie:

    Auf jeden Fall ist jetzt alles gut :)           

    Na wunderbar. ;)

    Das ist ja soweit in Ordnung, bezüglich Schreibsperren mußt Du


    natürlich manuell in Aktion treten und etwas passendes einbauen.

    Also ein Teilprojekt ist jetzt fertig. Die Datenherkunft geht nur noch über ein Recordset mit Select auf eine SP bein Laden des Formulars. Jede Aktion muss mit einem Event ausgelöst werden, wie am Beispiel oben. Wenn eine Datenherkunft auf die Tabelle ausgelöst wird, dann nur ganz kurz z.B. beim Entern eines Kombinationsfeldes. Sperren habe ich jetzt noch keine gehabt. Meinst Du das mit "Manuell in Aktion treten"?

    Jepp, das meinte ich.

    Servus
    Winfried


    Access-FAQ: http://www.donkarl.com/AccessFAQ.htm Access-Stammtisch: http://www.access-muenchen.de
    NNTP-Bridge für MS-Foren: http://communitybridge.codeplex.com/
    vbeTwister: http://www.vbetwister.com/

    Sonntag, 30. Oktober 2016 18:27