Написание инструкций Transact-SQL, адаптированных к международному использованию

Относится к:SQL ServerБаза данных SQL AzureУправляемый экземпляр SQL AzureAzure Synapse AnalyticsСистема платформы аналитики (PDW)База данных SQL в Microsoft Fabric

Базы данных и приложения базы данных, использующие инструкции Transact-SQL, становятся более переносимыми с одного языка на другой или поддерживают несколько языков, если следуют следующие рекомендации:

  • Начиная с SQL Server 2019 (15.x) и в Базе данных SQL Azure используйте один из следующих вариантов:

    • Типы данных char, varchar и varchar(max) с параметрами сортировки, поддерживающими UTF-8, при этом данные кодируются в UTF-8.
    • Типы данных nchar, nvarchar и nvarchar(max) с параметрами сортировки, поддерживающими дополнительные символы (SC), используют кодировку UTF-16. При использовании параметров сортировки, отличных от SC, данные кодируются с использованием UCS-2.

    Это позволяет избежать проблемы преобразования кодовых страниц. О других аспектах см. Различия в хранении между UTF-8 и UTF-16.

  • До SQL Server 2017 (14.x) включительно замените все использования типов данных char, varchar и varchar(max) на nchar, nvarchar и nvarchar(max). При использовании правил сортировки с поддержкой дополнительных символов (SC) данные кодируются с помощью UTF-16. При использовании параметров сортировки, отличных от SC, данные кодируются с использованием UCS-2. Это позволяет избежать проблемы преобразования кодовых страниц. Дополнительные сведения см. в статье Collation and Unicode Support.

    Внимание

    Тип данных text является устаревшим, и его не следует использовать в новых разработках. Запланируйте преобразование данных типа text в varchar(max).

  • При сравнении месяцев и дней недели, а также при выполнении операций с ними используйте числовые компоненты даты вместо строковых названий. При различных языковых настройках возвращаются различные названия месяцев и дней недели. Например, DATENAME(MONTH,GETDATE()) возвращает May, если выбран язык «английский (США)», Mai, если выбран язык «немецкий», и mai, если выбран язык «французский». Вместо нее следует использовать функцию наподобие DATEPART, в которой вместо названия месяца используется его номер. При выводе результирующих наборов пользователю лучше использовать названия из функции DATEPART(), так как они зачастую более информативны, чем числовое представление даты. Однако не следует кодировать какую-либо логику, зависящую от отображаемых названий на том или ином языке.

  • При указании дат в сравнениях или в качестве входных данных для операторов INSERT или UPDATE используйте константы, которые интерпретируются одинаково при любых языковых параметрах:

    • Приложения ADO, OLE DB и ODBC должны использовать следующие экранирующие последовательности ODBC для метки времени, даты и времени:

      { ts'yyyy-mm-ddhh:mm:ss [.fff] '} например: { ts'1998-09-24 10:02:20'}

      { d'yyyy-mm-dd'}, например: { d'1998-09-24'}

      { t'hh:mm:ss'}, например: { t'10:02:20'}

    • Приложения, использующие другие API-интерфейсы или скрипты Transact-SQL, хранимые процедуры и триггеры, должны использовать неуправляемые числовые строки. Например, yyyymmdd в виде 19980924.

    • Приложения, использующие другие API, а также скрипты Transact-SQL, хранимые процедуры и триггеры, должны использовать инструкцию CONVERT с явным параметром стиля для всех преобразований между типами данных time, date, smalldate, datetime, datetime2 и datetimeoffset и строковыми типами символьных данных. Например, следующая инструкция интерпретируется одинаково для любых настроек языка и формата даты в соединении:

      SELECT *  
      FROM AdventureWorks2022.Sales.SalesOrderHeader  
      WHERE OrderDate = CONVERT(DATETIME, '20060719', 101)