Autor Beitrag
reimo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75



BeitragVerfasst: Mi 08.08.07 11:04 
Hi!

Habe folgendes Problem! Möchte für meine Datenbank ein UpdateTool schreiben! dieses liest aus einem Verzeichnis alle vorhandenen UpdateScripts ein und führt diese aus!

mein problem ist jetzt folgendes! da die scripts derzeit für das "osql - tool" geschrieben wurden, wird auch zum beenden eines Batch innerhalb eines scripts der MSSQL - Befehl "GO" verwendet, welches kein SQL Befehl ist! wenn ich jetzt ein script einlese und dieses ausführe, bekomm ich natürlich vom ODBC Treiber einen Syntax fehler!

Das GO verwend ich deshalb innerhalb eines Scripts:

ALTER TABLE Tabelle1 ADD Col5
GO // --- schreibt alle befehle sicher in die DB
UPDATE Tabelle1 SET Col5 = 3 // dadurch kann ich auf die COl5 im gleichen script zugreifen

Fehler!! :

ALTER TABLE Tabelle1 ADD Col5
-- GO
UPDATE Tabelle1 SET Col5 = 3

So, und hier ist ja auch schon mein Problem! wenn ich innerhalb eines scripts auf die (wie im beispiel ohne GO) Col5 etwas schreiben will, geht das natürlich nicht, da diese in einer transaction mit dem erstellen dieser column liegt!
Es funktioniert aber auch nicht, wenn ich beide befehle in unterschiedliche transaktionen unterteile:

BEGIN TRANSACTION
ALTER TABLE Tabelle1 ADD Col5
END

BEGIN TRANSACTION
UPDATE Tabelle1 SET Col5 = 3
END

Wie kann ich den SQL Server dazu zwingen, dass er zuerst die Col5 erstellen soll??? Ohne, dass ich den GO - Befehl verwende ??? was für einen befehl kann ich dazu verwenden?
gibt es da eine möglichkeit?

Sollte am besten standard SQL sein, da ich das Update sowohl für einen MSSQL server alsauch für Postgres verwenden möchte!

vielen dank!
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Mi 08.08.07 11:12 
Schonmal mit Commit probiert?
Amiga-Fan
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 534



BeitragVerfasst: Mi 08.08.07 11:21 
im sqlserver management studio kann man unter Optionen/Abfrageausführung das Batchtrennzeichen einstellen, das normalerweise GO heißt

_________________
- Leg dich nie mit einem Berufsprogrammierer an
- Wahre Profis akzeptieren keine einfachen Lösungen
reimo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75



BeitragVerfasst: Mi 08.08.07 13:53 
user profile iconjasocul hat folgendes geschrieben:
Schonmal mit Commit probiert?


ja, geht leider nicht! das wäre ja das, was meiner meinung nach funktionieren müsste! geht aber nicht!
reimo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75



BeitragVerfasst: Mi 08.08.07 14:09 
user profile iconAmiga-Fan hat folgendes geschrieben:
im sqlserver management studio kann man unter Optionen/Abfrageausführung das Batchtrennzeichen einstellen, das normalerweise GO heißt


ja, das kann schon sein! nur dieses Batch-trennzeichen ist nur für die MSSQL-Clients (osql und ähnliche) gedacht! es ist kein SQL-Konformer Befehl! es wird nichtmal zum SQL-Server abgeschickt, sondern nur vom Client dementsprechent umgewandelt!
Wenns GO als SQL Befehl zum server abschickst bekommst genauso eine Fehlermeldung!

jetzt brauch ich aber einen SQL (oder SQL Server) Befehl, der genau das gleiche, wie GO bewirkt!
Normalerweise würd ich damit rechnen, dass COMMMIT die bewirkt ( BEGIN TRANSACTION .... COMMIT ), tut dies aber nicht
also

Create Spalte
Commit // <- an dieser Stelle sollte doch die Spalte in die DB geschrieben werden
Spalte Wert zuweisen // <- funktioniert aber nicht, da anscheinend Spalte do noch nicht vorhanden!

Wird das Commit durch GO ersetzt funktioniert aber alles problemlos
(das beispiel bezieht sich auf ein durch OSQL gestartetes script)

Da ich aber von meiner aplikation aus die SQL-Befehle Starte, darf ich GO ja nicht verwenden...wie soll ichs dann machen??
ungefährer programmablauf:

Query.SQL.LoadFromFile(updatefile.sql)
Query.ExecSQL
Query.Close
Query.Free

Wenn ich aber das erzeugen der tabelle in 2 schritten machen würde, dann funktionierts

//zuerst erzeugen
Query.SQL.Add( 'create Spalte' )
Query.ExecSQL
Query.Close

//dann zuweisen
Query.SQL.Add( 'Spalte wert zuweisen' )
Query.ExecSQL
Query.Close


???? hab schon alles mögliche ausprobiert! keine ahnung mehr!
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Mi 08.08.07 14:26 
Ich bin mir jetzt nicht ganz sicher, aber ich mein, dass Batch-Verarbeitung mit einem normalem TQuery nicht möglich ist. Allerdings müsstest Du dann auch eine Fehlermeldung bekommen, denke ich. Vielleicht musst Du das wirklich in mehrere Schritte splitten. Hätte auch den Vorteil, dass Du relativ einfach eine Fortschrittsanzeige einbauen kannst. :wink:

Da ich überwiegend mit Oracle arbeite, benutze ich andere Komponenten. Dort gibt es extra eine, die für die Batch-Verarbeitung genutzt werden kann. Standard-Trennzeichen ist dort ein ";".
reimo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75



BeitragVerfasst: Mi 08.08.07 14:39 
wie soll ich soetwas dann lösen?
hab eine sammlung von updates als script vorliegen! jetzt möcht ich aber eine eigene aplikation schreiben, welche die DB auf den neuesten stand bringt und als quelle wollt ich diese scripts nehmen!

natürlich könnt ich zusätzlich nochmal im code hardcodiert die befehle eintippen, aber dann hätt ichs 2x gemacht! einmal im code und ein mal im script, was fürn a.... ist!

ich könnte auch die scripts zeile für ziele rauslesen und zeilenweise verschicken! wenn ich ein trennzeichen in die scripts einbau, weiss ich, wo ein befehl endet!
und zusätzlich schau ich nach "GO"...an dieser stelle könnt ich das Query schliessen und wieder öffnen!
Das ist aber so umständlich!

habt ihr irgendwelche vorschläge, wie ich so ein update handeln könnte??
reimo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75



BeitragVerfasst: Mi 08.08.07 14:51 
Nachtrag: Die Batch-Verarbeitung funktioniert mit TQuery eigentlich ganz gut, bis auf meine schwierrigkeiten
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Mi 08.08.07 15:20 
user profile iconreimo hat folgendes geschrieben:
ich könnte auch die scripts zeile für ziele rauslesen und zeilenweise verschicken! wenn ich ein trennzeichen in die scripts einbau, weiss ich, wo ein befehl endet!
und zusätzlich schau ich nach "GO"...an dieser stelle könnt ich das Query schliessen und wieder öffnen!
Das ist aber so umständlich!
Also bevor es gar nicht funktioniert, würde ich es so machen. Aber statt jede Zeile einzulesen, kannst Du auch eine TStringList verwenden und das dann Stückweise in die Query einbauen.

Aber vielleicht weiß es ja noch jemand besser als ich.

Übrigens noch eine Frage: Da Du TQuery verwendest, würde mich noch interessieren, wie Du auf die DB kommst. Du benutzt doch wohl nicht die BDE? Ansonsten schaue nochmal alle ODBC-Einstellungen durch. Evtl. ist da noch irgendwas, was Dir in die Suppe spuckt (habe schon jahrelang kein ODBC mehr gemacht).
reimo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75



BeitragVerfasst: Mi 08.08.07 16:15 
danke, dann bleibt mir wohl nix anderes, als es pro zeile zu machen!

ja, verwende leider die BDE! verwend leider Delphi 4 Prof und da gibt es ja nicht so viele alternativen
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Mi 08.08.07 16:21 
Dann schau Dir bei den BDE-Einstellungen auch noch mal die Einstellungen für SQLQUERYMODE und SQLPASSTHRU MODE an. Evtl. gibt es damit noch Probleme.

(BDE :roll: ) Aber wenn es nicht anders geht...
reimo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75



BeitragVerfasst: Do 09.08.07 10:54 
user profile iconjasocul hat folgendes geschrieben:
Dann schau Dir bei den BDE-Einstellungen auch noch mal die Einstellungen für SQLQUERYMODE und SQLPASSTHRU MODE an. Evtl. gibt es damit noch Probleme.

(BDE :roll: ) Aber wenn es nicht anders geht...


Wo kann ich die einstellungen für die von die erwähnten modi vornehmen?

Habs jetzt so gelöst, dass ich das Scriptfile einlese, dieses dann zeile für zeile in eine eigene Stringliste kopier! dabei überprüf ich die zeilen auf die Commit-schlüsselwörter! wird eines erkannt, so commit ich die DB manuell und mach anschliessend im Scriptfile weiter!
Funktioniert ganz gut bis jetzt!
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Do 09.08.07 11:08 
user profile iconreimo hat folgendes geschrieben:
Wo kann ich die einstellungen für die von die erwähnten modi vornehmen?
In der Systemsteuerung sollte es "BDE-Verwaltung" geben. Bei den Treibern für MSSQL sollten die Parameter einstellbar sein.

user profile iconreimo hat folgendes geschrieben:
dieses dann zeile für zeile in eine eigene Stringliste kopier!
TStringList kennt auch LoadFromFile. Du musst also nicht zeilenweise einlesen.
reimo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75



BeitragVerfasst: Do 09.08.07 14:50 
user profile iconjasocul hat folgendes geschrieben:
user profile iconreimo hat folgendes geschrieben:
Wo kann ich die einstellungen für die von die erwähnten modi vornehmen?
In der Systemsteuerung sollte es "BDE-Verwaltung" geben. Bei den Treibern für MSSQL sollten die Parameter einstellbar sein.

user profile iconreimo hat folgendes geschrieben:
dieses dann zeile für zeile in eine eigene Stringliste kopier!
TStringList kennt auch LoadFromFile. Du musst also nicht zeilenweise einlesen.


Ja, ich weiss! Ich lese es ja auch in einem ausm File, dann geh ich die ausgelesenen Zeilen aber in der Liste durch, also:
for i.... do liste.string[i]

diese zeile überpüf ich dann halt mit Pos() auf die Commit strings. diese werden aus der liste entfernt und an deren stelle ein manuelles commit durchgeführt!

mal zur gesamten funktionsweise, falls es wen interessiert! Vielleicht hat ja jemand bessere ideen:
Das ganze soll so aussehen, dass ein exe file ausgeliefert wird und ein gepackter ordner (das nächste Problem *gg*)
Dieser gapackte ordner enthält die einzelnen updatescripts und ein file, welches die checksummen aller Scriptfiles enthält (wieder ein problem...hehe)!
Beim starten der Exe wird der ordner in einen Temp-ordner entpackt (Problem?), es werden die scriptfiles eingelesen, deren checksumme berechnet und mit der checksumme im ausgelieferten file vergliechen.
Erst dann kann ein Datenbank update gestartet werden!

Dadurch hab ich den vorteil, dass ich die scripts nur einmal vorliegen hab (sowohl beim entwickeln alsauch zum ausliefern), und diese werden dann zum ausliefern einfach mittels einer eigenen kleinen applikation aufbereitet ( = Checksummen berechnen + diese in ein file schreiben + gesamten ordner komprimieren)

So, jetzt brauch ich nur noch einen alg. zum checksummen berechnen!
und die möglichkeit dateien und ordner von der applikation aus zu komprimieren ( zip, rar,... )