Agradecemos tu apoyo para extender nuestras crónicas con relación a las ciencias informáticas.
Solución:
Una opción que podría considerar es separar los dos. Cree un archivo con su exportación y todos los campos. El otro archivo solo tiene su encabezado. El último paso sería combinar los dos con algo como esto:
REM create the header file
ECHO 100|0|SSO|UPDATE|EN|N|N| >"MyExport.txt.header"
REM append the bcp export to the header file
TYPE "MyExport.txt">>"MyExport.txt.header"
REM rename the header file back to the export file name
MOVE /y "MyExport.txt.header" "MyExport.txt"
Mencionaste que la exportación se hacía a diario. ¿Hay un programa de trabajo de SQL para hacer esto? Esto podría ser un paso agregado al trabajo usando el Sistema operativo (CmdExec) tipo. No tiene por qué ser un proceso “externo” si te entiendo bien. Todo el código se puede ingresar en el paso del trabajo.
Si no está familiarizado con él, la otra cosa que puede investigar es SQLCMD. La conclusión es que creo que tiene razón: lo que quiere probablemente no se pueda hacer usando bcp directamente en un solo paso.
Puede crear un script CMD para crear un archivo de fila de encabezado temporal, ejecutar BCP y luego agregar la salida de BCP al archivo de encabezado temporal. Esto se llamaría a través de xp_cmdshell
al igual que la llamada existente a BCP en su configuración actual.
Aquí está el script CMD, que nombré AddHeaderToExportFile.cmd. Toma dos parámetros:
- El nombre del archivo.
- La fila del encabezado. Si cambia, solo necesita actualizar el procedimiento almacenado.
Simplemente cree un nuevo archivo de texto en el Explorador de Windows, luego reemplace el nombre (incluida la extensión .txt) con AddHeaderToExportFile.cmd. Luego edita AddHeaderToExportFile.cmd y pegue el siguiente código y guárdelo.
AddHeaderToExportFile.cmd:
@ECHO OFF
SET TempHeaderRowFile="%TEMP%TempHeader.txt"
SET TempOutputFile="%TEMP%TempOutput.txt"
BCP "EXEC [MyDBServer].[MyDbName].dbo.ConcurEmployeeExport" queryout %TempOutputFile% -c -C 1252 -T -t "|"
ECHO %~2 > %TempHeaderRowFile%
REM Concatenate Header + BCP_Output -> @FileName
REM /V = Verifies that new files are written correctly.
REM /Y = Suppresses prompting to confirm you want to overwrite an existing destination file
REM /B = treat files as Binary (else you get an extraneous CHAR(26) at the end)
COPY /V /Y /B %TempHeaderRowFile% + %TempOutputFile% %1
REM Delete the temporary Header and BCP output files
IF EXIST %TempHeaderRowFile% DEL /Q %TempHeaderRowFile%
IF EXIST %TempOutputFile% DEL /Q %TempOutputFile%
Al adaptar su secuencia de comandos original para llamar a la nueva secuencia de comandos CMD, su nuevo SQL debería ser algo como:
Procedimiento almacenado:
--employee export
DECLARE @FileName NVARCHAR(500)
SET @FileName = N'\someFileServerPublicsomeFolderemployee_p06010603ace_305_202105_' +
REPLACE(REPLACE(REPLACE(
CONVERT(NVARCHAR(19), CONVERT(DATETIME, GETDATE(), 112), 126),
N'-', N''), N'T', N''), N':', N'') +
N'.txt';
DECLARE @Command NVARCHAR(4000),
@Header NVARCHAR(500);
SET @Header = N'100|0|SSO|UPDATE|EN|N|N|';
SET @Command = N'C:TEMPBCPAddHeaderToExportFile.cmd "' +
@FileName +
N'", "' +
REPLACE(@Header, N'|', N'^|') +
N'"';
EXEC xp_cmdshell @Command; --, NO_OUTPUT;
Opuede crear un archivo de texto para contener el valor de la fila del encabezado y luego omitir el script CMD por completo y usar varias llamadas para xp_cmdshell
para lograr lo mismo:
--employee export
DECLARE @FileName NVARCHAR(500),
@HeaderFile NVARCHAR(500);
SET @FileName = N'\someFileServerPublicsomeFolderemployee_p06010603ace_305_202105_' +
REPLACE(REPLACE(REPLACE(
CONVERT(NVARCHAR(19), CONVERT(DATETIME, GETDATE(), 112), 126),
N'-', N''), N'T', N''), N':', N'') +
N'.txt';
SET @HeaderFile = N'\someFileServerpublicsomeFolderheader.txt'; -- static header row
DECLARE @Command NVARCHAR(4000);
SET @Command = N'BCP "EXEC [MyDBServer].[MyDbName].dbo.ConcurEmployeeExport" queryout ' + @FileName + 'tmp -c -C 1252 -T -t "|"';
EXEC xp_cmdshell @Command; --, NO_OUTPUT;
SET @Command = N'COPY /V /Y /B ' + @HeaderFile + N' + ' + @FileName + N'tmp ' + @FileName;
EXEC xp_cmdshell @Command; --, NO_OUTPUT;
SET @Command = N'IF EXIST ' + @FileName + N'tmp DEL /Q ' + @FileName + N'tmp';
EXEC xp_cmdshell @Command; --, NO_OUTPUT;
Recuerda que tienes la capacidad de comentar tu experiencia si te fue de ayuda.