sql >> Base de Datos >  >> RDS >> Database

4 métodos y casos de uso de conversión de datos SQL listos para usar

En primer lugar, no puedes prescindir de ellos, ¿verdad?

Las conversiones de datos SQL o, más específicamente, las conversiones de tipos de datos son una parte esencial del trabajo de programación regular de un desarrollador de base de datos o DBA.

Ahora, ¿qué sucede si su jefe firmó un contrato con otra empresa para proporcionarles un archivo en formato de texto procedente de su base de datos de SQL Server?

¡Esto suena como un desafío emocionante!

Pero descubrió que tendría que lidiar con una fecha en una cadena, un número en una cadena y un montón de otras conversiones de datos SQL. ¿Aún estás listo para el desafío?

¡No sin su arsenal de trucos de conversión de datos!

¿Qué hay disponible listo para usar?

Cuando comencé a programar T-SQL, lo primero que vi que encajaba con el propósito de la conversión fue CONVERT () función.

Además, la palabra "convertir" está ahí, ¿verdad?

Aunque esto puede ser cierto, es solo una de las 4 formas de realizar este trabajo. Y lo estaba usando para casi TODAS mis conversiones de datos SQL. Me alegro de haber superado eso. Porque aprendí que los 4 métodos tienen su propio lugar en tu código.

Antes de llegar al tema de la publicación, permítanme presentarles los 4 métodos listos para usar para realizar la conversión de datos SQL:

  • REPARTO ()
  • CONVERTIR ()
  • ANALIZAR ()
  • TRY_CAST (), TRY_CONVERT (), TRY_PARSE ()

Cada una de las siguientes secciones:

  • Explica qué es
  • Decirle cuándo usarlo (casos de uso)
  • Presenta sus limitaciones
  • Dé ejemplos y explíquelo

Todo lo que se presenta en este artículo está en un inglés sencillo y simple tanto como sea posible. Cuando termine de leer la publicación completa, sabrá qué método es apropiado para una situación determinada.

Entonces, sin más preámbulos, profundicemos.

1. Conversión de datos SQL mediante CAST()

Si bien todos los métodos que verá pueden convertir tipos de datos, su primera opción para convertir definitivamente debería ser CAST ().

Estas son las razones por las que:

  • Es la función de conversión de ejecución más rápida de todas. Intentaremos probar esto más adelante en esta publicación.
  • Está incluido en los estándares de especificación del lenguaje SQL-92. Entonces, cuando necesite migrar su código a otros productos SQL, como MySQL, la función también está disponible.

Aquí hay una sintaxis muy simple para CAST ():

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

Primero, examinemos la sintaxis:

  • <expresión> es cualquier expresión válida que dé como resultado un valor que se pueda convertir al tipo de datos de destino.
  • <tipo_datos> es el tipo de datos de destino.
  • longitud es opcional y se relaciona con el tamaño de los datos.

Cuándo usarlo

Si lo único que necesita es convertir un valor a otro tipo de datos, entonces CAST () es justo lo que necesita.

Limitación

En el lado negativo, CAST () no puede proporcionarle una salida con formato lista para usar, como un valor de fecha y hora con formato.

Ejemplos

A. Convertir una cadena en una fecha:

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

Y ejecutar la declaración anterior dará como resultado:

B. Convertir un número en una cadena:

SELECT CAST(10.003458802 as varchar(max))

Y el resultado de la conversión anterior es:

Ahora, si necesita algo más como formatear los datos convertidos, el siguiente método puede ayudarlo.

2. Conversión de datos SQL mediante CONVERT()

La siguiente opción de conversión de datos es usar CONVERT (). Como dije antes, este es el que más usé en los primeros días.

Aquí está la sintaxis:

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

De la sintaxis anterior, tenga en cuenta que el <estilo> parámetro es opcional. Y a menos que lo proporcione, la función será similar a CAST ().

Ahí es donde comenzó mi confusión cuando era nuevo en SQL.

Cuándo usarlo

Si convierte los datos con un formato instantáneo, entonces CONVERTIR () es tu amigo. Lo que significa que tratas el <estilo> parámetro correctamente.

Limitaciones

  • REPARTO () es más rápido que CONVERT (), por lo que si solo necesita convertir los datos, use CAST (). Si se debe formatear la salida, use CONVERT ().
  • CONVERTIR () no es un estándar SQL-92, así que si necesita portarlo a otro RDBMS, evite usarlo.

Ejemplos

A. Convertir una fecha a un formato de cadena aaaammdd

En el siguiente ejemplo, usaré la base de datos de muestra AdventureWorks y transforma la [StartDate ] columna a yyyymmdd :

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

Tenga en cuenta que el estilo 112 se usa para dar formato a las fechas a yyyymmdd .

B. Convierta un número en una cadena con comas cada 3 dígitos a la izquierda del punto decimal.

De manera similar, el siguiente ejemplo ilustrará el AdventureWorks base de datos de muestra, y formatearemos el número con comas y con 2 decimales.

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

Tenga en cuenta que el formato 1 se usa para [ActualCost ]. Y gracias a CONVERTIR (), podemos formatear estas columnas en un instante.

Sin embargo, ¿qué sucede si necesita convertir una expresión de fecha más larga? CONVERTIRÁ () trabajar en ese caso? Siga leyendo para conocer el siguiente método.

3. Conversión de datos SQL usando PARSE()

El siguiente método que vamos a considerar es PARSE ().

Mira la sintaxis:

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

Cuándo usarlo

  • Para convertir cadenas en fechas o números usando una referencia cultural específica.
  • Cuando la cadena no se puede convertir en una fecha o un número usando CAST () o CONVERTIR (). Consulte los ejemplos para obtener más información.

Limitaciones

  • La conversión solo es posible para cadena a fechas y cadena a números
  • Se basa en la presencia de .Net Framework Common Language Runtime (CLR) en el servidor.
  • No está incluido en las especificaciones estándar de SQL-92, por lo que la migración a otros RDBMS es un problema.
  • Tiene una sobrecarga de rendimiento cuando se trata de analizar la cadena.

Ejemplos

A. Convertir una cadena de fecha larga

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

El ejemplo anterior es una cadena de fecha larga que se convertirá en datetime Valorar el uso de la cultura inglesa estadounidense. Y aquí es donde PARSE () hará todo lo posible.

Esto se debe a que el código anterior fallará si usa CAST () o CONVERTIR ().

B. Conversión de un valor monetario con un símbolo de moneda

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

Ahora, intenta hacer la conversión usando CAST () y CONVERTIR ()

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

La declaración no arrojará errores, aún así, eche un vistazo a este resultado inesperado:

Como resultado, el valor se ha convertido a 102401,00 en lugar de 1024,01.

Hasta ahora, hemos descubierto que los primeros 3 métodos son propensos a errores a menos que los verifique. Sin embargo, el cuarto método puede ser su solución al resultado defectuoso.

4. Conversión de datos SQL usando TRY_CAST(), TRY_CONVERT() o TRY_PARSE()

Finalmente, el último método para la conversión de datos SQL utiliza una variante de los primeros 3 pero con el prefijo TRY_.

Pero aun así, ¿cuál es la diferencia?

Tienen los mismos parámetros que los 3 anteriores sin el prefijo TRY_. Pero la diferencia es que devuelven NULL si el valor no se puede convertir. Ahora, si ninguno de los 3 puede convertir el valor explícitamente, se produce un error. Vea los ejemplos a continuación para una mejor comprensión.

Cuándo usarlo

Puede usar cualquiera de los 3 con declaraciones condicionales como CASE CUANDO o IFI para comprobar si hay errores.

Limitaciones

Los 3 tienen las mismas limitaciones que los que no tienen el prefijo TRY_, excepto por los valores que no se pueden convertir.

Ejemplos

A. Use TRY_CAST() para probar si la conversión tendrá éxito usando IIF:

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

El código anterior devolverá "Error de transmisión" porque "111b" no se puede convertir a real . Quite la 'b' del valor y devolverá 'Transmisión exitosa'.

B. Usar TRY_CONVERT() en fechas con un formato específico

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

Esto devolverá NULL porque el formato usa dmy o día-mes-año. Y la expresión de entrada para TRY_CONVERT () tiene el formato mdy o mes-día-año. El error se activó porque el valor del mes es 31.

C. Usando TRY_PARSE() que generará un error de tiempo de ejecución

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

Este código generará un error de tiempo de ejecución como se ve a continuación:

Eso es todo para los 4 métodos listos para usar en la conversión de datos SQL. Pero hay más por venir.

¿Qué hay de la conversión de datos SQL mediante conversión implícita?


Ahora consideremos la conversión implícita. Este es un método silencioso.

¿Por qué callar?

Porque es posible que ya lo estés haciendo, pero no eres consciente de ello. O al menos, sabes que está sucediendo, pero lo estás ignorando.

En otras palabras, este es el tipo de conversión que SQL realiza automáticamente sin ninguna función.

Déjame darte un ejemplo:

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]

El código anterior se ejecutará con éxito. Pruébelo usted mismo y obtendrá un resultado similar al siguiente:

Intentemos esto con fechas:

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]

Como era de esperar, esto producirá un resultado exitoso:

Intentémoslo esta vez con números:

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]

Sigue siendo un éxito, ¿verdad?

Hasta ahora, hemos usado valores simples que serán adecuados para un tipo de datos bastante similar. Pasemos al siguiente nivel:de números a cadenas.

DECLARE @number int
DECLARE @string varchar(5)

SET @number = 1701
SET @string = @number

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

Esto se convertirá con éxito como puede ver en el siguiente resultado:

Hay muchos más casos en los que SQL Server intentará "adivinar" cómo convertir datos. Como puede ver en esta referencia, hay muchas instancias en comparación con las que requieren una conversión explícita.

Dado que SQL Server permite esto, ¿significa esto que puede permitir que esto suceda libremente en todo su código?

Advertencias en la conversión implícita

Por un lado, puede ser conveniente. Pero una vez que se alcancen los límites de cada tipo de datos, se dará cuenta de que la conversión implícita es un poco peligrosa si no se controla.

Considere un ejemplo a continuación:

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]

¿Viste el valor del emoji? Eso contará como un valor Unicode.

Si bien todas las declaraciones anteriores se ejecutarán correctamente, las variables con tipos que no sean Unicode como varchar y char tendrá resultados inesperados. Vea el resultado a continuación:

Sin embargo, ese no es el único problema. Aparecerán errores cuando el valor esté fuera de rango. Considere un ejemplo con fechas:

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]

La asignación de la fecha y hora valor al smalldatetime variable activará el error como puede ver a continuación:

Pero hay otra advertencia, que también debe tener en cuenta cuando se trata de una conversión implícita:la sobrecarga de rendimiento. Al ver que este es un tema candente, merece tener una sección aparte.

Implicaciones de rendimiento de diferentes métodos de conversión de datos SQL

Lo crea o no, los diferentes métodos de conversión de datos SQL tendrán un rendimiento diferente en situaciones reales. Y al menos debería ser consciente de esto para evitar problemas de rendimiento.

Cómo funcionan CAST(), CONVERT() y PARSE()

Primero, examinemos cómo CAST (), CONVERTIR () y ANALIZAR () realizar en condiciones naturales comparando cuál es más rápido. Adaptamos y probamos el concepto de nuestro ejemplo tomado de aquí. Considere el siguiente código:

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

Ahora, examinemos el código que usa AdventureWorks base de datos de Microsoft:

  • ACTIVAR TIEMPO DE ESTADÍSTICAS generará el tiempo de CPU y el tiempo transcurrido en cada uno de los SELECCIONAR declaraciones
  • Entonces, la columna que elegimos para convertir con fines de demostración es [NationalIDNumber ], que tiene un tipo de nvarchar(15) .
  • Además, la conversión es de una cadena a un número entero:nvarchar(15) a int .
  • Y por último, restauramos el ESTABLECER TIEMPO DE ESTADÍSTICAS a su valor anterior

Observe el resultado en Mensajes pestaña del resultado de la consulta:

Esto es lo que se nos ocurrió usando este ejemplo:

  • Demuestra que CAST () realiza el más rápido (1 ms.) y PARSE () realiza el más lento (318 ms.).
  • Seguimos esta prioridad al decidir qué función usar para convertir datos:(1 ) ENVIAR () (2 ) CONVERTIR () (3 ) ANALIZAR ().
  • Recuerde cuándo cada función es relevante y tenga en cuenta las limitaciones al decidir qué función usar.

Cómo funciona la conversión implícita

En este punto, debería poder ver que recomiendo el uso de funciones como CAST() para convertir datos. Y en esta sección, verás por qué.

Considere esta consulta usando WideWorldImporters base de datos de Microsoft. Antes de ejecutarlo, habilite Incluir plan de ejecución real en SQL Server Management Studio .

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

En la consulta anterior, filtramos el resultado de los pedidos de venta con [CustomerID ] como '487%'. Esto es solo para demostrar qué efecto tiene la conversión implícita de un int tipo de datos tiene en varchar .

A continuación, examinamos el plan de ejecución a continuación:

Como puede ver, hay una advertencia en SELECCIONAR icono. Por lo tanto, desplace el mouse para ver la información sobre herramientas. A continuación, observe el mensaje de advertencia, a saber, CONVERT_IMPLICIT .

Antes de continuar, este CONVERT_IMPLICIT La advertencia se produce cuando es necesario realizar una conversión implícita para SQL Server. Echemos un vistazo más de cerca al problema. Como se describe a continuación, la advertencia tiene 2 partes:

  • CONVERTIR_IMPLICIT puede afectar a "CardinalityEstimate" en una elección de plan de consulta.
  • CONVERTIR_IMPLICIT puede afectar "SeekPlan" en una elección de plan de consulta.

Ambos indican que su consulta se ejecutará más lentamente. Pero sabemos por qué, por supuesto. Intencionadamente forzamos una conversión implícita usando un ME GUSTA operador para un valor entero.

¿Cuál es el punto en eso?

  • La conversión implícita de datos hace que SQL Server use CONVERT_IMPLICIT , lo que ralentiza la ejecución de la consulta.
  • Para solucionar este problema, elimine el uso de la conversión implícita. En nuestro caso, usamos [CustomerID ] ME GUSTA '487%', podemos arreglarlo cambiando [CustomerID ] =487. La corrección de la consulta cambiará el plan de ejecución de la consulta, eliminará la advertencia anterior y cambiará el operador de exploración de índice a una búsqueda de índice. Al final, el rendimiento mejora.

¿Final feliz? ¡Sí!

Puntos para llevar

Como se muestra, no podemos simplemente dejar que SQL Server haga la conversión con una conversión implícita. Le recomiendo que siga la precedencia cuando se trata de decidir qué usar al convertir datos.

  • En primer lugar, si solo necesita convertir tal cual, use CAST (). Es una función más estandarizada cuando se trata de portar a otros RDBM.
  • En segundo lugar, si necesita datos formateados, use CONVERT ().
  • En tercer lugar, si ambos CAST () y CONVERTIR () no puede hacer el trabajo, use PARSE ().
  • Por último, para probar errores al convertir, use TRY_CAST (), TRY_CONVERT (), o TRY_PARSE ().

Bueno, eso es todo por ahora. Espero que esto te ayude con tus próximas aventuras de codificación. ¡Rompe una pierna!

Para obtener más información sobre el tema de la conversión de datos SQL de Microsoft:

  • ENVIAR y CONVERTIR
  • ANALIZAR
  • TRY_CAST, TRY_CONVERT y TRY_PARSE