{"id":516,"date":"2007-04-01T13:25:57","date_gmt":"2007-04-01T11:25:57","guid":{"rendered":"http:\/\/www.glorf.it\/blog\/2007\/04\/01\/sql-talk\/sql-server-daten-aus-csv-oder-xls-lesen"},"modified":"2007-04-01T13:55:25","modified_gmt":"2007-04-01T11:55:25","slug":"sql-server-daten-aus-csv-oder-xls-lesen","status":"publish","type":"post","link":"http:\/\/www.glorf.it\/blog\/2007\/04\/01\/sql-talk\/sql-server-daten-aus-csv-oder-xls-lesen","title":{"rendered":"SQL-Server: Daten aus CSV  oder XLS lesen"},"content":{"rendered":"<p>In meinem gestrigen SQL-Kurs fragte mich ein Teilnehmer, wie man Daten aus einer CSV- oder XLS-Datei in den Microsoft SQL-Server laden kann.<\/p>\n<p>Dazu gibt es ein ganzes B&#252;ndel an M&#246;glichkeiten. Wenn man selber Administrator ist und f&#252;r den eigenen Bedarf Daten importieren will, dann w&#252;rde ich den Einsatz von OpenRowSet bevorzugen.<\/p>\n<p>Das erkl&#228;re ich im folgenden im Rahmen einer Work-Bench: Man kann den kompletten Code in das Management-Studio laden und schrittweise ausf&#252;hren. Dazu markiert man die Statements,<br \/>\ndie zwischen zwei &quot;go&quot; stehen und dr&#252;ckt auf &quot;Ausf&#252;hren&quot;. Dadurch werden nur die markierten Befehle ausgef&#252;hrt.<\/p>\n<p>Die <a href='http:\/\/www.glorf.it\/blog\/wp-content\/uploads\/2007\/04\/openrowset.zip' title='Alle Dateien auf einen Schlag'>ben&#246;tigten Dateien<\/a> kann man auf einen Schwupps speichern.<\/p>\n<p>Eigentlich wollte ich es so machen, dass man den ganzen Text einfach per Cut&#038;Paste ins Management-Studio ziehen kann, aber WordPress wandelt die einfachen geraden Anf&#252;hrungszeichen immer in schr&#228;ge um. Damit kommt SQL aber nicht zurecht. Daher werden die <a href=\"http:\/\/www.glorf.it\/blog\/wp-content\/uploads\/2007\/04\/openrowset.zip\">Dateien<\/a> dennoch ben&#246;tigt.<\/p>\n<h4>Vorarbeiten: OpenRowSet erlauben<\/h4>\n<p>Zuerst den Zugriff auf externe Quellen mittels OpenRowSet erlauben<br \/>\nAchtung: bitte nur f&#252;r den internen Bedarf oder privat einsetzen. <\/p>\n<p><code lang=\"sql\">exec sp_configure 'show advanced options', 1<br \/>\nreconfigure with override<\/p>\n<p>exec sp_configure &#x0027;Ad Hoc Distributed Queries&#x0027;, 1<br \/>\nreconfigure with override<\/code><\/p>\n<h4>XLS lesen<\/h4>\n<p>Hier ein Beispiel-Zugriff auf ein Blatt in einer XLS-Datei. Die XLS-Datei ist auf dem Server unter &quot;I:\\Openrowset\\testing.xls&quot; gespeichert:<\/p>\n<p><code lang=\"sql\">select * from OPENROWSET( 'Microsoft.Jet.OLEDB.4.0',<br \/>\n&#x0027;Excel 8.0;Database=I:\\Openrowset\\testing.xls&#x0027;,'SELECT * FROM [Tabelle1$]&#x0027;)<br \/>\n<\/code><\/p>\n<p>H&#228;tte das Blatt einen anst&#228;ndigen Namen, dann w&#252;rde man anstelle von &quot;Tabelle1$&quot; diesen Namen schreiben.<\/p>\n<h4>In XLS schreiben<\/h4>\n<p>Man kann auch in ein bereits existierendes Excel-Document schreiben:<br \/>\n<code lang=\"sql\">insert into OPENROWSET( 'Microsoft.Jet.OLEDB.4.0',<br \/>\n             &#x0027;Excel 8.0;Database=I:\\Openrowset\\testing.xls&#x0027;,'SELECT * FROM [Tabelle1$]&#x0027;)<br \/>\n(Nachname, Vorname, Geburtstag, Wohnort)<br \/>\nvalues (&#x0027;Bond&#x0027;, &#x0027;James&#x0027;, &#x0027;4.4.1930&#x0027;, &#x0027;London&#x0027;) <\/p>\n<p>&#8211; Kontrolle, ob es geklappt hat:<br \/>\nselect * from OPENROWSET( &#x0027;Microsoft.Jet.OLEDB.4.0&#x0027;,<br \/>\n&#x0027;Excel 8.0;Database=I:\\Openrowset\\testing.xls&#x0027;,'SELECT * FROM [Tabelle1$]&#x0027;)<br \/>\n<\/code><\/p>\n<p>Es ist mir nicht gelungen ein neues Dokument anzulegen.<\/p>\n<h4>Aus XLS l&#246;schen<\/h4>\n<p>Das L&#246;schen geht leider nicht:<\/p>\n<p><code lang=\"sql\">delete from OPENROWSET( 'Microsoft.Jet.OLEDB.4.0',<br \/>\n            &#x0027;Excel 8.0;Database=I:\\Openrowset\\testing.xls&#x0027;,'SELECT * FROM [Tabelle1$]&#x0027;)<br \/>\nwhere nachname = &#x0027;Bond&#x0027;<\/code><\/p>\n<p>Es kommt ein Fehler, weil der Provider das L&#246;schen nicht unterst&#252;tzt:<br \/>\n<code>OLE DB provider \"Microsoft.Jet.OLEDB.4.0\" for linked server \"(null)\" returned message \"ISAM unterst&#252;tzt das L&#246;schen von Daten in einer verkn&#252;pften Tabelle nicht.\".<br \/>\nMsg 7345, Level 16, State 1, Line 1<br \/>\nThe OLE DB provider &quot;Microsoft.Jet.OLEDB.4.0&quot; for linked server &quot;(null)&quot; could not delete from table &quot;SELECT * FROM [Tabelle1$]&quot;. There was a recoverable, provider-specific error, such as an RPC failure.<br \/>\n<\/code><\/p>\n<h4>Zeilen aus XLS &#228;ndern<\/h4>\n<p>Das &#196;ndern von Datens&#228;tzen geht hingegen:<br \/>\n<code lang=\"sql\">Update OPENROWSET( 'Microsoft.Jet.OLEDB.4.0',<br \/>\n            &#x0027;Excel 8.0;Database=I:\\Openrowset\\testing.xls&#x0027;,'SELECT * FROM [Tabelle1$]&#x0027;)<br \/>\nset nachname = &#x0027;Blond&#x0027;<br \/>\nwhere nachname = &#x0027;Bond&#x0027;<\/p>\n<p>&#8211; Kontrolle, ob es geklappt hat:<br \/>\nselect * from OPENROWSET( &#x0027;Microsoft.Jet.OLEDB.4.0&#x0027;,<br \/>\n&#x0027;Excel 8.0;Database=I:\\Openrowset\\testing.xls&#x0027;,'SELECT * FROM [Tabelle1$]&#x0027;)<\/code><\/p>\n<h4>CSV lesen<\/h4>\n<p>Das Lesen der CSV geht auch mit dem Jet-Treiber:<\/p>\n<p><code lang=\"sql\">SELECT * FROM OPENROWSET( 'Microsoft.Jet.OLEDB.4.0',<br \/>\n&#x0027;Text;Database=I:\\Openrowset\\&#x0027;,'SELECT * FROM [testing.csv]&#x0027;)<\/code><\/p>\n<p>Hier gibt man als &quot;Database&quot; nur das Verzeichnis an, die Datei folgt im Select.<\/p>\n<p>Man kann auch &#252;ber ODBC lesen:<br \/>\n<code lang=\"sql\">SELECT *<br \/>\nFROM OPENROWSET(&#x0027;MSDASQL&#x0027;,<br \/>\n        &#x0027;Driver={Microsoft Text Driver (*.txt; *.csv)};DEFAULTDIR=I:\\Openrowset\\;Extensions=CSV;&#x0027;,<br \/>\n        &#x0027;SELECT * FROM [testing.csv]&#x0027;)<\/code><\/p>\n<p>Wenn man &quot;komplizierte&quot; Formate &#252;ber ODBC lesen will, dann muss man in der Datei &quot;schema.ini&quot; die Formate definieren. <\/p>\n<p>Als Beispiel habe ich die Datei mit den Losungen 2007 aus <a href=\"http:\/\/www.brueder-unitaet.de\/download\/Losung_2007_CSV.zip\">http:\/\/www.brueder-unitaet.de\/download\/Losung_2007_CSV.zip<\/a> verwendet.<\/p>\n<p><code lang=\"sql\">SELECT *<br \/>\nFROM OPENROWSET(&#x0027;MSDASQL&#x0027;,<br \/>\n        &#x0027;Driver={Microsoft Text Driver (*.txt; *.csv)};<br \/>\n          DEFAULTDIR=I:\\Openrowset\\;Extensions=CSV;&#x0027;,<br \/>\n        &#x0027;SELECT * FROM [Losungen Free 2007.csv]&#x0027;)<br \/>\n\/* Schema.ini in &quot;I:\\Openrowset\\&quot;:<br \/>\n[losungen free 2006.csv]<br \/>\nColNameHeader=True<br \/>\nMaxScanRows=0<br \/>\nCharacterSet=ANSI<br \/>\nFormat=Delimited(;)<br \/>\n*\/<br \/>\n<\/code><\/p>\n<h4>Nacharbeiten: OpenRowSet wieder abschalten<\/h4>\n<p><code lang=\"sql\">exec sp_configure 'Ad Hoc Distributed Queries', 0<br \/>\nreconfigure with override<\/p>\n<p>exec sp_configure &#x0027;show advanced options&#x0027;, 0<br \/>\nreconfigure with override<\/code><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In meinem gestrigen SQL-Kurs fragte mich ein Teilnehmer, wie man Daten aus einer CSV- oder XLS-Datei in den Microsoft SQL-Server laden kann. Dazu gibt es ein ganzes B&#252;ndel an M&#246;glichkeiten. Wenn man selber Administrator ist und f&#252;r den eigenen Bedarf Daten importieren will, dann w&#252;rde ich den Einsatz von OpenRowSet bevorzugen. Das erkl&#228;re ich im [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts\/516"}],"collection":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/comments?post=516"}],"version-history":[{"count":0,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts\/516\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/media?parent=516"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/categories?post=516"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/tags?post=516"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}