我正在尝试开发一个脚本,按照RFC 4180定期导出格式正确的CSV文件。我正在使用PowerShell脚本来调用Sqlcmd。但是,输出似乎会更改数据库中某些值的大小写。例如,uniqueidentifier值从完全大写更改为
92adbee2-ADBF-de11-90b0-005056b325c4
我正在运行以输出到powershell终端的脚本如下所示。
Invoke-Sqlcmd -Query "SELECT top 10 * FROM
dbo.Account;" `
-Database db_name `
-Server server-name `
-QueryTimeout 65535
有没有办法阻止此工具更改uniqueidentifier类型值的大小写?
由于
答案 0 :(得分:0)
在Powershell中使用: $ SQL_Command =" sqlcmd -S $ DbServer -U $ SQL_User -P $ SQL_Pass -i $ TSQL_File -o $ CSV_OutPut_FileName -s',' -w 65530"
Invoke-Expression $ SQL_Command
第一个变量($ SQL_Command)存储sqlcmd命令 Invoke-Expression cmdlet评估或运行指定的字符串作为命令
$ TSQL_File变量是包含sql语句的文件名(例如:SELECT GUID FROM TableName ....在sql server中的uniqueidentifier数据类型或者你可以使用SELECT * FROM TableName)
输出不会改变SQL Server中uniqueidentifier数据类型的情况...希望这个帮助。
sqlcmd的语法
-a packet_size
-A(专用管理员连接)
-b(如果有错误则终止批处理作业)
-c batch_terminator
-C(信任服务器证书)
-d db_name
-e(回声输入)
-E(使用可信连接)
-f codepage | i:代码页[,o:代码页] | ○:代码页[,I:代码页]
-g(启用列加密)
-G(使用Azure Active Directory进行身份验证)
-h rows_per_header
-H workstation_name
-i input_file
-I(启用带引号的标识符)
-j(打印原始错误消息)
-k [1 | 2](删除或替换控制字符)
-K application_intent
-l login_timeout
-L [c](列出服务器,可选清洁输出)
-m error_level
-M multisubnet_failover
-N(加密连接)
-o output_file
-p [1](打印统计,可选冒号格式)
-P密码
-q" cmdline查询"
-Q" cmdline查询" (并退出)
-r [0 | 1](msgs to stderr)
-R(使用客户区域设置)
-s col_separator
-S [protocol:] server [instance_name] [,port]
-t query_timeout
-u(unicode输出文件)
-U login_id
-v var ="值"
-V error_severity_level
-w column_width
-W(删除尾随空格)
-x(禁用变量替换)
-X [1](禁用命令,启动脚本,环境变量,可选退出)
-y variable_length_type_display_width
-Y fixed_length_type_display_width
-z new_password
-Z new_password(并退出)
- ? (用法)
答案 1 :(得分:0)
正如一些评论指出uniqueidentifier实际上是二进制值,xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx只是二进制值的许多不同视觉表示之一。
在SQL Server Management Studio中,查询结果窗口使用带有大写十六进制数字的xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx布局格式化唯一标识符。
SQL Server中的uniqueidentifier类型映射到PowerShell中的Guid类型(即.Net)。默认的.Net Guid.ToString方法也使用xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx布局,但使用小写十六进制数字。
如果您可以在PowerShell中覆盖Guid.ToString方法,那么您可以更改使用的格式,但是您无法执行此操作。如果您已经有一个自定义表格式化程序来处理RFC 4180特殊情况(引号,值中的分隔符等),那么您可以在其中添加Guid格式。
答案 2 :(得分:0)
#----------------------------------------------------------------------------------------------------------
#--- Each line of TSQL_FileName.TXT ($ScriptsArray) contains a file name ($TSQL_File) of the TSQL statement that need to be execute
#----------------------------------------------------------------------------------------------------------
FOREACH ($TSQL_File in $ScriptsArray)
{ $Num_TSQL_File++
$Result_MSG = ''
#----------------------------------------------------------------------------------------------------------
#--- GENERATE OUT PUT FILE NAME USE FOR CSV FILE WHEN WE RUN sqlcmd
#----------------------------------------------------------------------------------------------------------
$OutPut_File = (Get-Item $TSQL_File).Basename+'_'+$OutPut_DateTime
$OutPut_File = $OutPut_File.replace(' ','_')
$OutPut_File = $OutPut_File.replace('.','_')
$OutPut_File = $OutPut_File+'.CSV'
$OutPut_Error = ''
$SQL_Command = "sqlcmd -S $DbServer -U $SQL_User -P $SQL_Pass -i $TSQL_File -o $OutPut_File -s ',' -w 65530"
Invoke-Expression $SQL_Command
$OutPut_Array = Get-Content $OutPut_File
$ThirdLine = "|"+$OutPut_Array[3]+"|"
#----------------------------------------------------------------------------------------------------------
#--- Determine if an error had occured, if so send email notification
#----------------------------------------------------------------------------------------------------------
IF (($OutPut_Array -like "Error*") -or ($OutPut_Array -like "Msg*") -or ($OutPut_Array -like "Invalid*") -or ($OutPut_Array -like "Sqlcmd: Error*") )
{ $OutPut_Error = (Get-Item $TSQL_File).Basename+'_'+$OutPut_DateTime+'.ERR'
$OutPut_Array | out-file ".\$OutPut_Error"
$Result_MSG = 'Error!'
$OutPut_File = $OutPut_Error
$OutPut_FileSizeKb = $NumOfRow_Send = 0
$global:DbErr++
"{0,-16} {1,-40} {2,-60} {3,-10} {4,-4} {5,-4}" -f $DbServer, $TSQL_File, $OutPut_File, [int]$OutPut_FileSizeKb, $NumOfRow_Send, $Result_MSG
$Results_Array += ,@($Results_Array_Index, $DbServer, $TSQL_File, $OutPut_File, $OutPut_FileSizeKb, $NumOfRow_Send, $Result_MSG)
$Results_Array_Index++
}
ELSE
{ #----------------------------------------------------------------------------------------------------------
#--- Determine if zero row return from query, if so modify the array so that it will send only header info
#----------------------------------------------------------------------------------------------------------
IF ( ($OutPut_Array.Length -EQ 3) -and ($ThirdLine -EQ '||') )
{ $NeedFix_Array = Get-Content $OutPut_File
#-------------------------------------------------------------
#--- MODIFY THE ARRAY SO THAT IT WILL SEND ONLY THE HEADER
#-------------------------------------------------------------
$NeedFix_Array = $NeedFix_Array[1]
#-----------------------------------------------------------
#--- REMOVE BLANK SPACE FROM THE LINE
#-----------------------------------------------------------
$NeedFix_Array = $NeedFix_Array -replace '\s+', ' '
$NeedFix_Array = $NeedFix_Array -replace ' ,', ','
$NeedFix_Array = $NeedFix_Array -replace ', ', ','
#-----------------------------------------------------------
$NeedFix_Array | out-file $OutPut_File -Encoding ASCII
$OutPut_FileSizeKb = (Get-Item $OutPut_File).length/1KB
$OutPut_FileSizeKb = [int][Math]::Ceiling($OutPut_FileSizeKb)
$NumOfRow_Send = 1
$Num_CSV_File_Created++
"{0,-16} {1,-40} {2,-60} {3,-10} {4,-4} {5,-4}" -f $DbServer, $TSQL_File, $OutPut_File, [int]$OutPut_FileSizeKb, $NumOfRow_Send, $Result_MSG
$Results_Array += ,@($Results_Array_Index, $DbServer, $TSQL_File, $OutPut_File, $OutPut_FileSizeKb, $NumOfRow_Send, $Result_MSG)
$Results_Array_Index++
}
#----------------------------------------------------------------------------------------------------------
#--- REMOVE 1st LINE AND '-----' IN 3rd LINE AND FIX THE SPACES BETWEEN COMMA
#----------------------------------------------------------------------------------------------------------
ELSE
{ $NeedFix_Array = Get-Content $OutPut_File
#-------------------------------------------------------------
#--- REMOVE THE FIRST LINE
#-------------------------------------------------------------
$NeedFix_Array = $NeedFix_Array[1..($NeedFix_Array.Length-1)]
#-------------------------------------------------------------
#--- REMOVE THE SECOND LINE AFTER THE FIRST LINE WERE REMOVE
#-------------------------------------------------------------
$NeedFix_Array = $NeedFix_Array[0,0+2..($NeedFix_Array.length - 1)]
$NeedFix_Array = $NeedFix_Array[1..($NeedFix_Array.Length-1)]
#-----------------------------------------------------------
#--- REMOVE BLANK SPACE FROM THE LINE
#-----------------------------------------------------------
$NeedFix_Array = $NeedFix_Array -replace '\s+', ' '
$NeedFix_Array = $NeedFix_Array -replace ' ,', ','
$NeedFix_Array = $NeedFix_Array -replace ', ', ','
#-----------------------------------------------------------
$NeedFix_Array | out-file $OutPut_File -Encoding ASCII
$OutPut_FileSizeKb = (Get-Item $OutPut_File).length/1KB
$OutPut_FileSizeKb = [int][Math]::Ceiling($OutPut_FileSizeKb)
$NumOfRow_Send = $NeedFix_Array.Length
$Num_CSV_File_Created++
"{0,-16} {1,-40} {2,-60} {3,-10} {4,-4} {5,-4}" -f $DbServer, $TSQL_File, $OutPut_File, [int]$OutPut_FileSizeKb, $NumOfRow_Send, $Result_MSG
$Results_Array += ,@($Results_Array_Index, $DbServer, $TSQL_File, $OutPut_File, $OutPut_FileSizeKb, $NumOfRow_Send, $Result_MSG)
$Results_Array_Index++
}
}
}`enter code here`