{"id":1260,"date":"2019-09-25T17:02:17","date_gmt":"2019-09-25T17:02:17","guid":{"rendered":"http:\/\/www.art-events.de\/weblog\/?p=1260"},"modified":"2021-11-14T15:35:06","modified_gmt":"2021-11-14T14:35:06","slug":"fuer-programmers-firebird-und-microsoft-sql-server-nutzen","status":"publish","type":"post","link":"https:\/\/www.art-events.de\/weblog\/fuer-programmers-firebird-und-microsoft-sql-server-nutzen\/","title":{"rendered":"F\u00fcr Programmers: Firebird und Microsoft SQL Server nutzen"},"content":{"rendered":"<p>Werbung: Mobile Apps f\u00fcr Datenerfassung gibt es bei AESYSTEME<br \/>\n<a href=\"https:\/\/www.terminal-systems.de\/wp\/home-2\/mobile1\/\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-2419 size-large\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2021\/11\/211102-apps1-1024x341.jpg\" alt=\"\" width=\"640\" height=\"213\" srcset=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2021\/11\/211102-apps1-1024x341.jpg 1024w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2021\/11\/211102-apps1-300x100.jpg 300w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2021\/11\/211102-apps1-768x256.jpg 768w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2021\/11\/211102-apps1-1536x512.jpg 1536w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2021\/11\/211102-apps1-1568x523.jpg 1568w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2021\/11\/211102-apps1.jpg 1800w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n<p>Das ist jetzt eine Betrachtung f\u00fcr C# und DOT NET Anwendungsprogrammierer!\u00a0Der eine oder andere hat es ja schon ausf\u00fchrlich diskutiert: im Rahmen unserer Produktpflege werden wir die Lagerverwaltung AE WWS Lite (<a href=\"https:\/\/www.terminal-systems.de\/wp\/home-2\/lager1\/lagerverwaltung-aktuell\/\">Link hier<\/a>) zuk\u00fcnftig mit zwei SQL Clients versehewn:<\/p>\n<ul>\n<li>F\u00fcr\u00a0Microsoft SQL Server (incl der kostenfreien Microsoft SQL Server Express Versionen)<\/li>\n<li>als auch f\u00fcr Firebird SQL Server. <a href=\"https:\/\/firebirdsql.org\" target=\"_blank\" rel=\"noopener noreferrer\">LINK_HIER<\/a>.<\/li>\n<\/ul>\n<p><a href=\"http:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2019\/09\/20190925-SQLGrau.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-1265\" src=\"http:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2019\/09\/20190925-SQLGrau-1024x429.jpg\" alt=\"\" width=\"640\" height=\"268\" srcset=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2019\/09\/20190925-SQLGrau-1024x429.jpg 1024w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2019\/09\/20190925-SQLGrau-300x126.jpg 300w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2019\/09\/20190925-SQLGrau-768x322.jpg 768w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<p>Technisch gesehen ben\u00f6tigt die Software daher zwei SQL Clients: f\u00fcr Microsoft SQL Server und die Firebird DOT NET Bibliothek, beide jeweils als DLL Datei im Programmverzeichnis.<\/p>\n<p>Im ersten Workaround gehen wir davon aus, dass die Software jeweils nur f\u00fcr einen der Clients compiliert wird. Nat\u00fcrlich w\u00e4re es problemlos m\u00f6glich, beide Clients zum gleichen Zeitpunkt zu integrieren &#8211; jedoch w\u00fcrde hierbei das Anwendungsprogramm u.E. nach unn\u00f6tig aufgebl\u00e4ht werden, so dass wir erst mal mit der Trennung auf Compilerebene arbeiten.<\/p>\n<p>De facto sind bereits heute alle SQL Aktivit\u00e4ten in einer eigenen SQL Klasse ausgelagert. Das hat den Vorteil dass f\u00fcr die Umstellung nur eine Datei angepasst werden muss.<\/p>\n<p>Datei: SQL Class<\/p>\n<hr \/>\n<h3><strong>Preprocessor Compiler Definition<\/strong><\/h3>\n<p>Am Anfang: Preprocessor Defintion f\u00fcr den Compiler. Via Copy und Paste wird hier\u00a0 direkt vor dem Compilieren wahlweise Firebird oder MSSQL eingetragen. Im Beispiel aktuell wird der Code auf Firebird compiliert:<\/p>\n<pre>\/\/ Firebird OR MSSQL\r\n#define Firebird<\/pre>\n<hr \/>\n<p>Weil uns Fragen erreichten:<\/p>\n<h3><strong>Exkurs: Was macht der Preprocessor im Compiler<\/strong><\/h3>\n<p>Mit dem Preprocessor kann man den Compiler beim \u00dcbersetzen der Anwendung dazu bringen, gewisse Teile des Codes zu ignorieren oder zu verwenden. Erreicht wird dieses in der Regel durch<\/p>\n<pre>#if (AUSDRUCK)\r\n\r\n#elif (AUSDRUCK)\r\n\r\n#endif<\/pre>\n<p>Formulierungen. Wenn der Compiler findet dass AUSDRUCK wahr (TRUE) ist, wird der eingeschlossene Code compiliert. Ansonsten ignoriert. Dieses Verhalten ist besonders dann von Bedeutung, wenn man seinen Code f\u00fcr bestimmte Bedingungen \u00fcbersetzen will, z.B. nur f\u00fcr eine bestimmte Sprache oder wie in diesem Fall nur f\u00fcr einen bestimmten SQL Client &#8211; und trotzdem in allen F\u00e4llen mit dem gleichen Sourcecode in einem Projekt arbeiten m\u00f6chte.<\/p>\n<p>Und nat\u00fcrlich kann man den Preprocessor auch durch jederzeit eine if Bedingung im Code ersetzen. Dann werden alle Optionen compiliert und man er\u00f6ffnet dem Anwender die M\u00f6glichkeit, beide Teile zu verwenden. (Hier muss man dann nat\u00fcrlich eine Anwendungssteuerung f\u00fcr den Benutzer programmieren, dass dieser mittels Auswahlfeld zur Laufzeit bestimmen kann, welchen Teil er haben m\u00f6chte. Der Nachteil dieser Kombination: Da immer alles compiliert wurde, wird das Programm hierdurch gr\u00f6\u00dfer, Insofern sind<\/p>\n<pre>#if (DEUTSCH)\r\n\r\nhier nur der deutsche Teil\r\n\r\n#endif\r\n\r\nund \r\n\r\nif (DEUTSCH == TRUE) { deutscher Teil; }<\/pre>\n<p>im Prinzip gleichwertig. Allerdings kann man den #if \/ #endif Teil dazu verwenden dass der Compiler den Inhalt ignoriert = das Programm k\u00fcrzer macht. Hier gilt es also zu \u00fcberlegen, ob dem Anwender alle Bedingungen gleicherma\u00dfen zur Verf\u00fcgung stehen m\u00fcssen, oder ob man mittels Preprocessor Compilerschalter bestimmten Code einfach ausblendet.<\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<h3><strong>SQL DLLs einbinden, f\u00fcr Firebird SQL oder Microsoft SQL<\/strong><\/h3>\n<p>Die Einbindung der verschiedenen DLL f\u00fcr die SQL Clients. Es wird nur derjenige SQL Client eingebunden, der im Compiler aktiviert wurde.<\/p>\n<pre>#if (MSSQL)\r\nusing System.Data.SqlClient;\r\n#endif\r\n\r\n#if (Firebird)\r\nusing FirebirdSql.Data.FirebirdClient;\r\n#endif<\/pre>\n<hr \/>\n<h3><strong>SQL Datensatz schreiben<\/strong><\/h3>\n<p>Beispiel der Routine die einen Datensatz an den SQL Server schreibt &#8211; mit Unterst\u00fctzung SQL Client Microsoft SQL Server und Firebird:<\/p>\n<p>\/\/ Nur aktivieren wenn SQL aktiv!<\/p>\n<pre>if (Form1.OpenMode != (int)OpenModeValue.SQL) { return;}<\/pre>\n<p>\/\/ Das SQL Kommando. In diesem Fall haben wir den Namen der SQL Tabelle als Parameter in Form1 definiert. Sch\u00f6ner, aber f\u00fcr unser Beispiel etwas un\u00fcbersichtlicher, ist es nat\u00fcrlich den Tabellennamen beim Aufruf der Sub zu \u00fcbergeben.<\/p>\n<pre>string cmdstring = \"INSERT INTO \" + Form1.SQLTable_Data + \" (Idx, ArtNr, ArtText, MaterialGroup) \" + \"VALUES (@Idx, @ArtNr, @ArtText, @MaterialGroup )\";<\/pre>\n<p>\/\/ Die Befehlsfolge f\u00fcr Microsoft SQL<\/p>\n<pre>#if (MSSQL)\r\nSqlConnection connection = new SqlConnection(Form1.SQLConnectionstringNeu);\r\nconnection.Open();\r\nSqlCommand command = new SqlCommand(cmdstring, connection);\r\n#endif<\/pre>\n<p>\/\/ Die Befehlsfolge f\u00fcr Firebird SQL<\/p>\n<pre>#if (Firebird)\r\nFirebirdSql.Data.FirebirdClient.FbConnection connection = new FirebirdSql.Data.FirebirdClient.FbConnection(Form1.SQLConnectionstringNeu);\r\nconnection.Open();\r\nFirebirdSql.Data.FirebirdClient.FbCommand command = new FirebirdSql.Data.FirebirdClient.FbCommand(cmdstring, connection);\r\n#endif<\/pre>\n<p>\/\/ Und hier die Befehle f\u00fcr beide SQL Clients: Daten f\u00fcllen und schreiben. Da die Befehle identisch sind, ist eine Trennung nicht mehr notwendig. Wer mag, kann diese Befehle noch in ein &#8222;try &#8230; catch (exception)&#8220; kapseln und sich so vor ungewollten Ausnahmen sch\u00fctzen.<\/p>\n<pre>command.Parameters.AddWithValue(\"@Idx\", myAdv[\"Idx\"]);\r\ncommand.Parameters.AddWithValue(\"@ArtNr\", myAdv[\"ArtNr\"]);\r\ncommand.Parameters.AddWithValue(\"@ArtText\", myAdv[\"ArtText\"]);\r\ncommand.Parameters.AddWithValue(\"@MaterialGroup\", myAdv[\"MaterialGroup\"]);\r\n\r\ncommand.ExecuteNonQuery();<\/pre>\n<p>\/\/ Auf gar keinen Fall Close vergessen!!! Dateien oder Datenbanken nach Verwendung NICHT zu schlie\u00dfen ist ein Kapitalverbrechen f\u00fcr jeden Programmierer und sollte in Fleisch und Blut \u00fcbergehen.<\/p>\n<pre>connection.Close()<\/pre>\n<hr \/>\n<h3><strong>SQL Datens\u00e4tze lesen<\/strong><\/h3>\n<p>\u00c4hnlich aufgebaut wenn alle Datens\u00e4tze aus einer Tabelle gelesen werden sollen. Auf die erl\u00e4uternden Kommentare verzichten wir hier und zeigen gleich die ganze Routine:<\/p>\n<pre>public bool SQLReadTable(string mySQLTable, DataTable myDT1)\r\n{\r\n\/\/=======================================================\r\n\/\/Ganze Tabelle lesen. Firebird und MSSQL\r\n\/\/Return: TRUE wenn alles OK, FALSE im Fehlerfall\r\n\/\/=======================================================\r\n\r\n\/\/Die Datatable wird vor dem Lesen geloescht\r\nmyDT1.Clear();\r\n\r\n#if (MSSQL)\r\nSqlDataAdapter locAdapter = new SqlDataAdapter(\"Select * from \" + mySQLTable, Form1.SQLConnectionstringNeu);\r\n#endif\r\n#if (Firebird)\r\nFirebirdSql.Data.FirebirdClient.FbDataAdapter locAdapter = new FirebirdSql.Data.FirebirdClient.FbDataAdapter(\"Select * from \" + mySQLTable, Form1.SQLConnectionstringNeu);\r\n#endif\r\n\r\ntry\r\n{\r\nlocAdapter.Fill(myDT1);\r\n}\r\ncatch (Exception ex)\r\n{\r\n\/\/Sollte es zu einer Ausnahme gekommen sein, greifen wir die hier ab!\r\nMessageBox.Show(\"#1610101100 ERROR.\\n\\n\" + ex.Message, \"SQL ERROR: sqlreadtable\", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);\r\nreturn false;\r\n}\r\n\r\nreturn true;\r\n\r\n} \/\/end sub\r\n\r\n\r\n<\/pre>\n<hr \/>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Werbung: Mobile Apps f\u00fcr Datenerfassung gibt es bei AESYSTEME &nbsp; Das ist jetzt eine Betrachtung f\u00fcr C# und DOT NET Anwendungsprogrammierer!\u00a0Der eine oder andere hat es ja schon ausf\u00fchrlich diskutiert: im Rahmen unserer Produktpflege werden wir die Lagerverwaltung AE WWS Lite (Link hier) zuk\u00fcnftig mit zwei SQL Clients versehewn: F\u00fcr\u00a0Microsoft SQL Server (incl der kostenfreien [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[18,36],"tags":[],"class_list":["post-1260","post","type-post","status-publish","format-standard","hentry","category-software-technical-view","category-windows-linux","entry"],"_links":{"self":[{"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/posts\/1260","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/comments?post=1260"}],"version-history":[{"count":0,"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/posts\/1260\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/media?parent=1260"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/categories?post=1260"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/tags?post=1260"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}