wir beabsichtigen, eine Software von der Anbindung vom MS-Sql-Server auf PG umzustellen. Was kann denn an möglichen Problemen auf uns zukommen?
Die Software ist in C# geschrieben und verwendet die “SqlConnection” als Zugriffklasse. Es gibt einen kompletten Datenbankgenerator, welcher aus einer XML-Datei heraus die Datenbank erstellen und mit Inhalt vorbefüllen kann. Hier werden also alle Varianten von “Alter Table”, “Alter Column”, “Add Column” etc. benötigt. Im Code selber wird hie und da mit direkten SQL-Befehlen gearbeitet, üblicherweise simple Sachen der Art “Update xxx SET FieldA=0 WHERE FieldA=null” o.ä. Ansonsten werden Daten via der üblichen Konstruktion über ein DataSet/DataAdapter geladen und geschrieben und gelöscht.
Aus meiner Erfahrung stolpern die meisten bei einer Umstellung von SQL Server zu Postgres darüber, dass String Vergleiche standardmäßig Groß/Kleinschreibung beachten. 'Bla' ist also nicht gleich 'bla'
Anders als praktisch alle anderen relationalen Datenbanksysteme unterscheidet SQL Server nicht zwischen der Abfragesprache und der prozeduralen Sprache. Schleifen, IF Abfragen oder Variablen gibt es nur in prozeduralen Sprachen. In Postgres ist das üblicherweise PL/pgSQL.
Postgres hält sich stärker an den SQL Standard und verwendet demnach doppelte Anführungszeichen " anstatt der unsäglichen eckigen Klammern [] (die in SQL und bei Postgres für den Zugriff auf Array Elemente vorgesehen sind).
Das Transaktionshandling ist unterschiedlich. In einer Standardinstallation von SQL Server blockieren sich lesende und schreibende Zugriffe gegenseitig (was häufig mit der Holzhammermethode “with nolock” umgangen wird in SQL Server).
“Rechnen” mit Timestamp oder Date Werten geht völlig anders (z.B. - anstatt datediff())
Index-Strategien sind unterschiedlich. Postgres hat z.B. keinen “clustered index” (und ich stimme hier Markus Winand zu, dass diese als Primäschlüssel nicht wirklich eine bessere Wahl darstellen).
danke für deine Antwort. Das klingt ja bis hierhin gar nicht übel. Wir haben bisher die Datenbank nur als Datenspeicher verwendet und uns von solchen Dingen wie Trigger, gespeicherten Prozeduren etc. ferngehalten. Das erledigen wir alles im Code, da wir früher schon mal Oracle parallel unterstützt hatten. Das bedeutet, solchen Sachen wir “Rechnen mit timestamp”, JSON etc. fallen bei uns schon mal weg. Der String-Vergleich freilich wird spannend.
Gibt es Empfehlungen zum Zugriffstreiber? Ich haben jetzt den OLEDB-Treiber von Intellisoft gesehen, weiterhin hat Devart einen ADO.NET Treiber und dann gibt es noch kostenlose Pakete wie Npg…
Was ist mit der SQL-Syntax zum Erstellen und Pflegen der Strukturen, also alles was so mit “Create/Alter/Add/Drop” etc. angeht? Gibt es da Fallen?
Keine Ahnung, wir verwenden ausschließlich Java/JDBC
Was heisst “Fallen”?
Einige Datentypen sind unterschiedlich z.b. datetime2 vs. timestamp oder bit vs. boolean. Die bestehenden Skripte werden auf keinen Fall ohne Änderung laufen.
Grundsätzlich würde ich auch empfehlen Postgres auf Linux laufen zu lassen und nicht auf einem Windows Server. Viele nützliche Tools und Erweiterungen gibt es halt nur für Linux
Mit “Fallen” meine ich zum Beispiel eine andere SQL-Syntax zum Erzeugen/Anpassen von Tabellen zum Beispiel. Ich habe schon gemerkt, dass es bei den Datentypen Unterschiede gibt. Mit Linux kann ich leider nicht umgehen, da fehlen mir die Kenntnisse. Der PG soll auch auf einem windows-Server laufen, weil er die Datenquelle für einen Webservice ist, der unter dem IIS läuft. Da brächte man sonst doch wieder zwei Server und eben Linuxkenntnisse.
Ich danke dir auf jeden Fall mal für deine Hilfe, ist nicht selbstverständlich an einem Sonntag
Ja, das war natürlich ein unglückliches Beispiel, es muss freilich heißen “FieldA IS NULL”.
Dennoch scheitere ich derzeit an scheinbar trivialen Dingen. Vielleicht kann mir jemand da ja noch helfen. Ich habe folgenden simplen Code:
string sql = "SELECT ID, Nummer FROM TestTable WHERE ID=1";
OleDbCommand cmd = new OleDbCommand(sql, con);
OleDbDataAdapter oleda = new OleDbDataAdapter(cmd);
OleDbCommandBuilder olecb = new OleDbCommandBuilder(oleda);
oleda.UpdateCommand = olecb.GetUpdateCommand();
Genau in der letzten Zeile scheitert das System und sagt:
Das gibts doch nicht, oder? Die Tabelle ist da, habe sie mit dem “pgAdmin” selber angelegt.
Das Beispiel wäre mit dem OLEDB-Treiber von Intellisoft. Ein gleiches Beispiel habe ich mit dem Treiber von Devart:
string sql = "SELECT ID, Nummer FROM TestTable WHERE ID=1";
Devart.Data.PostgreSql.PgSqlCommand cmd = new Devart.Data.PostgreSql.PgSqlCommand(sql, con);
Devart.Data.PostgreSql.PgSqlDataAdapter oleda = new Devart.Data.PostgreSql.PgSqlDataAdapter(cmd);
Devart.Data.PostgreSql.PgSqlCommandBuilder olecb = new Devart.Data.PostgreSql.PgSqlCommandBuilder(oleda);
oleda.UpdateCommand = olecb.GetUpdateCommand();
"TestTable" ist ein anderer Name als TestTable (was das Gleiche ist, wie testtable).
Du hast offensichtlich beim Anlegen der Tabellen die Namen in doppelten Anführungszeichen geschrieben, was dazu führt, dass der Name nun Case-Sensitive ist (so wie der SQL Standard es fordert).
Am Besten verwendest Du niemals doppelte Anführungszeichen für Tabelle- oder Spaltenamen.
Ich nutze pgAdmin nicht, aber ich glaube das fügt die Anführungszeichen hinzu sobald ein Name Groß/Kleinschreibung enthält. D.h. im Fall Deines Screenshots wird daraus ein create table "TestTable" (...) gemacht.
Grundsätzlich ist das Anlegen von Tabellen über eine GUI sowieso eine schlechte Idee. Das SQL Skript muss ja eh irgendwo gespeichert werden (idealerweise in einem Versionsverwaltungssystem wie Git), da kann man es auch gleich selber “eintippen” - vor allem wenn die GUI versucht schlauer zu sein, als der Anwender.
Ja, du hast schon Recht, die TastTable war auch nur ein Versuch. Unsere echte Datenbank wird natürlich über einen Generator erzeugt, das wäre jetzt der nächste Schritt für mich. Ich wollte halt mal die grundsätzliche Anbindung der Datenbank austesten. Aber ich werde jetzt unseren Generator mal drauf los lassen.
Also, der Tipp mit den Gänsefüßchen war goldrichtig. Die GUI “pgAdmin” hat die einfach hinzugedichtet. Unser DB-Generator erzeugt die Tabellen ohne diese Gänsefüßchen und alle Tabellen sind kleingeschrieben.
Was nicht funktioniert sind solche Befehle wie diese hier. Da ist irgendwie die Syntax falsch, aber was?
ALTER TABLE AB_Anlagenarten ALTER COLUMN Inventarnummer TYPE VARCHAR(20) DROP NOT NULL
ALTER TABLE AB_Bewegungen ALTER COLUMN BewegungsartID TYPE BIGINT SET NOT NULL
Ach herrje, ich hab’s befürchtet. Da muss ich unseren Generator umbauen. Der baut derzeit einfach aus allen vorgegebenen Eigenschaften das ALTER Statement zusammen und feuert das ab. Wenn die bestehende Tabelle schon genau so aussieht wie das Statement das fordert, so ist bislang gar nix passiert.
Das wird auf jeden Fall spannend.
Danke und Gruß, Karsten.
Ich hätte nochmal bitte eine Frage. Offenbar gibt es ein Problem mit Umlauten, sowohl in Tabellennamen als auch in Feldnamen. Geht das generell nicht? Oder muss man das dem Server erst beibringen? Vom Sinn oder Unsinn der Umlaute mal abgesehen…
Es kommt jedenfalls folgende merkwürdige Meldung von einem “CREATE TABLE…” zurück:
Hm, wenn ich via “pgAdmin” eine Tabelle mit Umlauten anlegen, dann geht das auch…
Wo könnte ich denn das Encoding definieren? Im “Connectionstring” in C#?
Das Begrenzen auf eine bestimmte Menge an Sätzen im SELECT haben wir früher mit “SELECT TOP xxx” gemacht, bei PG muss man offenbar ein “LIMIT xxx” hinten anhängen.