Ответ 1
Я не думаю, что есть какой-либо вариант, доступный для этого - вам придется жить с этими заголовками, я боюсь.
Как я могу подавить дефисы (------------) из набора результатов этой команды sqlcmd
:
C:\temp>sqlcmd -d AdventureWorks -s ";"
-Q "SET NOCOUNT ON SELECT top 5 FirstName, LastName FROM Person.Contact;"
FirstName ;LastName
--------------------------------------------------;----------------------------
Gustavo ;Achong
Catherine ;Abel
Kim ;Abercrombie
Humberto ;Acevedo
Pilar ;Ackerman
C:\temp>
Я не думаю, что есть какой-либо вариант, доступный для этого - вам придется жить с этими заголовками, я боюсь.
Единственное, о чем я могу думать, это удалить заголовок с помощью переключателя -h -1
и добавить имена столбцов в качестве первой строки в SQL Query:
SELECT 'FirstName' as FirstName, 'LastName' as LastName
UNION
SELECT top 5 FirstName, LastName FROM Person.Contact
Обратите внимание, что если есть другие типы данных, тогда (var)char
, вам нужно преобразовать это поле, используя: CAST(MyColumnName AS varchar(32)) as MyColumnName
Использование только sqlcmd и командной строки Windows без хранимых процедур:
REM Get the column headers ("set nocount on" is necessary to suppress the rows affected message)
sqlcmd -S MyServer -Q "set nocount on;select top 0 * from MyDatabase.MySchema.MyTable" -o "MyTableColumns.csv" -s "," -W
REM Remove hyphen line
findstr /R /C:"^[^-]*$" MyTableColumns.csv > MyTableHeader.csv
REM Get data without headers
sqlcmd -S MyServer -Q "set nocount on;select * from MyDatabase.MySchema.MyTable" -o "MyTableData.csv" -h -1 -s "," -W
REM You can also use bcp for this step
REM bcp "select * from MyDatabase.MySchema.MyTable" queryout "MyTableData.csv" -c -t"," -r"\n" -S MyServer -T
REM Append header and data
type MyTableHeader.csv MyTableData.csv > MyTableDataWithHeader.csv
Чтобы обрабатывать данные с разделителями внутри (например, "Атланта, Джорджия" ), вам нужно будет указать поля отдельно (вместо использования "select *" ) и использовать функцию QUOTENAME в SQL Server.
Я не видел всю эту информацию в одном месте и думал, что следующий человек, который ее ищет, может это оценить...
используйте параметр -h -1
, чтобы удалить тире (--------) с выхода и SET NOCOUNT ON
, чтобы удалить "затронутые строки". Это здорово, если вы создаете отчет или файл CSV для обработки другой системы.
Пример:
SQLCMD -S 127.0.0.1\SQL_SERVER_Instance -d db_name -U db_login -P password -i your_script.sql -o your_output.csv -h -1
В вашем SQL script:
SET NOCOUNT ON -- removes (rows affected from the output)
select 'your_column_1, your_column_2'
select * from your_table
Вам не нужно использовать соединение между вашими утверждениями выбора.
Или, возможно, пост-обработать вывод через sed как:
sqlcmd ... | sed -e '2d'
чтобы удалить вторую строку?
Вы можете получить команду Win32 из http://gnuwin32.sourceforge.net/packages/sed.htm
Чтобы избавиться от дефисов, я добавляю код в мои хранимые процедуры, которые будут выводить только заголовок столбца. Извлечение данных с помощью SQLCMD
выполняется в 2 частях.
Сначала я вызываю свою хранимую процедуру со специальным набором параметров. В моем случае, когда я вызываю SP со всеми NULL, это означает, что я хочу иметь заголовок столбца.
Затем я вызываю SQLCMD
второй раз и добавляю вывод к файлу, который я только что создал до и voila!
Создайте пустой CSV файл для хранения заголовка столбца
sqlcmd -S server -d database -U username -P password -o "somefile.csv" -h-1
-Q "exec myStoredProcedure NULL, NULL" -W -w 2000 -s"," > sometextfile.csv
Теперь добавьте выходной результат из хранимой процедуры
sqlcmd -S server -d database -U username -P password -o "somefile.csv" -h-1
-Q "exec myStoredProcedure 2011, 10" -W -w 2000 -s"," >> sometextfile.csv
Обратите внимание первая команда использует , а вторая → . При использовании одного → "Создать или перезаписать" и два → "Добавить или создать".
Что это!
Как я могу подавить дефисы (------------) из набора результатов этой команды sqlcmd:
Вы можете сделать все это простым способом в 1 команде, без каких-либо script или манипуляций с файлами!
sqlcmd -d AdventureWorks -s ";" -Q "SET NOCOUNT ON; SELECT top 5 FirstName, LastName FROM Person.Contact" |findstr /v /c:"---"
Добавьте set nocount on;
, чтобы удалить строку (X rows affected)
.
Добавьте |findstr /v /c:"---"
, чтобы удалить подчеркивания.
Таким образом вы получите чистый ответ, только:
FirstName ;LastName
Gustavo ;Achong
Catherine ;Abel
Kim ;Abercrombie
Humberto ;Acevedo
Pilar ;Ackerman
если вы хотите вывести данные из системы, вы можете установить следующий переключатель:
SET UNDERLINE OFF,
Если вы могли сначала выполнить вывод в файл (с использованием опции -o
), другой вариант послепроцесса с использованием powershell будет работать, читая содержимое файла - при пропуске второй строки - и записывая его обратно в себя.
(Get-Content "file.txt" | Where {$_.ReadCount -ne 2}) | Set-Content "file.txt"
MichaelM имеет достойное решение, но, как показала рогатка, findstr может быть более агрессивным и удалять строки данных, содержащие дефисы. Другой подход заключался бы в вызове sqlcommand для получения набора данных, а затем с использованием set/p для захвата первой строки из выходного файла и назначения ее переменной. Затем удалите выходной файл orignal. Затем выделите заголовки для нового файла. И, наконец, подключите другой файл sqlcmd без заголовка к этому файлу.
sqlcmd -S server -d database -E -Q "exec myStoredProcedure" -W -o my_headers.csv -m-1
set /p headers=< my_headers.csv
del my_headers.csv
echo %headers% > my_data.csv
sqlcmd -S server -d database -E -Q "exec myStoredProcedure" -W -m-1 -h-1 >> my_data.csv
Также Top 0 - хороший выбор для создания "файла заголовков", но только если вы используете оператор select. Если вы вызываете хранимую процедуру, изучите использование FMTONLY ON, чтобы захватить заголовки только из SP.
sqlcmd -S server -d database -E -Q "Set NOCOUNT ON; Set FMTONLY ON; exec myStoredProcedure" -W -o my_headers.csv -m-1
Предостережение заключается в том, что FMTONLY ON нельзя использовать против SP, используя таблицы #temp. Это связано с тем, что FMTONLY ON не выполняет SP. Он захватывает только метаданные. Но если имена столбцов поступают из таблиц, которые не существуют перед выполнением, то вы не можете получить имена этих столбцов.
Public Sub HyphenDelete(strFilename1 As String, Hyphens As Integer)
Const FOR_READING = 1
Const FOR_WRITING = 2
strFileName = strFilename1
strCheckForString = Left("-------", Hyphens)
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objTS = objFS.OpenTextFile(strFileName, FOR_READING)
strContents = objTS.ReadAll
objTS.Close
arrLines = Split(strContents, vbNewLine)
Set objTS = objFS.OpenTextFile(strFileName, FOR_WRITING)
For Each strLine In arrLines
If Not (Left(UCase(LTrim(strLine)), Len(strCheckForString)) = strCheckForString) Then
objTS.WriteLine strLine
End If
Next
End Sub
Следующая строка:
findstr /R /C:"^[^-]*$" MyTableColumns.csv > MyTableHeader.csv
очень опасен, поскольку он удаляет все строки, содержащие "-". Вы лучше посмотрите на findstr/? и используйте что-то вроде:
findstr /B /V /C:"-----" MyTableColumns.csv > MyTableHeader.csv
Если при успешном выполнении выведите файл в файл, выполните следующие действия:
findstr /v /c:"---" sqloutput.dat > finaloutput.dat
Я использую "---", поскольку все мои столбцы имеют более 3 символов, и у меня никогда не было этой строки в моих данных, но вы также можете использовать "-; -", чтобы уменьшить риск или какой-либо разделитель на основе ваших данных в место ";".