chgs2011
Goto Top

2 Spalten einer CSV per Batch in Variable auswerten und an MSSQL-Query übergeben

Hallo,

ich habe eine primitive CSV-Datei, die ich gerne auswerten würde (Spaltentrenner ";").
Die CSV hat beliebig viele Zeilen, muss daher auch zeilenweise verarbeitet werden.

Ich muss nun Spalte 3 und Spalte 5 von insg. 15 Spalten auswerten.
Ich wollte Spalte 3 und Spalte 5 jeweils in eine Variable auslesen.

Im nachfolgenden Schritt sollen die 2 Variablen an ein MSSQL-Query Befehl übergeben werden.
Das MSSQL-Query fragt mit Variable 1 in der Datenbank den Datensatz ab und schreibt dort Variable 2 nieder.

Ich habe hier im Forum dutzende Themen gesehen, gelesen und versucht.


Ich habe zuerst versucht, das CSV überhaupt einmal auszulesen im Batchfile, hatte aber Probleme.


@ECHO ON
CLS
COLOR 1e

FOR /F "eol=# tokens=3,5 delims=;" %%1 IN ("test.csv") DO echo %%1 %%2  

PAUSE

:setit
set var1=%~1
set var2=%~2

echo %var1% %var2%

PAUSE

Content-ID: 250034

Url: https://administrator.de/contentid/250034

Ausgedruckt am: 22.11.2024 um 22:11 Uhr

Friemler
Friemler 24.09.2014 aktualisiert um 16:41:51 Uhr
Goto Top
Hallo,

Dein Code ist ja schon fast richtig. Du bist nur über den üblichen Fallstrick von Batchscript gestolpert, die verzögerte Variablenerweiterung, hast nicht berücksichtigt, dass die Laufvariablen %%1 und %%2 der FOR-Schleife nichts mit den Parameter-Variablen %1 und %2 zu tun haben und hast die Syntax von FOR /F anscheinend noch nicht richtig verstanden (usebackq fehlt).

Tipp: Mein Tutorial zur FOR-Schleife

Hier mein Vorschlag:
@echo off & setlocal

cls
color 1e

for /f "usebackq eol=# tokens=3,5 delims=;" %%a in ("test.csv") do (  
  call :ProcessItems "%%a" "%%b"  
)

exit /b


:ProcessItems
  set "Var1=%~1"  
  set "Var2=%~2"  

  echo %Var1%
  echo %Var2%
exit /b

Hierbei gilt es aber zu beachten, dass der Batchscript-Interpreter bestimmte Zeichen als Steuerzeichen/Befehle auswertet. Wenn solche Zeichen in den zu verarbeitenden Zeichenketten enthalten sind, wird es zu Problemen kommen. Auch die Zeichencodierung (Konsole: Codepage 850) kann bei der Weitergabe an ein anderes Programm, das z.B. Windows-1252 erwartet, zu Problemen führen. In solchen Fällen kann man z.B. auf VBScript statt Batchscript ausweichen.

Gruß
Friemler
chgs2011
chgs2011 24.09.2014 um 20:09:37 Uhr
Goto Top
Hallo Friemler,

vielen Dank für den Ansatz, nun komme ich schon weiter!
Ich bin leider noch ein recht rechter Newbie, sorry.

Nun habe ich noch 2 kleine Schönheitsfehler, die Spalte wird nicht gezählt wenn keine Angabe enthalten ist, dann haut es mir leider alles durcheinander.
Zudem weiß ich nicht, was er bei diesen Zeichen treibt "<", ">", "[", "]" ... die Variable 2 gibt dann zB nur ein "b" aus.

So sieht eine Datenzeile z.B. aus, muss hier Spalte 2 und hinten "Deutschland" auslesen (zB Spalte 55):
3843;432784037441;0;1;1;4;;23.09.2014;4;25633;100;;3744;;;24966007033000;;AB-1409-29303-001;;1,45;;24.09.2014;0;0;3,82;[3,80] Gewicht<0>N [0,00] <101>L [0,02] <149>L;EUR;;0;;;33;EUR;Deutschland;;EUR;;276;0;;0;

OSQL läuft bereits, muss lediglich leere Spalten ebenfalls zählen und Sonderzeichen als String erkennen, eben den Wert zwischen je einem ";"

Vielen Dank vorab, hat mir schon sehr geholfen.
Friemler
Friemler 24.09.2014 aktualisiert um 23:34:13 Uhr
Goto Top
Hey,

tja, da haben wir den Salat: Sonderzeichen, die vom Batchscript-Interpreter als Steuerzeichen interpretiert werden und aufeinander folgende Trennzeichen, die nicht als ein Trennzeichen interpretiert werden sollen. Batchscript ist damit einfach überfordert.

Man könnte jetzt auf natives VBScript ausweichen, per VBScript Excel fernsteuern und die Datei damit zerpflücken oder PowerShell benutzen. In letzterem bin ich so gut wie ahnungslos. Um aus den ersten beiden Möglichkeiten die richtige auswählen zu können, musst Du zuerst noch verraten, ob es dabei bleibt, in jeder Zeile der CSV-Datei zwei bestimmte Spalten auszulesen, oder ob da evtl. noch mehr ausgelesen oder gar manipuliert werden muss oder ob es Abhängigkeiten zwischen Spalten gibt (z.B. "verarbeite Spalte X nur dann, wenn Spalte Y den Wert Z enthält" o.ä.). Je komplexer die Aufgabe, um so eher tendiere ich zur Excel-Fernsteuerlösung.

Gruß
Friemler
chgs2011
chgs2011 25.09.2014 um 00:12:54 Uhr
Goto Top
Hey,

sooo ein Käse face-sad

Also, der Aufbau der CSV-Dateien bleibt IMMER gleich, auch die Spalten die ausgelesen werden müssen.
Es muss NICHTS manipuliert werden, NUR ausgelesen werden um die Ausgaben per SQL an die DB zu übergeben.

Ich benötige lediglich Spalte X + Y derzeit, habe dies nochmals geprüft. Diese Spalten kommen VOR den Steuerzeichen vor,
so dass unser Script nicht durch alle Spalten laufen / zählen muss.

Ich brauche also den Wert von oben "432784037441" (Spalte 2) und "AB-1409-29303-001" (Spalte 18).
Man müsste also nur die Leerzellen abfangen und mitzählen, da diese einmal befüllt oder leer sind.
rubberman
rubberman 25.09.2014 um 00:28:06 Uhr
Goto Top
Hallo chgs2011.

Käse oder nicht, Friemler hat schon Recht. CSV sicher mit Batch zu parsen ist genauso aussichtslos wie XML oder HTML. Und genau mit dem "Leerzellen abfangen" kommst du mit einer einfachen FOR /F Schleife an die Grenzen des Machbaren. Richtig eklig wird es aber (neben den von Friemler schon genannten Problemen), wenn innerhalb eines in Anführungszeichen stehenden Wertes Semikola vorkommen, die nicht als Trennzeichen geparst werden dürfen oder wenn ein einzelnes Line Feed einen Umbruch innerhalb eines Wertes darstellt, während die Kombination aus Carriage Return und Line Feed den Datensatz beendet. Bei solchen Dingen kommt eigentlich tatsächlich nur noch Excel infrage.

Deinem Beispiel zufolge ist der Spaß aber gerade noch mit Batch eine überschaubare Aufgabe.
@echo off &setlocal
set "file=test.csv"  
set /a "n1 = 2, n2 = 18"  

setlocal EnableDelayedExpansion
<"!file!" (  
  for /f %%i in ('type "!file!"^|find /c /v ""') do for /l %%j in (1 1 %%i) do (  
    set "line=" &set /p "line="  
    set /a "c=0"  
    for %%k in ("!line:;=" "!") do (  
      set /a "c += 1"  
      if !c!==!n1! (
        endlocal
        set "c=%n1%"  
        set "var1=%%~k"  
        setlocal EnableDelayedExpansion
      )
      if !c!==!n2! (
        endlocal
        set "c=%n2%"  
        set "var2=%%~k"  
        setlocal EnableDelayedExpansion        
      )
    )
    call :ProcessItems
  )
)
endlocal
pause
exit /b

:ProcessItems
echo !var1!
echo !var2!
exit /b
Grüße
rubberman
chgs2011
chgs2011 27.09.2014 um 11:59:34 Uhr
Goto Top
Danke für eure Hilfe, das 2. Beispiel sieht komplett anders aus, ist aber fast das was ich gesucht habe.

Leider habe ich das Problem, dass nur die erste Zeile von zB. 11 übergeben wird, mein aktuelles Script sieht so aus:

@echo off & setlocal

cls
color 1e
mode con lines=20 cols=55

ECHO.
ECHO.
ECHO. ####################################################
ECHO. ####################################################
ECHO.
ECHO.
ECHO.
ECHO.                      ACHTUNG
ECHO.
ECHO.   DHL-Sendungsdatenimport laeuft, bitte warten ...
ECHO.
ECHO.
ECHO.
ECHO. ####################################################
ECHO. ####################################################
ECHO.
ECHO.

set "file=\\chgs-office\DHL\OUT\out.txt"  
set /a "n1 = 2, n2 = 23"  

setlocal EnableDelayedExpansion
<"!file!" (  
  for /f %%i in ('type "!file!"^|find /c /v ""') do for /l %%j in (1 1 %%i) do (  
    set "line=" &set /p "line="  
    set /a "c=0"  
    for %%k in ("!line:;=" "!") do (  
      set /a "c += 1"  
      if !c!==!n1! (
        endlocal
        set "c=%n1%"  
        set "var1=%%~k"  
        setlocal EnableDelayedExpansion
      )
      if !c!==!n2! (
        endlocal
        set "c=%n2%"  
        set "var2=%%~k"  
        setlocal EnableDelayedExpansion        
      )
    )
    call :ProcessItems
  )
)
endlocal

exit /b

:ProcessItems
"\\hauptserver\Microsoft SQL Server\100\Tools\Binn\SQLCMD.EXE" -S HAUPTSERVER,1083\TEST -d testdb -U admin -P pass -Q "UPDATE tVersand SET cIdentCode = '%Var1%' FROM tVersand INNER JOIN tLieferschein ON tVersand.kLieferschein = tLieferschein.kLieferschein WHERE (tVersand.kLieferschein = tVersand.kLieferschein) AND (tLieferschein.cLieferscheinNr = '%Var2%')"  

CLS
ECHO.
ECHO.
ECHO. ####################################################
ECHO. ####################################################
ECHO.
ECHO.
ECHO.
ECHO.                      ACHTUNG    
ECHO.
ECHO.   DHL-Sendungsdatenimport laeuft, bitte warten ...
ECHO.
ECHO.
ECHO.
ECHO. ####################################################
ECHO. ####################################################
ECHO.
ECHO.

exit /b


Wo liegt das Problem bei mir?

P.S. die Verbindung mit SQLCMD auf die Datenbank ist das einzigste was am längsten Zeit frist, leider ist das aber nicht anders lösbar.
rubberman
rubberman 27.09.2014 um 14:17:13 Uhr
Goto Top
Leider habe ich das Problem, dass nur die erste Zeile von zB. 11 übergeben wird
Aha, die erste Zeile von 11. Ist das so etwas wie das 5. Wort von "Bahnhof"?

Wo liegt das Problem bei mir?
Kann man nicht ohne reale CSV Datei beantworten. Aber das Hauptproblem ist vermutlich immer noch dass du Batch verwendest...

Grüße
rubberman
chgs2011
chgs2011 27.09.2014 um 15:07:11 Uhr
Goto Top
Ja klar Batch face-sad

Ich dachte das Script liest je Zeile nur die Spalten vor Steuerzeichen aus, dann hätte ich das Problem nicht.

Ich habe das ECHO ja auslesen lassen, hier wurden die Werte korrekt ausgelesen. Ersetze ich aber das ECHO mit SQLCMD, wird nur noch die erste Zeile verarbeitet, obwohl das Script alle Zeilen durchläuft.

face-sad
rubberman
rubberman 27.09.2014 um 15:39:24 Uhr
Goto Top
Ja klar Batch face-sad
Naja, noch deutlicher kann man nicht auf die Gefahren hinweisen. Batch mag für einiges taugen, zum Parsen einer CSV Datei aber nun mal nicht.

Ich dachte das Script liest je Zeile nur die Spalten vor Steuerzeichen aus
Nein. Jeder Wert wird gelesen, sogar "leere" Werte.

Ich kenne den Inhalt deiner CSV nach wie vor nicht.

Die Subroutine :ProcessItems läuft in einer Umgebung mit verzögerter Variablenerweiterung. Also ersetze dort die Prozentzeichen durch Ausrufezeichen bei den Variablen (so wie ich es dir oben vorgeturnt habe). Das verhindert schon mal dass der Batchcode abbricht wenn die Werte Zeichen enthalten, die in Batch eine besondere Bedeutung haben.
Was ich nicht weiß ist ob diese Werte dann Zeichen enthalten, die nicht in einer SQL Anweisung stehen dürfen. Da wäre ich auch sowieso überfragt, da ich davon keine Ahnung habe.

Grüße
rubberman
Friemler
Friemler 27.09.2014 aktualisiert um 17:05:42 Uhr
Goto Top
Hi,

sooo ein Käse face-sad
lass Dir für die Zukunft gesagt sein, dass solches Verhalten von jemandem, der Dir helfen möchte, als unverschämt empfunden werden kann...

Also, der Aufbau der CSV-Dateien bleibt IMMER gleich, auch die Spalten die ausgelesen werden müssen.
Es muss NICHTS manipuliert werden, NUR ausgelesen werden um die Ausgaben per SQL an die DB zu übergeben.
Ich habe die Erfahrung gemacht, dass Hilfesuchende oft nicht sofort verraten/erkennen, ob/wie ihre Daten manipuliert werden müssen. Deshalb habe ich Dich gebeten, darüber Auskunft zu geben und nicht behauptet, dass es so ist.

Ich benötige lediglich Spalte X + Y derzeit, habe dies nochmals geprüft. Diese Spalten kommen VOR den Steuerzeichen vor,
so dass unser Script nicht durch alle Spalten laufen / zählen muss.

Ich brauche also den Wert von oben "432784037441" (Spalte 2) und "AB-1409-29303-001" (Spalte 18).
Man müsste also nur die Leerzellen abfangen und mitzählen, da diese einmal befüllt oder leer sind.
Wenn Du wüsstest, wie die benötigten Batchscript-Befehle funktionieren, hättest Du hier keine Hilfe gesucht. Aus diesem Grund hättest Du Dir denken können, dass es schon möglich ist, dass es dabei Probleme gibt, von deren Existenz Du nichts wissen kannst.

OK, rubberman hat es wieder einmal geschafft, auch dieses Problem mit Batchscript (fast?) zu lösen (dafür meinen Respekt), ich persönlich benutze inzwischen lieber die Programmiersprache, die mir für die Problemstellung am geeignetsten erscheint, d.h. wo ich mir die wenigsten Knoten ins Hirn machen muss um zu einer sicheren Lösung zu kommen

Gruss
Friemler
chgs2011
chgs2011 27.09.2014 um 17:26:31 Uhr
Goto Top
Ich habe die Variablen-Ausgabe auch mit "!" Zeichen versucht, ECHO klappt immer, nur verarbeitet er bei SQLCMD die erste Zeile.

Anbei mal die komplette TXT!

Spalte 2 muss abgefragt werden, sowie die Spalte mit den Werten "AB-1409-29..."


3877;432784037772;0;1;1;4;0;0;0;0;0;27.09.2014;4;25697;100;;3777;;;;;;AB-1409-29381-001;;0,72;;27.09.2014;0;0;3,82;Deutschland;[0,00] Gewicht<0>N[0,00] DHL Paket<101>L[0,02] Go Green<149>L;EUR
3878;432784037788;0;1;1;4;0;0;0;0;0;27.09.2014;4;25698;100;;3778;;;;;;AB-1409-29382-001;;6,02;;27.09.2014;0;0;4,77;Deutschland;[0,00] Gewicht<0>N[0,00] DHL Paket<101>L[0,02] Go Green<149>L;EUR
3879;432784037794;0;1;1;4;0;0;0;0;0;27.09.2014;4;25706;100;;3779;;;;;;AB-1409-29392-001;;1,39;;27.09.2014;0;0;3,82;Deutschland;[0,00] Gewicht<0>N[0,00] DHL Paket<101>L[0,02] Go Green<149>L;EUR
3880;432784037801;0;1;1;4;0;0;0;0;0;27.09.2014;4;25742;100;;3780;;;;;;AB-1409-29433-001;;0,24;;27.09.2014;0;0;3,82;Deutschland;[0,00] Gewicht<0>N[0,00] DHL Paket<101>L[0,02] Go Green<149>L;EUR
3881;432784037817;0;1;1;4;0;0;0;0;0;27.09.2014;4;25737;100;;3781;;;;;;AB-1409-29428-001;;0,26;;27.09.2014;0;0;3,82;Deutschland;[0,00] Gewicht<0>N[0,00] DHL Paket<101>L[0,02] Go Green<149>L;EUR
3882;432784037823;0;1;1;4;0;0;0;0;0;27.09.2014;4;25738;100;;3782;;;;;;AB-1409-29429-001;;0,1;;27.09.2014;0;0;3,82;Deutschland;[0,00] Gewicht<0>N[0,00] DHL Paket<101>L[0,02] Go Green<149>L;EUR
3883;432784037839;0;1;1;4;0;0;0;0;0;27.09.2014;4;25741;100;;3783;;;;;;AB-1409-29432-001;;4,75;;27.09.2014;0;0;4,07;Deutschland;[0,00] Gewicht<0>N[0,00] DHL Paket<101>L[0,02] Go Green<149>L;EUR
3884;432784037845;0;1;1;4;0;0;0;0;0;27.09.2014;4;25751;100;;3784;;;;;;AB-1409-29445-001;;0,47;;27.09.2014;0;0;3,82;Deutschland;[0,00] Gewicht<0>N[0,00] DHL Paket<101>L[0,02] Go Green<149>L;EUR
3885;432784037851;0;1;1;4;0;0;0;0;0;27.09.2014;4;25649;100;;3785;;;;;;AB-1409-29449-001;;0,76;;27.09.2014;0;0;3,82;Deutschland;[0,00] Gewicht<0>N[0,00] DHL Paket<101>L[0,02] Go Green<149>L;EUR
3886;432784037867;0;1;1;4;0;0;0;0;0;27.09.2014;4;25755;100;;3786;;;;;;AB-1409-29450-001;;1,05;;27.09.2014;0;0;3,82;Deutschland;[0,00] Gewicht<0>N[0,00] DHL Paket<101>L[0,02] Go Green<149>L;EUR
3887;432784037873;0;1;1;4;0;0;0;0;0;27.09.2014;4;9881;100;;3787;;;;;;AB-1409-29453-001;;0,64;;27.09.2014;0;0;3,82;Deutschland;[0,00] Gewicht<0>N[0,00] DHL Paket<101>L[0,02] Go Green<149>L;EUR
rubberman
rubberman 27.09.2014 um 20:14:18 Uhr
Goto Top
Hast du mal versucht einfach 2 Beispielaufrufe für SQLCMD hintereinander zu setzen? Á la
@echo off &setlocal
"\\hauptserver\Microsoft SQL Server\100\Tools\Binn\SQLCMD.EXE" -S HAUPTSERVER,1083\TEST -d testdb -U admin -P pass -Q "UPDATE tVersand SET cIdentCode = '432784037772' FROM tVersand INNER JOIN tLieferschein ON tVersand.kLieferschein = tLieferschein.kLieferschein WHERE (tVersand.kLieferschein = tVersand.kLieferschein) AND (tLieferschein.cLieferscheinNr = 'AB-1409-29381-001')"  
"\\hauptserver\Microsoft SQL Server\100\Tools\Binn\SQLCMD.EXE" -S HAUPTSERVER,1083\TEST -d testdb -U admin -P pass -Q "UPDATE tVersand SET cIdentCode = '432784037788' FROM tVersand INNER JOIN tLieferschein ON tVersand.kLieferschein = tLieferschein.kLieferschein WHERE (tVersand.kLieferschein = tVersand.kLieferschein) AND (tLieferschein.cLieferscheinNr = 'AB-1409-29382-001')"  
pause
Und (wenn die MSDN Referenz richtig ist) ist es nicht so, dass ein Query eigentlich mit einem Semikolon abgeschlossen wird?

Grüße
rubberman
chgs2011
chgs2011 27.09.2014 um 21:56:30 Uhr
Goto Top
Ja habe ich, klappt einwandfrei, am Query liegt es nicht ... Semikolon braucht man hier auch nicht.

Die Ausgabe per ECHO klappt ja ebenfalls im ":ProcessItems ", nur wenn ich hier den Query verbaue, dann wird nur Zeile 1 übergeben.

Ich würde daher soweit alles andere ausschließen, der Code läuft fehlerfrei durch, Query stimmt ... nur werden wohl die Variablen nicht je Datenzeile ersetzt.
Kann das an der eigentlichen Query-Einbindung im Batch liegen? An einem Timeout? Sollte man einen Zeitpuffer von 500-750ms einbauen?

Wir sind bis dato sehr weit gekommen und bin sehr dankbar, alles auf VB umbauen wäre schade, zumal ich hier noch weniger Erfahrung habe. face-sad
rubberman
rubberman 27.09.2014 aktualisiert um 22:21:50 Uhr
Goto Top
Das ist im Trüben fischen.

Dass es ein Delay braucht, kann ich mir nicht vorstellen, kannst du aber testen.
>nul timeout /t 1 /nobreak

Kannst auch mal ein CALL vor den SQLCMD Aufruf setzen.

Ich glaube aber immer noch nicht dass das des Rätsels Lösung ist. Einfach weiter testen und überflüssigen Kram (insbesondere CLS) aus dem Code schmeißen, damit du auch Fehlermeldungen mitbekommst, falls sie auftreten...

Grüße
rubberman
chgs2011
chgs2011 27.09.2014 um 23:46:17 Uhr
Goto Top
Habe es mit einer Wartezeit mal versucht ...
ping 127.0.0.1 -n 5 > nul
.. brachte leider auch nichts.


Wenn ich teste, mache ich mir ohnehin jeden Schnickschnack aus, um mitlesen zu können, keine Fehler.


Habe dann zunächst mal die Werte bereinigt, habe mir eine saubere TXT schreiben lassen (2 Datenzeilen als Test):
432784037772;AB-1409-29381-001;
432784037788;AB-1409-29382-001;


Anschließend habe ich diese TXT verarbeitet und an den Query übergeben, um sicher zu gehen, dass keine Sonder-/Steuerzeichen Probleme machen.
Auch hier, wird nur die erste Zeile verarbeitet ...

Wie es scheint, mag Batch die SQLCMD Query nicht face-sad ...


Das Batch gibt auch keine Fehler aus, es schreibt stets, dass es eine Zeile in der DB aktualisiert hat, was auch korrekt ist.
Leider ist es aber immer nur die Zeile 1, die Variablen werden also im Query nicht ausgetauscht / ausgewechselt.


Ich hätte jetzt nur eine letzte Idee, um dem ganzen Problem aus dem Weg zu gehen.
Kann man nicht je Datenzeile 2 neue Variablen vergeben? Sprich dass unser Batch die Variablen fortlaufend hochzählt?
Im Query müsste ich dann ebenfalls auf die jeweilige Variable zugreifen.

Man könnte so sicherstellen, dass die Variablen saubere Values haben, wenn das nicht klappt, kann Batch keine SQL-Querys mit Schleifen verarbeiten.
rubberman
rubberman 28.09.2014 um 00:25:04 Uhr
Goto Top
Kann man nicht je Datenzeile 2 neue Variablen vergeben? Sprich dass unser Batch die Variablen fortlaufend hochzählt?

Wenn die Variablenwerte nicht verändert würden, würde die ECHO Ausgabe auch nicht funktionieren. Und ob du nun den Wert in die Console schreibst, oder an ein anderes Programm übergibst, ist völlig egal. Die Expansion der Variablen zum Wert findet im Batchcode statt und nicht erst beim aufgerufenen Programm.

Mit der Schleife hat das auch nichts mehr zu tun, da der Aufruf in einer Subroutine stattfindet.

Es ist doch ziemlich offensichtlich, dass das Problem woanders liegt. Ich muss wohl doch mal parallel Google anwerfen und mich in die SQL Statements einarbeiten...

Grüße
rubberman
chgs2011
chgs2011 28.09.2014 um 19:22:59 Uhr
Goto Top
Das ärgert mich, bislang konnte man eine schicke Lösung ausarbeiten, jetzt klemmt es wieder an der SQL-DB Schnittstelle face-sad

Ich habe auch versucht in verschiedenen Foren Infos zu derartigen Problemen zu finden, fand aber leider noch nichts konkretes.

Beim SQL-Query kann man mit Hilfe von Parametern den Befehl steuern, schau dir dazu mal "-Q" und "-q" an, evtl. liegt darin das Problem?
Habe diesen Parameter auch mal verändert, aber Abhilfe brachte es nicht.
rubberman
rubberman 28.09.2014 aktualisiert um 19:58:27 Uhr
Goto Top
schau dir dazu mal "-Q" und "-q" an
Jo, hab ich schon. Wenn ich es richtig verstehe, dann sollte -Q schon OK sein. Das Query wird abgearbeitet und anschließend erfolgt die Abmeldung von der Datenbank.
Leider kann ich den ganzen Spaß nicht selbst testen...

Welchen Datentyp hast du cIdentCode und cLieferscheinNr zugeordnet?

Grüße
rubberman
chgs2011
chgs2011 28.09.2014 um 20:49:53 Uhr
Goto Top
Super, ja so war auch meine Auffassung.

Die Datentypen habe ich nicht vorgegeben, diese sind vom System definiert und kann/sollte ich nicht ändern.
Zum verständnis, in der Tabelle "tVersand" wird "cIdentCode" aktualisiert, "cLieferscheinNr" dient nur zur Auftrags-/Lieferscheinzuordnung.

cIdentCode = varchar(255)
cLieferscheinNr = varchar(50)
rubberman
rubberman 28.09.2014 um 21:04:34 Uhr
Goto Top
Hmm, mit dem varchar Typ sollte es auch kein Problem geben, soweit ich das beurteilen kann.

Vielleicht mal 'ne andere Richtung einschlagen. Wie müsste denn ein SQL Script beispielhaft aussehen, um alle (oder erst mal nur 2) Queries mit einem Aufruf von SQLCMD abzuarbeiten? Schließlich ist es kein Problem Textdateien per Batch zu erstellen und zu erweitern ...
msdn.microsoft.com/de-de/library/ms170572.aspx

Grüße
rubberman
chgs2011
chgs2011 30.09.2014 um 23:58:44 Uhr
Goto Top
Diese Idee klingt gut!

Ich denke ich versuche zunächst die TXT per Batch zu bereinigen, um alle Werte für Spalte 1+2 sauber zeilweise zu filtern.

Anschließend aktualisiere ich die SQL-DB mit diesem TXT, lasse dazu zeilenweise die Werte anziehen.

Ich versuche mal dahingehend mein Glück.
rubberman
rubberman 01.10.2014 um 00:15:17 Uhr
Goto Top
Ich bin dir bei der Umsetzung schon behilflich. Da ich aber nicht selbst testen kann, müsstest du mir beispielhaft mal ein SQL Script vorkauen, das bei dir funktioniert. Also händisch in den Editor geschrieben für ein oder 2 Datensätze ...

Grüße
rubberman
chgs2011
chgs2011 03.10.2014 um 10:21:42 Uhr
Goto Top
Ich konnte nun das Problem endlich lösen!

Zunächst verarbeite und formatiere ich mein Datenfile in eine saubere 2 Spalten-Struktur, mit Hilfe von deinem Script! SUPER!

@echo off & setlocal

cls
color 1e
mode con lines=20 cols=55

IF EXIST "\\hauptserver\MSSQL\DATA\sendungsdatenimport.csv" del /F "\\hauptserver\MSSQL\DATA\sendungsdatenimport.csv"  

cls
ECHO.
ECHO.
ECHO. ####################################################
ECHO. ####################################################
ECHO.
ECHO.
ECHO.
ECHO.                      ACHTUNG
ECHO.
ECHO.   DHL-Sendungsdatenimport laeuft, bitte warten ...
ECHO.
ECHO.
ECHO.
ECHO. ####################################################
ECHO. ####################################################
ECHO.
ECHO.

set "file=\\office\dhl\OUT\out.txt"  
set /a "n1 = 2, n2 = 23"  

setlocal EnableDelayedExpansion
<"!file!" (  
  for /f %%i in ('type "!file!"^|find /c /v ""') do for /l %%j in (1 1 %%i) do (  
    set "line=" &set /p "line="  
    set /a "c=0"  
    for %%k in ("!line:;=" "!") do (  
      set /a "c += 1"  
      if !c!==!n1! (
        endlocal
        set "c=%n1%"  
        set "var1=%%~k"  
        setlocal EnableDelayedExpansion
      )
      if !c!==!n2! (
        endlocal
        set "c=%n2%"  
        set "var2=%%~k"  
        setlocal EnableDelayedExpansion        
      )
    )
    call :ProcessItems
  )
)
endlocal

exit /b

:ProcessItems
ECHO !VAR1!;!VAR2!>>"\\hauptserver\MSSQL\DATA\sendungsdatenimport.csv"  

cls
ECHO.
ECHO.
ECHO. ####################################################
ECHO. ####################################################
ECHO.
ECHO.
ECHO.
ECHO.                      ACHTUNG    
ECHO.
ECHO.   DHL-Sendungsdatenimport laeuft, bitte warten ...
ECHO.
ECHO.
ECHO.
ECHO. ####################################################
ECHO. ####################################################
ECHO.
ECHO.

exit /b



Per Batch triggere ich oben zunächst deine Formatierung an, anschließend führe ich den SQL-Query unten aus:

USE eazybusiness
GO

CREATE TABLE DHL_SENDUNGSDATENIMPORT
(TRACKINGID VARCHAR(20),
LIEFERSCHEINNUMMER VARCHAR(20))
GO

BULK
INSERT DHL_SENDUNGSDATENIMPORT
FROM '\\hauptserver\MSSQL\DATA\sendungsdatenimport.csv'  
WITH
(
FIELDTERMINATOR = ';',  
ROWTERMINATOR = '\n'  
)
GO

UPDATE	tVersand
SET		cIdentCode = DHL_SENDUNGSDATENIMPORT.TRACKINGID
FROM	tVersand INNER JOIN
		tLieferschein ON tVersand.kLieferschein = tLieferschein.kLieferschein CROSS JOIN
        DHL_SENDUNGSDATENIMPORT
WHERE	(tVersand.kLieferschein = tVersand.kLieferschein) AND (tLieferschein.cLieferscheinNr = DHL_SENDUNGSDATENIMPORT.LIEFERSCHEINNUMMER)
GO

DROP TABLE DHL_SENDUNGSDATENIMPORT
GO


Dieser sogenannte SQL-Bulk import kreiert eine temporäre Tabelle mit Daten, die dann verarbeitet / aktualisiert werden, danach wird die Tabelle wieder gekillt!

Wichtig ist nur, dass UAC ausgeschalten ist, zudem das formatierte File direkt auf dem Server abgelegt wird, da es sonst grundsätzlich zu Berechtigungsproblemen gibt.
rubberman
rubberman 03.10.2014 um 10:55:59 Uhr
Goto Top
Huch, doch so aufwendig face-plain

Ich hatte ursprünglich an etwas in der Art gedacht:
- den Anfang der SQL Datei im Hauptcode erstellen
z.B.
>"\\Server\Share\Import.sql" (  
  echo USE eazybusiness
  echo GO
  echo CREATE TABLE DHL_SENDUNGSDATENIMPORT
  echo (TRACKINGID VARCHAR(20^),
  echo LIEFERSCHEINNUMMER VARCHAR(20^)^)
  echo GO
)
- dann weitere Statements zum erstellen der Daten aus der Subroutine heraus anhängen (unter Verwendung der Variablen VAR1 und VAR2) á la
>>"\\Server\Share\Import.sql" echo foo !VAR1! bar !VAR2!;  
>>"\\Server\Share\Import.sql" echo GO  
... wobei ich nicht weiß wie die erste Zeile auszusehen hat ...

- evtl. noch weitere Anweisungen per >> unten anhängen.

- das Script per sqlcmd ausführen.

Auf diese Art hättest du das in einem Rutsch durch.


Grüße
rubberman
chgs2011
chgs2011 03.10.2014 um 11:11:10 Uhr
Goto Top
Danke für den Vorschlag.

Ich habe es bewusst so gemacht, damit man zumindest sieht was zuletzt importiert wurde an Daten.
Dort habe ich eine schöne Auflistung dann, auch zur Kontrolle.

So kann ich die 2 Programmteile getrennt voneinander betrachten und analysieren.

Soweit alles gut, läuft!