Database
 sql >> база данни >  >> RDS >> Database

4 готови метода за преобразуване на SQL данни и случаи на употреба

Първо, не можете без тях, нали?

Преобразуванията на SQL данни или, по-конкретно, преобразуванията на типове данни са съществена част от редовната работа по програмиране на разработчика на база данни или на DBA.

Ами сега, ако шефът ви подписа договор с друга компания, за да им предостави файл в текстов формат, идващ от вашата база данни на SQL Server?

Това звучи като вълнуващо предизвикателство!

Но открихте, че ще трябва да се справите с дата в низ, число в низ и куп други преобразувания на SQL данни. Още ли сте готови за предизвикателството?

Не и без вашия арсенал от трикове за преобразуване на данни!

Какво е налично като готово?

Когато за първи път започнах програмиране с T-SQL, първото нещо, което видях, което отговаряше на целта на преобразуването, беше CONVERT ().

Освен това има думата „конвертиране“, нали?

Въпреки че това може да е вярно, това е само един от 4-те начина за изпълнение на тази работа. И аз го използвах за почти ВСИЧКО мое преобразуване на SQL данни. Радвам се, че съм далеч от това. Защото научих, че 4-те метода имат свое собствено място във вашия код.

Преди да стигнем до темата на публикацията, позволете ми да представя 4-те готови метода за извършване на преобразуване на SQL данни:

  • CAST ()
  • КОНВЕРТИРАНЕ ()
  • PARSE ()
  • TRY_CAST (), TRY_CONVERT (), TRY_PARSE ()

Всеки от разделите по-долу ще:

  • Обяснете какво представлява
  • Кажем ви кога да го използвате (случаи на употреба)
  • Представете неговите ограничения
  • Дайте примери и го обяснете

Всичко, представено в тази статия, е на прост, прост английски, доколкото е възможно. Докато приключите с четенето на цялата публикация, ще знаете кой метод е подходящ за дадена ситуация.

Така че, без повече приказки, нека се потопим.

1. Преобразуване на SQL данни с помощта на CAST()

Въпреки че всички методи, които ще видите, могат да конвертират типове данни, първият ви избор при конвертирането определено трябва да бъде CAST ().

Ето причините за това:

  • Това е най-бързо работещата функция за преобразуване от всички. Ще се опитаме да докажем това по-късно в тази публикация.
  • Включен е в стандартите за спецификация на езика SQL-92. Така че, когато трябва да пренесете кода си към други SQL продукти, като MySQL, функцията също е налична.

Ето един много прост синтаксис за CAST ():

CAST( <expression> AS <data_type>[(length)] )

Първо, нека разгледаме синтаксиса:

  • <израз> е всеки валиден израз, който води до стойност, която може да бъде преобразувана в целевия тип данни.
  • <тип_данни> е целевият тип данни.
  • дължина е по избор и се отнася до размера на данните.

Кога да го използвате

Ако единственото нещо, от което се нуждаете, е да преобразувате стойност в друг тип данни, тогава CAST () е точно това, от което се нуждаете.

Ограничение

От отрицателна страна, CAST () не може да ви даде форматиран изход извън кутията като форматирана стойност за дата и час.

Примери

А. Преобразуване на низ в дата:

SELECT CAST('09/11/2004 4:30PM' as datetime2)

И изпълнението на горния оператор ще доведе до:

Б. Преобразуване на число в низ:

SELECT CAST(10.003458802 as varchar(max))

И резултатът от горното преобразуване е:

Сега, ако имате нужда от нещо друго като форматиране на преобразуваните данни, следващият метод може да ви помогне.

2. Преобразуване на SQL данни с помощта на CONVERT()

Следващата опция за преобразуване на данни е да използвате CONVERT (). Както казах преди, това е този, който използвах най-много в по-ранните дни.

Ето синтаксиса:

CONVERT( <data_type>[(length)], <expression> [, <style>])

От синтаксиса по-горе, имайте предвид, че <style> параметърът не е задължителен. И освен ако не го предоставите, функцията ще бъде подобна на CAST ().

Оттам започна моето объркване, когато бях нов в SQL.

Кога да го използвате

Ако преобразувате данните с незабавен формат, тогава КОНВЕРТИРАНЕ () е твой приятел. Което означава, че третирате <стила> параметър правилно.

Ограничения

  • CAST () е по-бързо от CONVERT (), така че ако трябва само да преобразувате данните, използвайте CAST (). Ако изходът трябва да бъде форматиран, използвайте CONVERT ().
  • КОНВЕРТИРАНЕ () не е стандарт SQL-92, така че ако трябва да го пренесете към друга RDBMS, избягвайте да го използвате.

Примери

А. Преобразуване на дата в низов формат ггггммдд

В следващия пример ще използвам примерната база данни AdventureWorks и трансформирайте [StartDate ] колона до ггггммдд :

USE AdventureWorks
GO
SELECT
[BillOfMaterialsID]
,CONVERT(varchar(10), [StartDate],112) as StartDate
FROM [Production].BillOfMaterials]
GO

Имайте предвид, че стил 112 се използва за форматиране на дати до ггггммдд .

Б. Преобразувайте число в низ със запетаи на всеки 3 цифри вляво от десетичната запетая.

По подобен начин следващият пример ще илюстрира AdventureWorks примерна база данни и ще форматираме числото със запетаи и с 2 знака след десетичната запетая.

USE AdventureWorks
GO
SELECT
[TransactionID]
,[ProductID]
,CONVERT(varchar(10),[TransactionDate] ,112) as StartDate
,[Quantity]
,CONVERT(varchar(10),[ActualCost],1) as ActualCost
FROM [Production].TransactionHistory
GO

Имайте предвид, че формат 1 се използва за [ActualCost ]. И благодарение на CONVERT (), можем да форматираме тези колони за миг.

Но какво ще стане, ако трябва да конвертирате по-дълъг израз за дата? Ще КОНВЕРИРА () работи в такъв случай? Прочетете, за да научите за следващия метод.

3. Преобразуване на SQL данни с помощта на PARSE()

Следващият метод, който ще разгледаме, е PARSE ().

Вижте синтаксиса:

PARSE( <string value> AS <datatype> [USING <culture>])

Кога да го използвате

  • За да конвертирате низове в дати или числа с помощта на конкретна култура.
  • Когато низът не може да бъде преобразуван в дата или число с помощта на CAST () или КОНВЕРТИРАНЕ (). Вижте примерите за повече информация.

Ограничения

  • Преобразуването е възможно само за низ в дати и низ в числа
  • Разчита на наличието на .Net Framework Common Language Runtime (CLR) на сървъра.
  • Не е включено в стандартните спецификации на SQL-92, така че пренасянето към други RDBMS е проблем.
  • Има допълнителни разходи за производителност, когато става въпрос за синтактичен анализ на низа.

Примери

А. Преобразуване на дълъг низ от датата

SELECT PARSE('Monday, June 8, 2020' as datetime USING 'en-US')

Примерът по-горе е дълъг низ от дата, който трябва да се преобразува в datetime стойност, използвайки американската английска култура. И тук PARSE () ще направи всичко възможно.

Това е така, защото кодът по-горе ще се провали, ако използвате CAST () или КОНВЕРТИРАНЕ ().

Б. Преобразуване на парична стойност със символ на валутата

SELECT PARSE('€1024,01' as money using 'de-DE')

Сега опитайте да извършите преобразуването с помощта на CAST () и КОНВЕРТИРАНЕ ()

SELECT CONVERT(money,'€1024,01')
SELECT CAST('€1024,01' as money)

Изявлението няма да доведе до грешки, все пак вижте този неочакван резултат:

В резултат на това стойността е преобразувана в 102401,00 вместо в 1024,01.

Досега открихме, че първите 3 метода са склонни към грешки, освен ако не ги проверите. Независимо от това, 4-ти метод може да бъде вашето решение за грешния резултат.

4. Преобразуване на SQL данни с помощта на TRY_CAST(), TRY_CONVERT() или TRY_PARSE()

И накрая, последният метод за преобразуване на SQL данни е използването на вариант на първите 3, но с префикс TRY_.

Но въпреки това, каква е разликата?

Те имат същите параметри като предишните 3 без префикса TRY_. Но разликата е, че те връщат NULL ако стойността не може да бъде преобразувана. Сега, ако стойността не може да бъде преобразувана от нито един от 3-те изрично, възниква грешка. Вижте примерите по-долу за по-добро разбиране.

Кога да го използвате

Можете да използвате всеки от 3-те с условни изрази като CASE КОГА или IIF за тестване за грешки.

Ограничения

Трите от тях имат същите ограничения като тези без префикса TRY_, с изключение на стойности, които не могат да бъдат преобразувани.

Примери

А. Използвайте TRY_CAST(), за да тествате дали преобразуването ще успее с IIF:

SELECT IIF(TRY_CAST('111b' AS real) IS NULL, 'Cast failed', 'Cast succeeded') AS Result

Кодът по-горе ще върне „Cast Failed“, защото „111b“ не може да бъде преобразуван в реален . Премахнете „b“ от стойността и тя ще върне „Предаване успешно“.

Б. Използване на TRY_CONVERT() на дати с конкретен формат

SET DATEFORMAT dmy;
SELECT TRY_CONVERT(datetime2, '12/31/2010') AS Result

Това ще върне NULL защото форматът използва dmy или ден-месец-година. И входният израз за TRY_CONVERT () е във формат mdy или месец-ден-година. Грешката се задейства, защото стойността на месеца е 31.

В. Използване на TRY_PARSE(), което ще генерира грешка по време на изпълнение

SELECT
CASE WHEN TRY_PARSE('10/21/2133' AS smalldatetime USING 'en-US') IS NULL
    THEN 'True'
    ELSE 'False'
END AS Result

Този код ще генерира грешка по време на изпълнение, както се вижда по-долу:

Това е всичко за 4-те нестандартни метода в преобразуването на SQL данни. Но предстои още.

Какво ще кажете за преобразуването на SQL данни чрез имплицитно преобразуване?


Сега нека разгледаме имплицитното преобразуване. Това е безшумен метод.

Защо мълча?

Защото може би вече го правите, но не сте наясно с това. Или поне знаете, че се случва, но го игнорирате.

С други думи, това е типът преобразуване, което SQL извършва автоматично без никакви функции.

Нека ви дам пример:

DECLARE @char CHAR(25)
DECLARE @varchar VARCHAR(25)
DECLARE @nvarchar NVARCHAR(25)
DECLARE @nchar NCHAR(25)
 
SET @char = 'Live long and prosper'
SET @varchar = @char
SET @nvarchar = @varchar
SET @nchar = @nvarchar
 
SELECT @char AS [char], @varchar AS [varchar], @nvarchar AS [nvarchar], @nchar AS [nchar]

Горният код ще бъде изпълнен успешно. Опитайте го сами и ще имате резултат, подобен на този по-долу:

Нека опитаме това с дати:

DECLARE @datetime datetime
DECLARE @smalldatetime smalldatetime
DECLARE @datetime2 datetime2

SET @datetime = '12/31/2050 14:34'
SET @smalldatetime = @datetime
SET @datetime2 = @smalldatetime

SELECT @datetime as [datetime], @smalldatetime as [smalldatetime], @datetime2 as [datetime2]

Както се очаква, това ще доведе до успешен резултат:

Нека опитаме този път с числа:

DECLARE @int int
DECLARE @real real
DECLARE @decimal decimal
DECLARE @float float

SET @int = 1701
SET @real = @int
SET @decimal = @real
SET @float = @decimal

SELECT @int as [int], @real as [real], @decimal as [decimal], @float as [float]

Все още има успех, нали?

Досега използвахме прости стойности, които ще бъдат подходящи за доста подобен тип данни. Нека преминем към следващото ниво:числа към низове.

DECLARE @number int
DECLARE @string varchar(5)

SET @number = 1701
SET @string = @number

SELECT @number as [number], @string as [string]

Това ще бъде преобразувано успешно, както можете да видите от резултата по-долу:

Има много повече случаи, когато SQL Server ще се опита да „отгатне“ как да конвертира данни. Както можете да видите от тази справка, има много случаи в сравнение с тези, които изискват изрично преобразуване.

Тъй като SQL Server позволява това, означава ли това, че можете свободно да позволите това да се случва във вашия код?

Предупреждения при имплицитното преобразуване

От една страна, може да е удобно. Но след като бъдат достигнати границите на всеки тип данни, ще разберете, че имплицитното преобразуване е малко опасно, ако не бъде отметнато.

Помислете за пример по-долу:

DECLARE @char char(25)
DECLARE @varchar varchar(25)
DECLARE @nvarchar nvarchar(25)
DECLARE @nchar nchar(25)

SET @nvarchar = N'I ❤ U!'
SET @nchar = @nvarchar 
SET @char = @nchar
SET @varchar = @nchar

SELECT @char as [char], @varchar as [varchar], @nvarchar as [nvarchar], @nchar as [nchar]

Видяхте ли стойността на емоджи? Това ще се брои като стойност на Unicode.

Докато всички изявления по-горе ще се изпълняват успешно, променливите с не-unicode типове като varchar и char ще има неочаквани резултати. Вижте резултата по-долу:

Въпреки това, това не е единственият проблем. Грешките ще изскочат, когато стойността излезе извън диапазона. Помислете за пример с дати:

DECLARE @datetime datetime
DECLARE @smalldatetime smalldatetime
DECLARE @datetime2 datetime2

SET @datetime = '12/31/2374 14:34'
SET @smalldatetime = @datetime
SET @datetime2 = @smalldatetime

SELECT @datetime as [datetime], @smalldatetime as [smalldatetime], @datetime2 as [datetime2]

Присвояването на дата и час стойност на smalldatetime променливата ще задейства грешката, както можете да видите по-долу:

Но има още едно предупреждение, което също трябва да сте наясно, когато се занимавате с имплицитно преобразуване:режийни разходи за производителност. Виждайки, че това е гореща тема, заслужава да има отделен раздел.

Влияние върху производителността на различни методи за преобразуване на SQL данни

Вярвате или не, различните методи за преобразуване на SQL данни ще имат различна производителност в реални ситуации. И поне трябва да сте наясно с това, за да избегнете клопки в производителността.

Как се представят CAST(), CONVERT() и PARSE()

Първо, нека разгледаме как CAST (), КОНВЕРТИРАНЕ () и PARSE () изпълняват при естествени условия, като сравняват кое е по-бързо. Ние адаптираме и доказваме концепцията на нашия пример, взет от тук. Помислете за кода по-долу:

USE AdventureWorks
GO

SET STATISTICS TIME ON
SELECT CAST([NationalIDNumber] as int) FROM [HumanResources].[Employee]
SELECT CONVERT(int,[NationalIDNumber]) FROM [HumanResources].[Employee]
SELECT PARSE([NationalIDNumber] as int) FROM [HumanResources].[Employee]
SET STATISTICS TIME OFF
GO

Сега нека разгледаме кода, който използва AdventureWorks база данни от Microsoft:

  • ЗАДАДЕТЕ ВРЕМЕ НА СТАТИСТИКАТА ВКЛЮЧЕНО ще изведе времето на процесора и изминалото време във всеки от SELECT изявления
  • След това колоната, която избираме да преобразуваме за демонстрационни цели, е [NationalIDNumber ], който има тип nvarchar(15) .
  • Освен това преобразуването е от низ към цяло число:nvarchar(15) довх .
  • И накрая, ние възстановяваме ЗАДАДЕНОТО ВРЕМЕ НА СТАТИСТИКАТА до предишната му стойност

Обърнете внимание на изхода в Съобщения раздел на резултата от заявката:

Ето какво измислихме, използвайки този пример:

  • Това доказва, че CAST () изпълнява най-бързо (1 ms.) и PARSE () изпълнява най-бавното (318 ms.).
  • Следваме този приоритет, когато решаваме коя функция да използваме за преобразуване на данни:(1 ) CAST () (2 ) КОНВЕРТИРАНЕ () (3 ) PARSE ().
  • Запомнете кога всяка функция е уместна и вземете предвид ограниченията, когато решавате коя функция да използвате.

Как се представя неявното преобразуване

В този момент трябва да можете да видите, че препоръчвам използването на функции като CAST() за конвертиране на данни. И в този раздел ще видите защо.

Помислете за тази заявка с помощта на WideWorldImporters база данни от Microsoft. Преди да го изпълните, моля, активирайте Включи действителен план за изпълнение в SQL Server Management Studio .

USE WideWorldImporters
GO
SELECT
[CustomerID]
,[OrderID]
,[OrderDate]
,[ExpectedDeliveryDate]
FROM [Sales].[Orders]
WHERE [CustomerID] like '487%'

В заявката по-горе ние филтрираме резултата от поръчките за продажба с [CustomerID ] като „487%“. Thfe е само да демонстрира какъв ефект има имплицитното преобразуване на int тип данни има на varchar .

След това разглеждаме плана за изпълнение по-долу:

Както можете да видите, има предупреждение в SELECT икона. Затова задръжте курсора на мишката, за да видите подсказката. След това забележете предупредителното съобщение, а именно CONVERT_IMPLICIT .

Преди да продължим, това CONVERT_IMPLICIT предупреждението се появява, когато е необходимо да се извърши имплицитно преобразуване за SQL Server. Нека разгледаме по-отблизо проблема. Както е описано по-долу, предупреждението се състои от 2 части:

  • CONVERT_IMPLICIT може да повлияе на „CardinalityEstimate“ при избор на план на заявка.
  • CONVERT_IMPLICIT може да повлияе на „SeekPlan“ при избор на план за заявка.

И двете показват, че вашата заявка ще работи по-бавно. Но ние знаем защо, разбира се. Ние умишлено налагаме неявно преобразуване, като използваме LIKE оператор за целочислена стойност.

Какъв е смисълът в това?

  • Неявното преобразуване на данни кара SQL Server да използва CONVERT_IMPLICIT , което забавя изпълнението на заявката ви.
  • За да отстраните този проблем, премахнете използването на неявно преобразуване. В нашия случай използвахме [CustomerID ] Харесвам „487%“, можем да го поправим, като променим [CustomerID ] =487. Коригирането на заявката ще промени плана за изпълнение на заявката, ще премахне предупреждението по-рано и ще промени оператора за сканиране на индекс на търсене на индекс. В крайна сметка производителността се подобрява.

Щастлив край? Да!

Вземане за вкъщи

Както е показано, не можем просто да оставим SQL Server да извърши преобразуването с имплицитно преобразуване. Препоръчвам ви да следвате приоритета, когато става въпрос за решаване какво да използвате при конвертиране на данни.

  • Първо, ако просто трябва да конвертирате както е, използвайте CAST (). Това е по-стандартизирана функция, когато става въпрос за пренасяне към други RDBM.
  • Второ, ако имате нужда от форматирани данни, използвайте CONVERT ().
  • На трето място, ако и двете CAST () и КОНВЕРТИРАНЕ () не успеете да свършите работата, използвайте PARSE ().
  • Накрая, за да тествате за грешки при конвертиране, използвайте TRY_CAST (), TRY_CONVERT () или TRY_PARSE ().

Е, това е всичко за сега. Надявам се това да ви помогне със следващите ви приключения с кодиране. Счупете крак!

За да научите повече по темата за преобразуването на SQL данни от Microsoft:

  • CAST и CONVERT
  • PARSE
  • TRY_CAST, TRY_CONVERT и TRY_PARSE

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да премахнете дубликатите в SQL

  2. Разбиране на SQL типове данни – всичко, което трябва да знаете за типовете данни на SQL

  3. Как да получите записи от последните 30 дни

  4. SQL АКТУАЛИЗАЦИЯ за начинаещи

  5. Инкременталните статистики НЕ се използват от оптимизатора на заявки