niedziela, 2 października 2011

Zrzut danych z bazy do pliku tekstowego

Nieraz stajemy przed wyzwaniem jak sobie poradzić w przypadku braku jakiegoś narzędzia na naszym komputerze. Z doświadczenia wiem że w korporacjach komputery są dosyć rygorystycznie ograniczane pod kątem możliwości instalacji aplikacji, co może niestety dosyć utrudnić życie. Dlatego też trzeba często kombinować jak tu sobie poradzić w takiej ekstremalnej sytuacji. Dobrym przykładem moze być zrzut danych z bazy do pliku tekstowego. Do wielu baz danych są dostarczane odpowiednie narzędzia jak np. BCP.EXE albo SQLCMD.EXE do MSSQL-a. Problem w tym że trzeba te narzędzia zainstalować. Rozwiązaniem tego problemu może być prosty skrypt w VBS-e pobierający dane z bazy i zrzucający do pliku. Pozwoliłem sobie coś takiego napisać:

Dim aConn, sConn , aRs, sSQL 
Dim sPath
Dim oFld, sHeader, bHeader, sContent, sDelimiter
Dim sCharset
dim oArgs, oArg, sArg
dim oStdOut

Const adTypeText = 2
Const adSaveCreateOverWrite = 2

set oArgs=wscript.Arguments 
Set oStdOut = WScript.StdOut

sPath = ""
sCharset = "utf-8"
sDelimiter = ";"
bHeader = 0

For Each oArg In oArgs
 sArg = fGetParmName(oArg)
 select case sArg
  case "Sql", "S"
   sSQL = fGetParmValue(oArg)
  case "Path", "P"
   sPath = fGetParmValue(oArg)
  case "Conn", "C"
   sConn = fGetParmValue(oArg)
  case "Charset", "A"
   sCharset = fGetParmValue(oArg)
  case "Header" , "H"
   bHeader = fGetParmValue(oArg)
  case "Delimiter", "D" 
   sDelimiter = fGetParmValue(oArg)
 End Select
Next

On Error Resume Next
Err.Clear

Set aConn = CreateObject("ADODB.Connection")
aConn.Open sConn
If Err.Number <> 0 Then call sError

Set aRs = aConn.Execute(sSQL)
If Err.Number <> 0 Then call sError

aRs.MoveFirst
If Err.Number <> 0 Then call sError

if bHeader = "Yes" Then
 For Each oFld In aRs.Fields
  sHeader = sHeader & oFld.Name & sDelimiter
 Next
 sHeader = Left(sHeader, Len(sHeader) - 1) & Chr(13) & Chr(10)
End If

sContent = sHeader & aRs.GetString(, , sDelimiter)
If Err.Number <> 0 Then call sError

if sPath<> "" Then
 ExportToFile sPath, sContent
Else
 oStdOut.Write sContent
end if

aConn.Close
If Err.Number <> 0 Then call sError

set oStdOut = Nothing
Set aRs = Nothing
Set aConn = Nothing

function fGetParmName (sIn)
 fGetParmName= left(sIn, InStr(sIn,":") -1 )
 if left(fGetParmName,1) ="/" Then fGetParmName = mid(fGetParmName,2)
End Function

function fGetParmValue (sIn)
 fGetParmValue= mid(sIn, InStr(sIn,":") + 1 )
End Function

sub sError
 Wscript.Echo Err.Description
 On Error GoTo 0
 Err.Clear
 Wscript.Quit
End Sub

sub ExportToFile (sPath, sContent)
 Dim aStream 'As ADODB.Stream
 Set aStream = CreateObject("ADODB.Stream")
 With aStream
  .Open
  .Type = adTypeText
  .Charset = sCharset
  If Err.Number <> 0 Then call sError
  .Position = 0
  .WriteText sContent
  If Err.Number <> 0 Then call sError
  .SaveToFile sPath, adSaveCreateOverWrite
  If Err.Number <> 0 Then call sError   
 End With
 Set aStream = Nothing
End Sub

Skrypt ten można uruchomić w następujący sposób:

eksport.vbs /Sql:"SELECT * FROM dbo.v_struktura_akt" /Conn:"DRIVER=SQL Server Native Client 10.0;SERVER=MASZYNA;UID=username;Trusted_Connection=Yes;WSID=MASZYNA;DATABASE=baza_danych;LANGUAGE=polski;" /Path:"E:\Roboczy\wynik.csv"

dostępne są następujące parametry:

/SQL:"select * from tabela" - zapytanie które chcemy uruchomić
/Conn:"DRIVER=SQL Server....." - ciąg połączenia do bazy danych, zaletą tego rozwiązania jest to że możemy pobrać dane z praktycznie dowolnej bazy danych
/Path:"d:\katalog\plik.csv" - ścieżka do pliku w którym chcemy przechowywać wynik. W przypadku gdy nie podamy pliku wynik zostanie przekierowany do strumienia STDOUT
/Charset:"utf-8" - domyślny marametr strony kodowej w której zapiszemy plik. Standardowo jest utf-8, ale można zastosować dowolną stronę kodową obsługiwaną przez ADODB.Stream np. windows-1250
/Header:"Yes" - dodaje wiersz z nagłówkami
/Delimiter:";" - ustala znak podziału poszczególnych kolumn

Mała uwaga: jeżeli chcemy wyłączyć Banner w programie CSCRIPT

Microsoft (R) Windows Script Host Version 5.7
Copyright (C) Microsoft Corporation. All rights reserved.

Wykonajmy polecenie

cscript //NoLogo //S

Brak komentarzy:

Prześlij komentarz