Invoke-Sqlcmd изменяет регистры уникального идентификатора
Я пытаюсь разработать сценарий для регулярного экспорта правильно отформатированных файлов CSV согласно RFC 4180. Я использую сценарий 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 ответа
#----------------------------------------------------------------------------------------------------------
#--- 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`
Как отмечают некоторые комментарии, уникальный идентификатор действительно является двоичным значением, ххххххх-хххх-хххх-хххх-ххххххххххх является лишь одним из множества различных визуальных представлений двоичного значения.
В SQL Server Management Studio окно результатов запроса форматирует уникальные идентификаторы, используя формат xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx с шестнадцатеричными цифрами в верхнем регистре.
Тип уникального идентификатора в SQL Server сопоставляется с типом Guid в PowerShell (например,.Net). Метод.Net Guid.ToString по умолчанию также использует макет xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, но с шестнадцатеричными строчными буквами.
Если бы вы могли переопределить метод Guid.ToString в PowerShell, вы могли бы изменить используемый формат, но вы не можете этого сделать. Если у вас уже есть специальный форматер таблиц для обработки особых случаев RFC 4180 (кавычки, разделители в значениях и т. Д.), Вы можете добавить туда форматирование Guid.
Используется в Powershell: $SQL_Command = "sqlcmd -S $DbServer -U $SQL_User -P $SQL_Pass -i $TSQL_File -o$CSV_OutPut_FileName -s ',' -w 65530"
Вызов-выражение $ SQL_Command
Первая переменная ($SQL_Command) store sqlcmd Команда Командлет Invoke-Expression оценивает или запускает указанную строку как команду
Переменная $ TSQL_File - это имя файла, содержащее операторы SQL (пример: SELECT GUID FROM TableName.... тип данных uniqueidentifier на сервере SQL или вы можете использовать SELECT * FROM TableName)
Вывод не изменит случаи типа данных uniqueidentifier в SQL Server... Надеюсь, это поможет.
Синтаксис для sqlcmd
-a package_size
-A (выделенное соединение администратора)
-b (прервать пакетное задание в случае ошибки)
-c batch_terminator
-C (доверять сертификату сервера)
-d db_name
-e (эхо-вход)
-E (использовать доверенное соединение)
-f кодовая страница | i: кодовая страница [,o: кодовая страница] | o: кодовая страница [,i: кодовая страница]
-g (включить шифрование столбцов)
-G (использовать Azure Active Directory для проверки подлинности)
-h row_per_header
-H рабочая станция_имя
-i входной_файл
-I (включить идентификаторы в кавычках)
-j (выводить сообщения об ошибках)
-k[1 | 2] (удалить или заменить управляющие символы)
-K application_intent
-l login_timeout
-L [c] (список серверов, необязательный чистый вывод)
-m error_level
-M multisubnet_failover
-N (зашифрованное соединение)
-o выходной_файл
-p[1] (вывод статистики, необязательный формат двоеточия)
-P пароль
-q "cmdline query"
-Q "cmdline query" (и выход)
-r [0 | 1] (сообщения в stderr)
-R (использовать региональные настройки клиента)
-s col_separator
-S [протокол:] сервер [имя_экземпляра][, порт]
-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 новый_пароль
-Z новый_пароль (и выход)
-? (использование)