Mogę dość łatwo zrzucić dane do pliku tekstowego, takiego jak:
sqlcmd -S myServer -d myDB -E -Q "select col1, col2, col3 from SomeTable"
-o "MyData.txt"
Jednak przejrzałem pliki pomocy dla, SQLCMD
ale nie widziałem opcji specjalnie dla CSV.
Czy istnieje sposób na zrzucenie danych z tabeli do pliku tekstowego CSV za pomocą SQLCMD
?
sql-server
file
csv
sqlcmd
Promień
źródło
źródło
Odpowiedzi:
Możesz uruchomić coś takiego:
-h-1
usuwa nagłówki nazw kolumn z wyniku-s","
ustawia separator kolumn na,-w 700
ustawia szerokość wiersza na 700 znaków (będzie to musiało być tak szerokie, jak najdłuższy wiersz, w przeciwnym razie zostanie zawinięte do następnej linii)źródło
'""' + col1 + '""' AS col1
, zawijając (podwojone) podwójne cudzysłowy lub po prostu wywołując procedurę składowaną.Za pomocą PowerShell można starannie rozwiązać problem, przesyłając Invoke-Sqlcmd do Export-Csv.
SQL Server 2016 zawiera moduł SqlServer , który zawiera polecenie
Invoke-Sqlcmd
cmdlet, które będziesz mieć nawet po zainstalowaniu programu SSMS 2016. Wcześniej SQL Server 2012 zawierał stary moduł SQLPS , który zmienił bieżący katalog na ten, wSQLSERVER:\
którym moduł był jako pierwszy używany (wśród innych błędów), więc w tym celu musisz zmienić#Requires
powyższy wiersz na:Aby dostosować przykład do SQL Server 2008 i 2008 R2, usuń
#Requires
całkowicie linię i użyj narzędzia sqlps.exe zamiast standardowego hosta PowerShell.Invoke-Sqlcmd jest odpowiednikiem programu PowerShell dla sqlcmd.exe. Zamiast tekstu generuje obiekty System.Data.DataRow .
-Query
Parametr działa jak-Q
parametr sqlcmd.exe. Przekaż mu zapytanie SQL opisujące dane, które chcesz wyeksportować.-Database
Parametr działa jak-d
parametr sqlcmd.exe. Podaj nazwę bazy danych zawierającej dane do wyeksportowania.-Server
Parametr działa jak-S
parametr sqlcmd.exe. Podaj nazwę serwera zawierającego dane do wyeksportowania.Export-CSV to polecenie cmdlet programu PowerShell, które serializuje obiekty ogólne do CSV. Jest dostarczany z PowerShell.
Ten
-NoTypeInformation
parametr pomija dodatkowe dane wyjściowe, które nie są częścią formatu CSV. Domyślnie cmdlet zapisuje nagłówek z informacjami o typie. Pozwala poznać typ obiektu podczas późniejszej deserializacjiImport-Csv
, ale myli narzędzia, które oczekują standardowego pliku CSV.-Path
Parametr działa jak-o
parametr sqlcmd.exe. Pełna ścieżka dla tej wartości jest najbezpieczniejsza, jeśli utkniesz przy użyciu starego modułu SQLPS .-Encoding
Parametr działa jak-f
lub-u
parametrów sqlcmd.exe. Domyślnie Export-Csv generuje tylko znaki ASCII i zastępuje wszystkie inne znakami zapytania. Zamiast tego użyj UTF8, aby zachować wszystkie znaki i zachować zgodność z większością innych narzędzi.Główną zaletą tego rozwiązania w porównaniu z programem sqlcmd.exe lub bcp.exe jest to, że nie trzeba hakować polecenia, aby wyświetlić prawidłowy plik CSV. Polecenie cmdlet Export-Csv obsługuje to wszystko za Ciebie.
Główną wadą jest to, że
Invoke-Sqlcmd
czyta cały zestaw wyników przed przekazaniem go w potoku. Upewnij się, że masz wystarczająco dużo pamięci na cały zestaw wyników, który chcesz wyeksportować.Może nie działać płynnie dla miliardów wierszy. Jeśli to jest problem, można spróbować innych narzędzi, lub toczyć własną wydajną wersję
Invoke-Sqlcmd
używając System.Data.SqlClient.SqlDataReader klasę.źródło
Ostatnia linia zawiera opcje specyficzne dla CSV.
-W
usuń końcowe spacje z każdego pojedynczego pola-s","
ustawia separator kolumn na przecinek (,)-w 999
ustawia szerokość wiersza na 999 znakówodpowiedź scottm jest bardzo zbliżona do tego, czego używam, ale uważam, że
-W
jest to naprawdę fajny dodatek: nie muszę przycinać białych znaków, gdy konsumuję plik CSV w innym miejscu.Zobacz także dokumentację MSDN sqlcmd . To
/?
zawstydza wyjście opcji.źródło
'""' + col1 + '""' AS col1
, zawijając (podwojone) podwójne cudzysłowy lub po prostu wywołaj procedurę składowaną.Czy to nie
bcp
było przeznaczone?Uruchom to z linii poleceń, aby sprawdzić składnię.
Na przykład:
Pamiętaj, że
bcp
nie można wyświetlać nagłówków kolumn.Zobacz: strona dokumentacji programu bcp Utility .
Przykład z powyższej strony:
źródło
bcp
nie zawiera nagłówka (nazw kolumn), ale jest ~ 10 razy szybszy niżsqlcmd
(z mojego doświadczenia). W przypadku naprawdę dużych zbiorów danych możesz użyć,bcp
aby pobrać dane i użyćsqlcmd
(wybierz górne 0 * z ...), aby uzyskać nagłówek, a następnie połączyć je.Uwaga dla każdego, kto chce to zrobić, ale ma również nagłówki kolumn, oto rozwiązanie, w którym użyłem pliku wsadowego:
Spowoduje to wyświetlenie początkowych wyników (w tym separatorów ----, ---- między nagłówkami i danymi) do pliku tymczasowego, a następnie usunięcie tej linii, odfiltrowując ją za pomocą funkcji findstr. Zwróć uwagę, że nie jest doskonały, ponieważ odfiltrowuje
-,-
- nie zadziała, jeśli w wyniku jest tylko jedna kolumna, a także odfiltruje prawidłowe wiersze zawierające ten ciąg.źródło
Ta odpowiedź opiera się na rozwiązaniu @ iain-Elder, które działa dobrze, z wyjątkiem przypadku dużej bazy danych (jak wskazano w jego rozwiązaniu). Cały stół musi zmieścić się w pamięci twojego systemu, a dla mnie nie było to możliwe. Podejrzewam, że najlepszym rozwiązaniem byłoby użycie System.Data.SqlClient.SqlDataReader i niestandardowego serializatora CSV ( zobacz tutaj przykład ) lub innego języka ze sterownikiem MS SQL i serializacją CSV. W duchu pierwotnego pytania, które prawdopodobnie szukało rozwiązania bez zależności, poniższy kod PowerShell zadziałał dla mnie. Jest bardzo powolny i nieefektywny, szczególnie w przypadku tworzenia instancji tablicy danych $ i wywoływania Export-Csv w trybie dopisywania dla każdej linii $ chunk_size.
źródło
Alternatywna opcja z BCP:
źródło
Zwykle
sqlcmd
zawierabcp
narzędzie (jako częśćmssql-tools
), które domyślnie eksportuje do CSV.Stosowanie:
Na przykład:
Aby zrzucić wszystkie tabele do odpowiednich plików CSV, oto skrypt Bash :
źródło
Powyższa odpowiedź prawie rozwiązała problem, ale nie tworzy poprawnie przeanalizowanego pliku CSV.
Oto moja wersja:
Ktoś, kto mówi, że
sqlcmd
jest przestarzały na korzyść jakiejś alternatywy PowerShell, zapomina, żesqlcmd
nie jest to tylko dla systemu Windows. Jestem na Linuksie (a na Windowsie i tak unikam PS).Powiedziawszy to wszystko, wydaje mi się
bcp
łatwiejsze.źródło
Z dwóch powodów powinieneś uruchomić moje rozwiązanie w CMD:
Nazwa użytkownika i hasło logowania są czasami niezbędne do wysłania zapytania do zdalnej instancji SQL Server
źródło
Możesz to zrobić w hackerski sposób. Ostrożnie wykorzystując
sqlcmd
hack. Jeśli dane zawierają podwójne cudzysłowy lub przecinki, napotkasz kłopoty.Możesz użyć prostego skryptu, aby zrobić to poprawnie:
Źródło: zapisywanie wyników SQL do CSV za pomocą VBScript .
źródło
sqlcmd
, po prostu stwierdziliśmy, żesqlcmd
nie jest to właściwe uniknięcie przecinka, przez co jest ledwo nadające się do użycia w przypadku poważnych wyników CSV.