Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit

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

Frage Entwicklung Batch & Shell

Mitglied: chgs2011

chgs2011 (Level 1) - Jetzt verbinden

24.09.2014 um 14:48 Uhr, 1456 Aufrufe, 25 Kommentare, 2 Danke

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.


01.
@ECHO ON 
02.
CLS 
03.
COLOR 1e 
04.
 
05.
FOR /F "eol=# tokens=3,5 delims=;" %%1 IN ("test.csv") DO echo %%1 %%2 
06.
 
07.
PAUSE 
08.
 
09.
:setit 
10.
set var1=%~1 
11.
set var2=%~2 
12.
 
13.
echo %var1% %var2% 
14.
 
15.
PAUSE
Mitglied: Friemler
24.09.2014, aktualisiert um 16:41 Uhr
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:
01.
@echo off & setlocal 
02.
 
03.
cls 
04.
color 1e 
05.
 
06.
for /f "usebackq eol=# tokens=3,5 delims=;" %%a in ("test.csv") do ( 
07.
  call :ProcessItems "%%a" "%%b" 
08.
09.
 
10.
exit /b 
11.
 
12.
 
13.
:ProcessItems 
14.
  set "Var1=%~1" 
15.
  set "Var2=%~2" 
16.
 
17.
  echo %Var1% 
18.
  echo %Var2% 
19.
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
Bitte warten ..
Mitglied: chgs2011
24.09.2014 um 20:09 Uhr
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):
01.
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.
Bitte warten ..
Mitglied: Friemler
24.09.2014, aktualisiert um 23:34 Uhr
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
Bitte warten ..
Mitglied: chgs2011
25.09.2014 um 00:12 Uhr
Hey,

sooo ein Käse

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.
Bitte warten ..
Mitglied: rubberman
25.09.2014 um 00:28 Uhr
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.
01.
@echo off &setlocal 
02.
set "file=test.csv" 
03.
set /a "n1 = 2, n2 = 18" 
04.
 
05.
setlocal EnableDelayedExpansion 
06.
<"!file!" ( 
07.
  for /f %%i in ('type "!file!"^|find /c /v ""') do for /l %%j in (1 1 %%i) do ( 
08.
    set "line=" &set /p "line=" 
09.
    set /a "c=0" 
10.
    for %%k in ("!line:;=" "!") do ( 
11.
      set /a "c += 1" 
12.
      if !c!==!n1! ( 
13.
        endlocal 
14.
        set "c=%n1%" 
15.
        set "var1=%%~k" 
16.
        setlocal EnableDelayedExpansion 
17.
18.
      if !c!==!n2! ( 
19.
        endlocal 
20.
        set "c=%n2%" 
21.
        set "var2=%%~k" 
22.
        setlocal EnableDelayedExpansion         
23.
24.
25.
    call :ProcessItems 
26.
27.
28.
endlocal 
29.
pause 
30.
exit /b 
31.
 
32.
:ProcessItems 
33.
echo !var1! 
34.
echo !var2! 
35.
exit /b
Grüße
rubberman
Bitte warten ..
Mitglied: chgs2011
27.09.2014 um 11:59 Uhr
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:

01.
@echo off & setlocal 
02.
 
03.
cls 
04.
color 1e 
05.
mode con lines=20 cols=55 
06.
 
07.
ECHO. 
08.
ECHO. 
09.
ECHO. #################################################### 
10.
ECHO. #################################################### 
11.
ECHO. 
12.
ECHO. 
13.
ECHO. 
14.
ECHO.                      ACHTUNG 
15.
ECHO. 
16.
ECHO.   DHL-Sendungsdatenimport laeuft, bitte warten ... 
17.
ECHO. 
18.
ECHO. 
19.
ECHO. 
20.
ECHO. #################################################### 
21.
ECHO. #################################################### 
22.
ECHO. 
23.
ECHO. 
24.
 
25.
set "file=\\chgs-office\DHL\OUT\out.txt" 
26.
set /a "n1 = 2, n2 = 23" 
27.
 
28.
setlocal EnableDelayedExpansion 
29.
<"!file!" ( 
30.
  for /f %%i in ('type "!file!"^|find /c /v ""') do for /l %%j in (1 1 %%i) do ( 
31.
    set "line=" &set /p "line=" 
32.
    set /a "c=0" 
33.
    for %%k in ("!line:;=" "!") do ( 
34.
      set /a "c += 1" 
35.
      if !c!==!n1! ( 
36.
        endlocal 
37.
        set "c=%n1%" 
38.
        set "var1=%%~k" 
39.
        setlocal EnableDelayedExpansion 
40.
41.
      if !c!==!n2! ( 
42.
        endlocal 
43.
        set "c=%n2%" 
44.
        set "var2=%%~k" 
45.
        setlocal EnableDelayedExpansion         
46.
47.
48.
    call :ProcessItems 
49.
50.
51.
endlocal 
52.
 
53.
exit /b 
54.
 
55.
:ProcessItems 
56.
"\\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%')" 
57.
 
58.
CLS 
59.
ECHO. 
60.
ECHO. 
61.
ECHO. #################################################### 
62.
ECHO. #################################################### 
63.
ECHO. 
64.
ECHO. 
65.
ECHO. 
66.
ECHO.                      ACHTUNG     
67.
ECHO. 
68.
ECHO.   DHL-Sendungsdatenimport laeuft, bitte warten ... 
69.
ECHO. 
70.
ECHO. 
71.
ECHO. 
72.
ECHO. #################################################### 
73.
ECHO. #################################################### 
74.
ECHO. 
75.
ECHO. 
76.
 
77.
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.
Bitte warten ..
Mitglied: rubberman
27.09.2014 um 14:17 Uhr
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
Bitte warten ..
Mitglied: chgs2011
27.09.2014 um 15:07 Uhr
Ja klar Batch

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.

Bitte warten ..
Mitglied: rubberman
27.09.2014 um 15:39 Uhr
Ja klar Batch
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
Bitte warten ..
Mitglied: Friemler
27.09.2014, aktualisiert um 17:05 Uhr
Hi,

sooo ein Käse
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
Bitte warten ..
Mitglied: chgs2011
27.09.2014 um 17:26 Uhr
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..."


01.
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 
02.
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 
03.
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 
04.
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 
05.
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 
06.
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 
07.
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 
08.
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 
09.
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 
10.
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 
11.
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
Bitte warten ..
Mitglied: rubberman
27.09.2014 um 20:14 Uhr
Hast du mal versucht einfach 2 Beispielaufrufe für SQLCMD hintereinander zu setzen? Á la
01.
@echo off &setlocal 
02.
"\\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')" 
03.
"\\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')" 
04.
pause
Und (wenn die MSDN Referenz richtig ist) ist es nicht so, dass ein Query eigentlich mit einem Semikolon abgeschlossen wird?

Grüße
rubberman
Bitte warten ..
Mitglied: chgs2011
27.09.2014 um 21:56 Uhr
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.
Bitte warten ..
Mitglied: rubberman
27.09.2014, aktualisiert um 22:21 Uhr
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
Bitte warten ..
Mitglied: chgs2011
27.09.2014 um 23:46 Uhr
Habe es mit einer Wartezeit mal versucht ...
01.
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):
01.
432784037772;AB-1409-29381-001; 
02.
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 ...


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.
Bitte warten ..
Mitglied: rubberman
28.09.2014 um 00:25 Uhr
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
Bitte warten ..
Mitglied: chgs2011
28.09.2014 um 19:22 Uhr
Das ärgert mich, bislang konnte man eine schicke Lösung ausarbeiten, jetzt klemmt es wieder an der SQL-DB Schnittstelle

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.
Bitte warten ..
Mitglied: rubberman
28.09.2014, aktualisiert um 19:58 Uhr
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
Bitte warten ..
Mitglied: chgs2011
28.09.2014 um 20:49 Uhr
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)
Bitte warten ..
Mitglied: rubberman
28.09.2014 um 21:04 Uhr
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
Bitte warten ..
Mitglied: chgs2011
30.09.2014 um 23:58 Uhr
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.
Bitte warten ..
Mitglied: rubberman
01.10.2014 um 00:15 Uhr
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
Bitte warten ..
Mitglied: chgs2011
03.10.2014 um 10:21 Uhr
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!

01.
@echo off & setlocal 
02.
 
03.
cls 
04.
color 1e 
05.
mode con lines=20 cols=55 
06.
 
07.
IF EXIST "\\hauptserver\MSSQL\DATA\sendungsdatenimport.csv" del /F "\\hauptserver\MSSQL\DATA\sendungsdatenimport.csv" 
08.
 
09.
cls 
10.
ECHO. 
11.
ECHO. 
12.
ECHO. #################################################### 
13.
ECHO. #################################################### 
14.
ECHO. 
15.
ECHO. 
16.
ECHO. 
17.
ECHO.                      ACHTUNG 
18.
ECHO. 
19.
ECHO.   DHL-Sendungsdatenimport laeuft, bitte warten ... 
20.
ECHO. 
21.
ECHO. 
22.
ECHO. 
23.
ECHO. #################################################### 
24.
ECHO. #################################################### 
25.
ECHO. 
26.
ECHO. 
27.
 
28.
set "file=\\office\dhl\OUT\out.txt" 
29.
set /a "n1 = 2, n2 = 23" 
30.
 
31.
setlocal EnableDelayedExpansion 
32.
<"!file!" ( 
33.
  for /f %%i in ('type "!file!"^|find /c /v ""') do for /l %%j in (1 1 %%i) do ( 
34.
    set "line=" &set /p "line=" 
35.
    set /a "c=0" 
36.
    for %%k in ("!line:;=" "!") do ( 
37.
      set /a "c += 1" 
38.
      if !c!==!n1! ( 
39.
        endlocal 
40.
        set "c=%n1%" 
41.
        set "var1=%%~k" 
42.
        setlocal EnableDelayedExpansion 
43.
44.
      if !c!==!n2! ( 
45.
        endlocal 
46.
        set "c=%n2%" 
47.
        set "var2=%%~k" 
48.
        setlocal EnableDelayedExpansion         
49.
50.
51.
    call :ProcessItems 
52.
53.
54.
endlocal 
55.
 
56.
exit /b 
57.
 
58.
:ProcessItems 
59.
ECHO !VAR1!;!VAR2!>>"\\hauptserver\MSSQL\DATA\sendungsdatenimport.csv" 
60.
 
61.
cls 
62.
ECHO. 
63.
ECHO. 
64.
ECHO. #################################################### 
65.
ECHO. #################################################### 
66.
ECHO. 
67.
ECHO. 
68.
ECHO. 
69.
ECHO.                      ACHTUNG     
70.
ECHO. 
71.
ECHO.   DHL-Sendungsdatenimport laeuft, bitte warten ... 
72.
ECHO. 
73.
ECHO. 
74.
ECHO. 
75.
ECHO. #################################################### 
76.
ECHO. #################################################### 
77.
ECHO. 
78.
ECHO. 
79.
 
80.
exit /b


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

01.
USE eazybusiness 
02.
GO 
03.
 
04.
CREATE TABLE DHL_SENDUNGSDATENIMPORT 
05.
(TRACKINGID VARCHAR(20), 
06.
LIEFERSCHEINNUMMER VARCHAR(20)) 
07.
GO 
08.
 
09.
BULK 
10.
INSERT DHL_SENDUNGSDATENIMPORT 
11.
FROM '\\hauptserver\MSSQL\DATA\sendungsdatenimport.csv' 
12.
WITH 
13.
14.
FIELDTERMINATOR = ';', 
15.
ROWTERMINATOR = '\n' 
16.
17.
GO 
18.
 
19.
UPDATE	tVersand 
20.
SET		cIdentCode = DHL_SENDUNGSDATENIMPORT.TRACKINGID 
21.
FROM	tVersand INNER JOIN 
22.
		tLieferschein ON tVersand.kLieferschein = tLieferschein.kLieferschein CROSS JOIN 
23.
        DHL_SENDUNGSDATENIMPORT 
24.
WHERE	(tVersand.kLieferschein = tVersand.kLieferschein) AND (tLieferschein.cLieferscheinNr = DHL_SENDUNGSDATENIMPORT.LIEFERSCHEINNUMMER) 
25.
GO 
26.
 
27.
DROP TABLE DHL_SENDUNGSDATENIMPORT 
28.
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.
Bitte warten ..
Mitglied: rubberman
03.10.2014 um 10:55 Uhr
Huch, doch so aufwendig

Ich hatte ursprünglich an etwas in der Art gedacht:
- den Anfang der SQL Datei im Hauptcode erstellen
z.B.
01.
>"\\Server\Share\Import.sql" ( 
02.
  echo USE eazybusiness 
03.
  echo GO 
04.
  echo CREATE TABLE DHL_SENDUNGSDATENIMPORT 
05.
  echo (TRACKINGID VARCHAR(20^), 
06.
  echo LIEFERSCHEINNUMMER VARCHAR(20^)^) 
07.
  echo GO 
08.
)
- dann weitere Statements zum erstellen der Daten aus der Subroutine heraus anhängen (unter Verwendung der Variablen VAR1 und VAR2) á la
01.
>>"\\Server\Share\Import.sql" echo foo !VAR1! bar !VAR2!; 
02.
>>"\\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
Bitte warten ..
Mitglied: chgs2011
03.10.2014 um 11:11 Uhr
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!
Bitte warten ..
Neuester Wissensbeitrag
Humor (lol)

Linkliste für Adventskalender

(3)

Information von nikoatit zum Thema Humor (lol) ...

Ähnliche Inhalte
Batch & Shell
gelöst Batch Variable setzten mit Leerzeichen (3)

Frage von Marlon1 zum Thema Batch & Shell ...

Batch & Shell
Batch: Variable Expansion in einer FOR-Schleife (9)

Frage von .Sessl zum Thema Batch & Shell ...

Batch & Shell
gelöst In Batch variable DOS-Funktion von "größer" und "kleiner" Zeichen unterdrücken (3)

Frage von Markus5579 zum Thema Batch & Shell ...

Batch & Shell
gelöst Batch Variable auf 5 Zeichen begrenzen (5)

Frage von PinkFLuffyUnicorn zum Thema Batch & Shell ...

Heiß diskutierte Inhalte
Windows Server
DHCP Server switchen (24)

Frage von M.Marz zum Thema Windows Server ...

SAN, NAS, DAS
gelöst HP-Proliant Microserver Betriebssystem (14)

Frage von Yannosch zum Thema SAN, NAS, DAS ...

Grafikkarten & Monitore
Win 10 Grafikkarte Crash von Software? (13)

Frage von Marabunta zum Thema Grafikkarten & Monitore ...