script - Cómo suprimir los guiones en SQLCMD
sqlcmd login (14)
¿Cómo puedo suprimir los guiones (------------) del conjunto de resultados de este comando 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>
¡Eso es!
¿Cómo puedo suprimir los guiones (------------) del conjunto de resultados de este comando sqlcmd:
¡Puede hacerlo todo de una manera simple en 1 comando , sin ningún script o manipulación de archivos!
sqlcmd -d AdventureWorks -s ";" -Q "SET NOCOUNT ON; SELECT top 5 FirstName, LastName FROM Person.Contact" |findstr /v /c:"---"
Añadir set nocount on;
para eliminar la línea (X rows affected)
. Agregue |findstr /v /c:"---"
para eliminar los subrayados. De esta manera obtienes una respuesta limpia, con solo:
FirstName ;LastName
Gustavo ;Achong
Catherine ;Abel
Kim ;Abercrombie
Humberto ;Acevedo
Pilar ;Ackerman
La siguiente línea:
findstr /R /C:"^[^-]*$" MyTableColumns.csv > MyTableHeader.csv
es muy peligroso ya que elimina todas las líneas que contienen un "-". Será mejor que eche un vistazo a findstr /? y usa algo como:
findstr /B /V /C:"-----" MyTableColumns.csv > MyTableHeader.csv
Lo único que se me ocurre es eliminar el encabezado con el interruptor -h -1
y agregar los nombres de columna como la primera fila a la consulta SQL:
SELECT ''FirstName'' as FirstName, ''LastName'' as LastName
UNION
SELECT top 5 FirstName, LastName FROM Person.Contact
Tenga en cuenta que si hay otros tipos de datos, entonces (var)char
, debe convertir el campo usando: CAST(MyColumnName AS varchar(32)) as MyColumnName
MichaelM tiene una solución decente, pero como señaló slingshot ... findstr podría ser más agresivo y eliminar las líneas de datos que contienen guiones. Otro enfoque sería llamar a sqlcommand para obtener el conjunto de datos y luego usar set / p para tomar la primera fila del archivo de salida y asignarla a una variable. A continuación, elimine el archivo de salida orignal. A continuación, haga eco de los encabezados a un nuevo archivo. Por último, canalice otro sqlcmd sin encabezado a ese archivo.
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
Además, Top 0 es una buena opción para crear un "archivo de solo encabezados", pero solo si está utilizando una declaración de selección. Si está llamando a un procedimiento almacenado, busque el uso de FMTONLY ON para capturar los encabezados solo desde el SP.
sqlcmd -S server -d database -E -Q "Set NOCOUNT ON; Set FMTONLY ON; exec myStoredProcedure" -W -o my_headers.csv -m-1
Una advertencia es que el FMTONLY ON no se puede usar contra los SP usando las tablas #temp. Esto se debe a que FMTONLY ON no ejecuta el SP. Sólo agarra metadatos. Pero si los nombres de columna provienen de tablas que no existen antes de la ejecución, entonces no puede obtener esos nombres de columna.
- Troy
No creo que haya ninguna opción disponible para lograrlo, me temo que tendrá que vivir con esos encabezados.
No vi toda esta información en un solo lugar y pensé que la siguiente persona que la busque podría apreciarla ...
use la opción -h -1
para eliminar los guiones (--------) de la salida y SET NOCOUNT ON
para eliminar las "filas afectadas". Esto es excelente si está creando un informe o un archivo CSV para que otro sistema lo procese.
Ejemplo:
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
En su script SQL:
SET NOCOUNT ON -- removes (rows affected from the output)
select ''your_column_1, your_column_2''
select * from your_table
No necesita utilizar una unión entre sus declaraciones seleccionadas para esto.
O tal vez post-procesar la salida a través de sed como:
sqlcmd ... | sed -e ''2d''
para borrar la segunda linea?
Puede obtener un Win32 sed desde http://gnuwin32.sourceforge.net/packages/sed.htm
Para deshacerme de los guiones, agrego algo de código a mis procedimientos almacenados que solo darán salida al encabezado de la columna. La extracción de datos utilizando SQLCMD
se realiza en 2 partes.
Primero llamo a mi procedimiento almacenado con un conjunto especial de parámetros. En mi caso, cuando llamo al SP con todos los NULL, significa que deseo tener el encabezado de la columna.
Luego llamo a SQLCMD
por segunda vez y agrego la salida al archivo que acabo de crear antes y ¡listo!
Cree un archivo CSV en blanco para contener el encabezado de la columna
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
Ahora agregue el resultado de salida del procedimiento almacenado
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
Note que el primer comando usa > y el segundo >> . Cuando use uno -> "Crear o sobrescribir" y dos -> "Agregar o crear".
- -h-1 elimina el encabezado generado por SQLCMD
- -W elimina los espacios finales.
- -w establece el ancho máximo de fila
- -s define separador de columnas
Si desea poner en cola los datos, puede configurar el siguiente interruptor:
CONFIGURAR LA CARACTERÍSTICA DESACTIVADA;
Si pudiera enviar primero a un archivo (usando la opción -o
) , otra opción de proceso posterior que usa powershell funcionaría al leer el contenido del archivo, mientras se salta la segunda línea, y se escribe de nuevo en sí mismo.
(Get-Content "file.txt" | Where {$_.ReadCount -ne 2}) | Set-Content "file.txt"
Si se envía a un archivo, intente lo siguiente después de la ejecución exitosa:
findstr /v /c:"---" sqloutput.dat > finaloutput.dat
Uso "---" ya que todas mis columnas tienen más de 3 caracteres y nunca tengo esa cadena en mis datos, pero también podría usar "-; -" para reducir aún más el riesgo o cualquier delimitador basado en sus datos en lugar de ";".
Tuve que hacer un montón de investigación porque ninguna de las respuestas aquí encaja exactamente con lo que estaba buscando. Así que voy a resumir con la esperanza de que ayudará a otros.
Para mí, la forma más fácil era usar sed
. Si bien esto ya se sugirió aquí, había una sintaxis incorrecta para ejecutar sqlcmd y sed al mismo tiempo. Si está usando Windows, como fue mi caso, diríjase a http://gnuwin32.sourceforge.net/packages/sed.htm para descargar sed
Mi orden final parecía algo así como:
SQLCMD -m 1 -S "userpc/SQLEXPRESS" -E -i "C:/someDirectory/sqlfile.sql" -W -s "," -o "C:/someDirectory/output.csv" && sed -i 2d "C:/someDirectory/output.csv"
Dónde
- -m 1
elimina la línea "Cambio de contexto de la base de datos a ..."
- &&
ejecuta el segundo comando si el primer comando se ejecuta con éxito
- sed -i 2d
borra la segunda línea que contiene los guiones y sobrescribe la salida de sed a la salida original
Tenga en cuenta que el nombre del archivo de salida sed
y la salida de sqlcmd
deben coincidir; de lo contrario, la salida de sqlcmd
no se sobrescribirá correctamente. No debe haber citas alrededor de 2d
en la declaración sed
como se responde anteriormente y está presente en su documentación o obtendrá un error.
¡Espero que esto ayude!
Usando solo sqlcmd y la línea de comando de Windows, sin procedimientos almacenados:
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
Para manejar datos con delimitadores dentro (por ejemplo, "Atlanta, GA"), deberá especificar los campos por separado (en lugar de usar "seleccionar *") y usar la función QUOTENAME en SQL Server.
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