Как указать параметры региона/языка/культуры при вызове sqlcmd в Powershell?

Когда я выполняю функцию, которая возвращает дату и время (например, GETDATE()) в SQL Server Management Studio, вывод форматируется в «культуре» пользователя (настройки региона/языка). Однако, когда тот же запрос выполняется в Powershell с помощью командлета Invoke-Sqlcmd, выходные данные форматируются в формате даты США (который, как я полагаю, является инвариантной культурой). Другие командлеты, такие как Get-Date, возвращают дату и время в CurrentCulture.

Как я могу гарантировать, что выходные данные Invoke-Sqlcmd соответствуют настройкам CurrentCulture?

Минимальный пример кода для демонстрации

$result = Invoke-Sqlcmd -query "select GETDATE() as datetime" -ServerInstance ...
$now = Get-date -format "yyyy-MM-dd HH:mm:ss"
if ( $result.datetime -eq $now) {
  Write-output "ok"
} else {
  Write-warning "dates mismatch '$($result.datetime)' should be '$now'"
}

Предупреждение показывает первую дату и время, отображаемую в формате США, и вторую дату и время в указанном формате.


person Bram    schedule 31.01.2017    source источник
comment
Вы должны исправить сценарий, чтобы он не использовал литералы, зависящие от локали, когда следует использовать даты или числа. GetDate() не имеет формата нет — это просто строго типизированное двоичное значение datetime. Возможно, вы конвертируете его в строку? Разместите свой сценарий   -  person Panagiotis Kanavos    schedule 31.01.2017
comment
Если вы используете INSERT INTO MyTable (MyCol) VALUES(GetDate()), язык не имеет значения. Если вы пишете вместо EXEC 'INSERT ...' + GETDATE() + '..' у вас ошибка. Ваш скрипт не сработает, если изменится локаль, и он будет уязвим для множества других проблем, включая SQL-инъекции.   -  person Panagiotis Kanavos    schedule 31.01.2017
comment
@PanagiotisKanavos: я не использую это для вставки. Цель скрипта — убедиться, что пользовательская функция правильно возвращает текущую дату и время. Вы абсолютно правы в том, что функция (например, GETDATE()) возвращает объект System.DateTime. Форматирование происходит в вызове Write-Warning, который отображает результат и ожидаемое значение (которое передается функции в виде строки). Если вы опубликуете свой первый комментарий в качестве ответа, я приму его.   -  person Bram    schedule 31.01.2017


Ответы (1)


$result.datetime будет иметь тип datetime, а $now будет иметь тип string. Вот почему ваше сравнение и вывод не работают должным образом. Вы можете просто обойтись без преобразования текущей даты в строку:

...
$now = Get-Date
if ($result.datetime -eq $now) {
...

Но имейте в виду, что затем вы сравните оба значения с точностью до миллисекунд. Согласно вашей строке формата, я предполагаю, что вам нужна точность только в секундах. Затем вы можете сделать следующее:

...
$now = Get-Date
$format = 'yyyy-MM-dd HH:mm:ss'
if ($result.datetime.toString($format) -eq $now.toString($format)) {
...
person stackprotector    schedule 27.06.2020
comment
Спасибо @Томас. Я проверю как можно скорее (это может занять некоторое время, сейчас я работаю над некоторыми другими приоритетами) и приму ваш ответ или предоставлю отзыв! - person Bram; 29.06.2020