Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!

Mobiles Hauptmenü

Datenaktualisierung scheitert

Begonnen von Mokkie, Mai 16, 2025, 11:13:37

⏪ vorheriges - nächstes ⏩

Mokkie

#15


Sorry, das war jetzt doppeltHallo markusxy,

ZitatZitat von: Bitsqueezer am Mai 16, 2025, 12:50:29
Generell gilt: Diese Vorgehensweise bei Verwendung von "Execute" mit Dynamic SQL hat in jedem Fall den Nachteil, daß es für SQL Injection anfällig ist

Ist das so gemeint, dass ich eine StoreProcedur auf dem SQL Server ausführen sollte und dieser dann eben die entsprechenden Paramter übergeben sollte?

Mokkie

Hallo Markusxy,

ZitatZitat von: Bitsqueezer am Mai 16, 2025, 12:50:29
Generell gilt: Diese Vorgehensweise bei Verwendung von "Execute" mit Dynamic SQL hat in jedem Fall den Nachteil, daß es für SQL Injection anfällig ist

Ist das so gemeint, dass ich das über eine StoredProcedur auf dem SQL server und in Access nur die entsprechenden Paramter an diese übergeben sollte?

Das ist aber eine Menge Arbeit...  ::)
Und es ist eben komisch, das es mal super klappt und dann wieder kommt dieser Fehler.

Ich kenne mich mit dem Acitivity Monitor nicht so gut aus.
Beim Ausführen der Abfrage, und wenn diese hängen bleibt bekomme ich für Abfrae folgende Auswertung:
Logical Read = 3
Elapsed Time = 23070

was sagt mir das? Logical Read ist bei anderen Abfragen höher....


Bitsqueezer

Hallo,

eine Stored Procedure ist auf jeden Fall die sicherste und performanteste Methode, insbesondere bei Änderung von vielen Datensätzen, weil alles auf dem Server stattfindet.

Du kannst hier jeden Parameter vor der Verwendung in jedweder Form überprüfen, Daten in z.B. mehreren Tabellen ändern usw.
Sicherheitstechnisch kann die Stored Procedure (deren Ausführung) an Rechte gebunden werden und per "EXECUTE AS" kann man der SP selbst höhere Rechte geben, als der User hat, der sie ausführt. Somit kann die SP dann z.B. auf Systemabfragen zugreifen, die der User selbst vielleicht nicht abrufen kann, oder Tabellen ändern, die der User direkt nicht ändern kann oder der die Tabelle gar nicht zu sehen bekommt.
Außerdem kannst Du umfangreiche Rückgaben in der SP zur Verfügung stellen, vom Return-Code (immer ein int) bis zu komplexen Abfragen, oder auch OUTPUT-Parameter.
Mit Access kann das alles per ADO abgefragt/ausgeführt werden.

Eine SP zur Datenänderung würde ich aber nicht für jede kleine Tabellenänderung machen, sonst hast Du am Ende einen großen Verwaltungsaufwand. Eine SP empfiehlt sich, wenn es um komplexere Parameter/Tabellenzusammenhänge/Rechte usw. geht.
Allerdings zum Thema SQL Injection: Hier gilt natürlich das gleiche in Sachen Sicherheit: Wenn Du einen Dynamic SQL String in der SP zusammensetzt und mit EXECUTE ausführst, hast Du das gleiche Problem, als ob Du einen SQL-String in VBA zusammensetzt. Also auch hier aufpassen und wenn es geht, Dynamic SQL besser vermeiden.

Gruß

Christian

Bitsqueezer

Hallo,

das besagt, daß die Abfrage 23 Sekunden gebraucht hat (sind immer Millisekunden). Was schon relativ lange ist. Logical Reads:
Hier eine Liste, was die Angaben bedeuten:
https://knowledgebase.apexsql.com/how-to-use-and-interpret-the-sql-server-activity-monitor/

Ich würde erst mal im SQL Profiler schauen bzw. XEvents, was da eigentlich genau passiert.
Aber auch der Activity Monitor sollte Dir schon Angaben zeigen, wo z.B. sich Prozesse blockieren.

Gruß

Christian

Knobbi38


Mokkie

Hallo knobbie38,

oh je, dann muss ich das auch noch mal prüfen, Danke

Mokkie

#21
Hallo Christian,

ZitatEine SP zur Datenänderung würde ich aber nicht für jede kleine Tabellenänderung machen, so

ok, deswegen meine Anmerkung, dass es manchmal nur ein Feld ist, was eben geändert wird. und da hängt es dann, aber eben auch nicht immer :'(

ZitatDu einen SQL-String in VBA zusammensetzt. Also auch hier aufpassen und wenn es geht, Dynamic SQL besser vermeiden.
Ursprünglich hatte das Formular die Tabelle(VOMPANY) als Recordsource. Die Tabelle lässt sich auch öffnen und nachdem ich dieses Constraint(Spalte:Memo) entfernt hatte, auch bearbeiten, wenn man jetzt als Bsp. einfach dieses Memo Fel nimmt.
Der Fehler der dann eben manchmal, nicht immer, auftrat unterscheidet sich nicht zu dem Fehler der nun geworfen wird. Immer Abfragetime .


Mokkie

Hallo Christian,

ZitatIch würde erst mal im SQL Profiler schauen bzw. XEvents, was da eigentlich genau passiert.
Aber auch der Activity Monitor sollte Dir schon Angaben zeigen, wo z.B. sich Prozesse blockieren.

Danke, ich werde mich da jetzt dran machen.
ich melde mich wieder, vielen Dank

markusxy

Zitat von: Mokkie am Mai 21, 2025, 11:59:19Ist das so gemeint, dass ich das über eine StoredProcedur auf dem SQL server und in Access nur die entsprechenden Paramter an diese übergeben sollte?

Nein, bezüglich SQL Injection hat dynamic SQL keinen Nachteil, es sei denn man macht es so wie gezeigt.
Persönlich verwende ich zu 90% dynamic SQL und zu 10% Prozeduren. Aber ich verwende wie bereits erwähnt auch bei dynamic SQL das Parameter Objekt. Ich käme nie auf die Idee den per UI übergebenen Wert per String Operation zu übergeben. Ich entwickle zwar schon seit Jahren nichts neues mit VBA aber auch bei ADO.Net gilt das selbe Prinzip - nur gibts weit mehr Möglichkeiten.
Grundsätzlich solltest du dich mehr mit der Dokumentation beschäftigen, damit du zumindest die Möglichkeiten und Parameter kennst um dann von Fall zu Fall zu entscheiden, was du nehmen willst. Christian hat da ja schon einige wertvolle Hinweise gegeben. Vor allem muss man sich in einer Multi User Umgebung immer fragen, wie man gleichzeitige Zugriffe handelt.

Mokkie

Hallo markus xy,

ich habe mich am Wochenende eingelesen und das alles geändert auf:

Dim conn As ADODB.Connection
Dim cmd As ADODB.Command
Dim lActId As Long
Dim sCUmsatz As Variant ' Variant erlaubt auch Nullwerte

On Error GoTo errormessage

' Werte aus Formular lesen
lActId = Nz(Forms![Hotline -> Terminallist]!COMPANY_ID, 0)
sCUmsatz = Me.COMPANY_DoUmsStat

' Überprüfen
If IsNull(sCUmsatz) Then
    sCUmsatz = 0 ' Falls Null, dann False (0)
ElseIf sCUmsatz = True Then
    sCUmsatz = 1 ' Falls True, dann 1
Else
    sCUmsatz = 0 ' Falls False oder anderweitig, dann 0
End If

' Verbindung aufbauen
Set conn = New ADODB.Connection
With conn
    .ConnectionString = "Provider=MSOLEDBSQL;Server=AFC-MSSQL2016V;Database=FENG;Trusted_Connection=yes;"
    .Open
End With

' Kommando vorbereiten
Set cmd = New ADODB.Command
With cmd
    .ActiveConnection = conn
    .CommandType = adCmdText
    .CommandTimeout = 60 ' Timeout in Sekunden

    ' SQL mit Parametern
    .CommandText = "UPDATE data.COMPANY SET COMPANY_DoUmsStat = ? WHERE COMPANY_ID = ?"

    ' Parameter hinzufügen
    .Parameters.Append .CreateParameter("COMPANY_DoUmsStat", adBoolean, adParamInput, , sCUmsatz)
    .Parameters.Append .CreateParameter("COMPANY_ID", adInteger, adParamInput, , lActId)

    ' Ausführen
    .Execute
End With

' Aufräumen
conn.Close
Set cmd = Nothing
Set conn = Nothing

der Fehler ist immer noch. Ich habe hier auch extra noch mal auf diese ollen Bit Felder egprüft, da ich erfahren habe, dass das wohl oft ein Problem ist.
Auf allen diesen Felder liegt aber ein Contraint :

ALTER TABLE [data].[COMPANY] ADD  CONSTRAINT [DF__COMPANY__COMPANY__57F47C82]  DEFAULT ((0)) FOR [COMPANY_isINSO]
Die OBDC Verbindung habe ich auch angepasst.

Ich schaue nun wieder serverseitig :-(


Mokkie

Hallo knobbie38,

ich habe die ODBC verknüfung nun korrigiert,
danke für den Hinweis.