Übersetzen ein Code VBA auf SQL

narutoverse

Benutzer
Beiträge
7
Hallo Zusammen,

Ich ahbe ein Probleme. und Zwar mein Chef möchte, dass wir unsere ganzen datenbank von Access auf MS SQl
Server migrieren. Jetzt haben wir einfach die Daten auf den SQL Server expotiert.
und festgestellt, dass die Datenbank zu langsam geworden sind.
Jetzt verlangt er von mir, dass ich die ganze Abfragen und Function, die auf VBA programmiert wurde , direkt Auf SQL sprache programiert.
Könnte mich veilleicht jemand helfen ?
Ich würde mich auf eine Rückmeldung sehr freuen
 
Werbung:
Ich mus eigentlich keine Function, die auf VBA programmiert sind, auf SQL programmieren
Beispiel:

Public Function SQL_FieldDiff() As String
'liefert den WHERE-Ausdruck für das Finden der Wertunterschiede
'muß auch NULL vs. NOT NULL auswerten
'Aufruf: Unterschiedliche Werte
Dim i%, s$
For i = 0 To UBound(arrComp1)
s = s & "(Nz(T1.[" & Trim$(arrComp1(i)) & "],0) <> " & "Nz(T2.[" & Trim$(arrComp2(i)) & "],0)) OR "
Next i
SQL_FieldDiff = Left$(s, Len(s) - 4)
End Function
 
Wenn ich verstehen würde was VBA da tut könnte ich es vermutlich in SQL ausdrücken.

Vieles davon gibt es ja auch in MSSQL: ltrim(), rtrim() (nein, trim() gibt es nicht), <>, OR, left(), len(), NULL, NOT NULL, etc.
 
Hi,
ich kann Andreas da nur Recht geben! Access auf SQL-Server umstellen ist unter Umständen nicht ganz trivial, insbesondere wenn mehrfach Datenbank-Spezifische Aufgaben in VBA gelöst wurden.
Dann erledigen sich auch diverse Performance-Probleme. Je nach Komplexität und Umfang des Access-Projektes ist das auch nicht immer innerhalb von einer Woche "mal eben" gelöst.

Sucht euch einen versierten Freelancer bei euch im Kreis (über Gulp oder freelancermap.de), der das schon mal gemacht hat und sich insbesondere auch mit SQL Server auskennt.
Das ist meist preiswerter als ein Systemhaus darauf anzusetzen, auch wenn man mit einem Stundensatz von 55,-€ bis 65,-€ rechnen muss (bei echt guten Leuten auch mehr!).

Viele Grüße,
Tommi
 
Danke für den Vorschlag!!!
Aber mein Chef meint, dass wir es nicht leisten können. Und dass ich versuchen sollte, es selber zu lösen.
und jetzt versuche ich eine FUNCTION zu übersetzen. Aber ich weiße nicht, wie man "ADODB.Recordset." in SQL Sprache verwendet.
Könnte jemand mich zufällig da helfen ?
 
Es gibt kein Equivalent von ADODB.Recordset innerhalb einer Datenbank... Denn du musst nicht an eine Datenbank SENDEN... Du befindest dich bereits IN einer Datenbank...

Wenn du nichteinmal weißt was ein ADODB.Recordset ist und was es macht... Lass es lieber gleich bleiben und such dir jemand geschulten... Tu dir und deiner Firma einen gefallen...
 
Danke für die Antwort,
Ich weiße allgemein, was eine ADODB.Recordset in VBA macht. Aber ich dachte schon, es viellecht ein Equivalent oder was ähnliches:

Code:
Function concRefKat2(IDTXSSystem As Integer, IDTXSRefKat1 As Integer)
  Dim rs As New ADODB.Recordset
  Dim sqlString As String
  Dim concString As String
  Dim currentString As String
  Dim FirstEntry As Boolean
  sqlString = "SELECT tblTXSSystem.IDTXSSystem, tblTXSSystemToTXSRefKat.IDTXSRefKat1, tblTXSSystemToTXSRefKat.IDTXSRefKat2, tblTXSRefKat2.txtEN, tblTXSSystemToTXSRefKat.txtTXSRefKat2NoteEN " & _
  "FROM (tblTXSSystem INNER JOIN tblTXSSystemToTXSRefKat ON tblTXSSystem.IDTXSSystem = tblTXSSystemToTXSRefKat.IDTXSSystem) INNER JOIN tblTXSRefKat2 ON tblTXSSystemToTXSRefKat.IDTXSRefKat2 = tblTXSRefKat2.IDTXSRefKat2 " & _
  "WHERE tblTXSSystem.IDTXSSystem = " & IDTXSSystem & " AND tblTXSSystemToTXSRefKat.IDTXSRefKat1 = " & IDTXSRefKat1 & ";"
  rs.Open sqlString, CurrentProject.Connection, adOpenKeyset, adLockOptimistic
  If (rs.EOF = False) Then
  rs.MoveFirst
  concString = ""
  FirstEntry = True
  Else
  concString = ""
  concRefKat2 = concString
  Exit Function
  End If
  Do Until (rs.EOF = True)
  If rs![txtTXSRefKat2NoteEN] <> "" Then
  currentString = rs![txtEN] & " (Note: " & rs![txtTXSRefKat2NoteEN] & ")"
  Else
  currentString = rs![txtEN]
  End If
  If FirstEntry Then
  concString = currentString
  FirstEntry = False
  Else
  concString = concString & "; " & currentString
  End If
  rs.MoveNext
  Loop
  concRefKat2 = concString
  rs.Close
End Function
 
Zuletzt bearbeitet von einem Moderator:
(Oracle-Syntax... Weiß nicht wie man in T-SQL eine Konkatenierung via Aggregation macht...)
Code:
Select listagg(txs_ref_kat.txten || Case
                  When txs_ref.txttxsrefkat2noteen Is Not Null Then
                   '(Note: ' || txs_ref.txttxsrefkat2noteen || ')'
                  Else
                   ''
               End, '; ') within Group(Order By txs_ref_kat.txten)
From   tbltxssystem txs_sys

Inner  Join tbltxssystemtotxsrefkat xs_ref
On     xs_ref.idtxssystem = txs_sys.idtxssystem

Inner  Join tbltxsrefkat2 txs_ref_kat
On     txs_ref_kat.idtxsrefkat2 = txs_ref.idtxsrefkat2

Where  txs_sys.idtxssystem = &id_txs_system
And    txs_ref.idtxsrefkat1 = &id_txs_ref_kat_1

Btw.... Was willst du jetzt damit?
Musst du das nicht irgendwie an deinen Client zurückgeben? Oder verpass ich hier gerade etwas....?
 
Also, ich sollte Abfragen, die in Access programiert wurde, in MS SQl Server nprogrmieren.
und in manche Abfragen wurde ein paar function aufgerufen wie zum beispiel "
concRefKat2".
So sieht die Abfrage aus :
Code:
SELECT DISTINCT tblTXSSystem.IDTXSSystem, tblTXSSystemToTXSRefKat.IDTXSRefKat1, concRefKat2([tblTXSSystem.IDTXSSystem],[IDTXSRefKat1]) AS Subcategories
FROM tblTXSSystem
INNER JOIN tblTXSSystemToTXSRefKat
ON tblTXSSystem.IDTXSSystem=tblTXSSystemToTXSRefKat.IDTXSSystem
WHERE (((tblTXSSystemToTXSRefKat.IDTXSRefKat1)=1));
 
Zuletzt bearbeitet von einem Moderator:
Ich betone hier nocheinmal:
- Das ist Oracle-Syntax.
- Das macht eigentlich keinen Sinn... Weil man Code von OOP in der Regel nicht 1:1 in SQL übertragen kann. Die Basis ist eine ganz andere...

Aber bitte: (als kleine Anmerkung, ich bin furchtbar schlecht im dokumentieren und kommenteren...)
Code:
Select listagg(txs_ref_kat.txten || Case
-- Hier verwende ich einfach eine Aggregation, die quasi deine While-Schleife ersetzt
-- Innerhalb dieser Aggregation verwende ich noch ein Case, damit das "(Note: xxx)" auch wirklich nur dann dazu geschrieben wird, wenn es einen Wert gibt.
-- Dasheißt ich konkateniere den Wert von   txten  mit txttxsrefkat2noteen (mit diesem "(Note: xxx)" wenn es einen wird für txttxsrefkat2noteen gibt)
                  When txs_ref.txttxsrefkat2noteen Is Not Null Then
                   '(Note: ' || txs_ref.txttxsrefkat2noteen || ')'
                  Else
                   ''
               End, '; ') within Group(Order By txs_ref_kat.txten)
-- da es vorkommen kann, dass es mehrere verschiedene txten-Werte gibt (somit dann auch mehrere Zeilen ausgegeben werden) eben hier nocheinmal diese Aggregation "listagg"

-- Damit konkateniere ich die einzelnen Zeilen, das sieht ungefähr so aus:  Zeile1 + '; ' + Zeile2 + '; ' + Zeile3... (usw. für alle Zeilen)
-- Wobei die Zeilen nach txten aufsteigend sortiert sind


-- Die From-Clause ist eigentlich die selbe geblieben. Ich habe Sie nur nach meinen Vorstellungen "aufgehübscht"
-- Ich habe auch ein paar Aliase hinzugefügt, damit es etwas übersichtlicher aussieht
From   tbltxssystem txs_sys

Inner  Join tbltxssystemtotxsrefkat xs_ref
On     xs_ref.idtxssystem = txs_sys.idtxssystem

Inner  Join tbltxsrefkat2 txs_ref_kat
On     txs_ref_kat.idtxsrefkat2 = txs_ref.idtxsrefkat2

-- Der einzige Unterschied hier wären die Variablen die ich hier verwende.
-- Eigentlich sollten es auch Bind-Variablen sein - was ich hier unten nocheinmal angepasst habe
Where  txs_sys.idtxssystem = :id_txs_system
And    txs_ref.idtxsrefkat1 = :id_txs_ref_kat_1
 
Dankeschon Distrilec,

ich habe mite dein Code versucht, ein Funktion zu bastelt.
Aber, bei listagg gibt es ein fehlermeldung( listagg ist kein bekannter Name ein Integrierten Function )
" |" falscher syntax
bei ODERBY gist es auch ein fehler meldung
Kann ich überhaupt so ein function erstellen ?


Code:
CREATE FUNCTION  concRefKat2(@IDTXSSystem INT, @IDTXSRefKat1 INT)
  RETURNS VARCHAR
AS
BEGIN
  SELECT" listagg"(txs_ref_kat.txten || Case
  When txtTXSRefKat2NoteEN Is Not Null Then
  '(Note: ' || txtTXSRefKat2NoteEN || ')'
  Else
  ''
  End, '; ') within Group(Order By txs_ref_kat.txten)
From  tblTXSSystem
Inner  Join tblTXSSystemToTXSRefKat
On  tblTXSSystem.IDTXSSystem = tblTXSSystemToTXSRefKat.IDTXSSystem

INNER JOIN tblTXSRefKat2
ON tblTXSSystemToTXSRefKat.IDTXSRefKat2 = tblTXSRefKat2.IDTXSRefKat2

WHERE tblTXSSystem.IDTXSSystem =  & IDTXSSystem
AND tblTXSSystemToTXSRefKat.IDTXSRefKat1 =  & IDTXSRefKat1

RETURN concRefKat2;
END
 
Zuletzt bearbeitet von einem Moderator:
Ich sagte ja... Lass es bleiben wenn du Null-Ahnung von SQL / besonders T-SQL hast... :)
1. Das kann so nicht funktionieren. Deine Syntax ist falsch... Total falsch...
2. Ich habe mehrfrach darauf hingewiesen das es sich um Oracle-Syntax handelt und nicht T-SQL

Entweder suchst du dir erstmal ein paar Online-Hilfen und lernst dein System kennen, oder du machst es gleich richtig und besuchst eine professionelle Schulung... Dieses Forum wird dir bestimmt nicht dabei helfen deine kompletten Funktionen umzuschreiben (davon abgesehen das einige davon wahrscheinlich nichteinmal mehr gebraucht werden und anders gelöst werden können...)
 
Werbung:
Hi narutoverse,

am string aus posting 8 "Currentproject.connection" lässt sich erkenn, dass die bisheriege migration 'nur' via accessproject lief.
Kann manmachen aber da kommen wahrscheinlich die performance einbusen her.
Zwei gründe:
Wenn die Tabellen übermässig viele Spalten haben, dann überschreiten sie eventuell das, was man unter microsoft mit 'Seite' beschreibt.
Es geht dabei darum wie die daten auf der platte von Windows gespeichert werden, nicht nur die daten die du selbst in die Tabellen schreibts, sondern dei daten dei, die Tabelle beschreiben(metadaten).
Wie man das prüfen kann wusste ich auch mal, aber ist zu lang her(auf einer 'Seite' können so und so viel byte gespeichert werden. Jeder Datentyp einer splate verbracuht x-byte(so meine graue erinnerung))
2. Bei dieser art der migration werden nicht unbedingt die best möglichen datentyppen für die jeweiligen spalten gewählt, weil access nun mal nicht alle typen eines mssql servers kennt.

Mein Ansatz wäre also: mach dir eine tabelle mit allen datentypn die es auf dem server gibt. von dieser kannst du dir den string im abfragefenster ausgeben lassen, mit zwei clicks, diesen string nimmst du nun als vorlage für alle anderen und kannst eben so die entsprechenden datentypen auswählen.

Was den VBA code angeht, zwingend wäre jetzt nur eine Änderung des connectionstring und auch die Verwendung von "currentproject.connection" wird dann natürlich nicht mher gehen.

Dein chef hat sich wahrscheinlich beeindrucken lassen vom hören sagen: "stored prozedures", damit wird immer schnell um sich geworfen.
Das würde deiner performance nur dann merklich ins gewicht fallen, wenn auf dem server daten aus einer tabelle gefrimelrt werden müssen und diese vorrübergehend zwischengespeichert werden müssen, (weil sie nun nochmal ausgwerten werden müssen). In dem fall würden sie nicht übers netzt an access gesendet.

Also kurz um, ich seh nicht, dass du deinen ganzen vba code umschreiben musst.
Hier ausserdem eine seite die sowit ich seehen kann alle unterschiede listet zwischen T-sql vs. access sql
 
Zurück
Oben