Invoke-Sqlcmd更改uniqueidentifier的个案

时间:2017-06-22 14:44:28

标签: sql-server powershell sqlcmd invoke-sqlcmd

我正在尝试开发一个脚本,按照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类型值的大小写?

由于

3 个答案:

答案 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`