我正在使用 PowerShell 运行自动创建 UTF8 文本文件的查询。其中一个要求是查询结果是固定宽度的,并且结果从第一个字符开始。我有某些包含满足固定宽度要求的货币的货币字段,但结果不是从第一个字符开始。我想弄清楚如何使用 PS 来 a) 确保结果是固定宽度和 b) 从列的第一个字符开始。
cast(coalesce(SLCDPM.FBAL, '') as char(20)) as [BALANCE],
结果不是从字段的字符 1 开始,而是 20 个字符长
然而这
cast(coalesce(SLCDPM.FBAL, '') as varchar(20)) as [BALANCE]
OR
LTRIM(cast(coalesce(SLCDPM.FBAL, '') as varchar(20))) as [BALANCE]
结果从字符 1 开始,但固定宽度不正确。
Invoke-Sqlcmd -ServerInstance "ESTSVRSTD\MSSQLP901" -Database "C1PROD" -Query "SELECT distinct
cast(coalesce(ARECEIVABLE.FCUSTNO, ' ') as char(20)) as [CUSTNO],
cast(coalesce(CUSTOMER.fcompany, ' ') as char(255)) as [COMPANY],
cast(coalesce(CUSTOMER.FMSTREET, ' ') as char(240)) as [ADDRESS1],
cast(coalesce(CUSTOMER.FCITY, ' ') as char(50)) as [CITY],
cast(coalesce(CUSTOMER.fstate, ' ') as char(50)) as [STATE],
cast(coalesce(CUSTOMER.FZIP, ' ') as char(20)) as [ZIP],
cast(coalesce(CUSTOMER.FCRLIMIT, ' ') as char(20)) as [CRD_LIMIT],
replace(convert(varchar, FDLPAYDATE,101),'/','') as [LASTPAY],
cast(coalesce(CUSTOMER.FBAL, '') as char(40)) as [BALANCE],
cast(coalesce(CUSTOMER.FNPAYAMT, '') as char(20)) as [LASTAMT],
cast(coalesce(CUSTOMER.FANN_SALES, '') as char(20)) as [YTDSALES],
cast(coalesce('EAST SERVICE', ' ') as char(20)) as [BUSINESSUNIT]
FROM
CUSTOMER
right JOIN
ARECEIVABLE ON
CUSTOMER.fcustno = ARECEIVABLE.fcustno
LEFT JOIN
shmast ON ARECEIVABLE.fsono = shmast.fcsono AND ARECEIVABLE.fcustno = shmast.fcnumber
where FBAL > ' '
AND CUSTOMER.fcountry = 'United States of America'
ORDER BY CUSTNO" | ConvertTo-Csv -NoTypeInformation -Delimiter "`t" |
Select-Object -Skip 1 |
% { $_ -replace "`t`"", '' -replace '[\r?\n]', " " } | % {$_ -replace '"',""} | Out-File ("\\ESTSVRSTD\D\ARCUSTOMER.txt") -Force -Encoding ascii
考虑到你想使用 Powershell 以固定宽度格式提取数据,你最好在 Powershell 中进行格式化。
由于我们没有示例数据、示例查询或预期结果,因此您需要将此示例用于您自己的用途。您可以使用创建所需的格式并将其分配给变量,如David Brabant 的answer 所示,然后将其放入文件中。
当你说“结果从第一个字符开始”我假设你的意思是你希望数据是无头的,因此
-HideTableHeaders
开关。
本例以
sys.databases
为例,演示所有列的宽度固定:
$format = @{Expression={$_.name};width=128}, @{Expression={$_.database_id};width=5}, @{Expression={$_.compatibility_level};width=5}, @{Expression={$_.collation_name};width=60}, @{Expression={$_.recovery_model};width=15}
Invoke-Sqlcmd -ServerInstance 'srv-sql2022-dev\sandbox' -TrustServerCertificate `
-Query "SELECT name, database_id, compatibility_level, collation_name, recovery_model FROM sys.databases" |
Format-Table $format -HideTableHeaders > db.txt
这对我来说有以下结果:
master 1 160 SQL_Latin1_General_CP1_CI_AS 3
tempdb 2 160 SQL_Latin1_General_CP1_CI_AS 3
model 3 160 SQL_Latin1_General_CP1_CI_AS 3
msdb 4 160 SQL_Latin1_General_CP1_CI_AS 3
Sandbox 5 160 Latin1_General_CI_AS 3
AdventureWorks2019 6 160 SQL_Latin1_General_CP1_CI_AS 3
AdventureWorksDW2019 7 160 SQL_Latin1_General_CP1_CI_AS 3
CaseSensitive 8 160 SQL_Latin1_General_CP1_CS_AS 3
OldDB 9 160 Latin1_General_CI_AS 3
PermissionsPOC 10 160 Latin1_General_CI_AS 3
SecurityTest 11 160 Latin1_General_CI_AS 3
SecurityTest2 12 160 Latin1_General_CI_AS 3
SillyTest 13 160 Latin1_General_CI_AS 3