Skip to main content

Funciones de string — Referencia de SQL en Marketing Cloud

Las funciones de string que MC SQL soporta — LEN, LEFT, RIGHT, SUBSTRING, LTRIM, RTRIM, LOWER, UPPER, REPLACE, CHARINDEX, CONCAT — más las reglas de producción para normalización, manejo de NULL, y la trampa del case-fold-mata-el-índice.

Referencia·Actualizado 2026-05-07·Escrito por Lira · Editado por German Medina

Las funciones de string en MC SQL son un subset de las de T-SQL. La lista es corta, la sintaxis es estándar, y los bugs de producción son mayormente sobre tres cosas: propagación de NULL a través de concatenación con +, truncación de longitud cuando hacés LEFT() para encajar en una columna de destino, y el efecto matador-de-índice de envolver una columna en LOWER() adentro de un WHERE.

Sintaxis oficial

-- Largo (en caracteres, no bytes — Unicode-safe)
SELECT LEN(EmailAddress) AS EmailLen FROM master_subscribers;

-- Extracción de substring
SELECT
  LEFT(EmailAddress, 5)                AS FirstFive,
  RIGHT(EmailAddress, 4)               AS LastFour,
  SUBSTRING(EmailAddress, 2, 6)        AS PositionTwoLenSix
FROM master_subscribers;

-- Trim de espacios
SELECT LTRIM(RTRIM(SubscriberKey)) AS KeyClean FROM _Subscribers;

-- Conversión de case
SELECT
  LOWER(EmailAddress) AS EmailLower,
  UPPER(LoyaltyTier)  AS TierUpper
FROM master_subscribers;

-- Replace
SELECT REPLACE(PhoneNumber, '-', '') AS PhoneClean
FROM master_subscribers;

-- Encontrar posición (devuelve 0 si no se encuentra, NO -1)
SELECT
  EmailAddress,
  CHARINDEX('@', EmailAddress) AS AtPosition
FROM master_subscribers;

-- Concatenación: usá CONCAT (NULL-safe) sobre + (NULL-poisoning)
SELECT
  CONCAT(FirstName, ' ', LastName)        AS FullNameSafe,
  FirstName + ' ' + LastName              AS FullNameRisky
FROM master_subscribers;

El set soportado entre la mayoría de los tenants SFMC:

| Función | Qué hace | Devuelve | |---|---|---| | LEN(s) | Largo en caracteres (espacios trailing ignorados) | INT | | LEFT(s, n) | Primeros n caracteres | NVARCHAR | | RIGHT(s, n) | Últimos n caracteres | NVARCHAR | | SUBSTRING(s, start, len) | len chars empezando en posición start (1-indexada) | NVARCHAR | | LTRIM(s) / RTRIM(s) | Trim de espacios leading / trailing | NVARCHAR | | LOWER(s) / UPPER(s) | Case fold | NVARCHAR | | REPLACE(s, old, new) | Reemplaza todas las ocurrencias de old con new | NVARCHAR | | CHARINDEX(needle, haystack) | Posición 1-indexada de needle en haystack, o 0 si no se encuentra | INT | | CONCAT(s1, s2, ...) | Concatenar, NULL-safe (NULLs se vuelven strings vacíos) | NVARCHAR | | s1 + s2 | Concatenar, NULL-poisoning (NULL en cualquier lado → NULL en resultado) | NVARCHAR |

Referencia:

Lo que sobrevive en producción

Usá CONCAT, no +, cuando algún operando puede ser NULL

'Hello ' + NULL + 'World' devuelve NULL, no 'Hello World'. Cada concatenación con + que involucre una columna que puede ser NULL es una trampa de NULL silenciosa.

-- EN RIESGO — si FirstName o LastName es NULL, el resultado es NULL
SELECT FirstName + ' ' + LastName AS FullName
FROM master_subscribers;

-- DURABLE — CONCAT trata NULL como string vacío
SELECT CONCAT(FirstName, ' ', LastName) AS FullName
FROM master_subscribers;

-- O, si tenés que usar + (ej. para un alias que necesita el espacio
-- explícito en el medio), envolvé cada operando en COALESCE
SELECT COALESCE(FirstName, '') + ' ' + COALESCE(LastName, '') AS FullName
FROM master_subscribers;

+ propaga NULL por compatibilidad backward de T-SQL. CONCAT no. Elegí CONCAT por default salvo que quieras el comportamiento NULL a propósito.

LTRIM(RTRIM(...)) es la red de seguridad de SubscriberKey

Cuando joineás SubscriberKey entre DEs (o contra _Subscribers), los espacios trailing de un import CSV o un export de CRM son el killer silencioso. Siempre normalizá en los dos lados, incluso cuando estés seguro de que el dato está limpio — el costo es una llamada de función extra por fila, el ahorro es el post-mortem que no tenés que escribir.

-- DEFENSIVO — incluso cuando SubscriberKey parece limpio, normalizá
SELECT s.SubscriberKey, e.LoyaltyTier
FROM _Subscribers s
INNER JOIN ext_loyalty e
  ON LTRIM(RTRIM(CAST(s.SubscriberKey AS NVARCHAR(255))))
   = LTRIM(RTRIM(CAST(e.UserId AS NVARCHAR(255))));

Ver JOIN y gotchas — #9 para la trampa completa de SubscriberKey type-coercion + trim.

LOWER() / UPPER() en WHERE mata el índice — stagéa en su lugar

Envolver una columna en LOWER() para una comparación case-insensitive fuerza un full table scan porque el índice no se puede usar. En un Data Extension de 5M filas es la diferencia entre una query de 30 segundos y un timeout de 30 minutos.

-- EN RIESGO — LOWER() en la columna mata el índice, full scan
SELECT SubscriberKey
FROM master_subscribers
WHERE LOWER(LoyaltyTier) = 'gold';

-- MEJOR CUANDO ES POSIBLE — normalizá en momento de escritura, no de lectura.
-- Stagéa una columna LoyaltyTierLower en un de_stg_*, después indexá esa.
INSERT INTO de_stg_subscribers_normalized
SELECT
  SubscriberKey,
  LoyaltyTier,
  LOWER(LoyaltyTier) AS LoyaltyTierLower
FROM master_subscribers;

-- Después producción lee contra la columna normalizada:
SELECT SubscriberKey
FROM de_stg_subscribers_normalized
WHERE LoyaltyTierLower = 'gold';

El trade es más almacenamiento + un paso de staging, a cambio de lecturas rápidas para siempre. Pagalo una vez.

LEFT() para encajar en una columna de destino = truncación silenciosa

Si tu DE de destino tiene EmailAddress VARCHAR(50) y tu fuente es de hasta 75 chars, LEFT(EmailAddress, 50) trunca silenciosamente sin surfacear qué filas perdieron datos. O redimensioná el destino, o contá las truncaciones explícitamente.

-- DIAGNÓSTICO — contá filas que se truncarían, antes de hacerlo
SELECT
  COUNT(*) AS TotalRows,
  SUM(CASE WHEN LEN(EmailAddress) > 50 THEN 1 ELSE 0 END) AS WouldTruncate
FROM master_subscribers;

Corré esto contra producción antes de cambiar largos de columna o agregar llamadas a LEFT(). Ver gotchas — #5.

Decisión rápida

Usá CONCAT en lugar de + cuando:

  • Algún operando puede ser NULL.
  • Default para código nuevo. + solo es útil cuando querés propagación de NULL específicamente.

Usá LTRIM(RTRIM(...)) siempre cuando:

  • Joineás o comparás SubscriberKey o cualquier identificador externo.

Stagéa los resultados de LOWER() / UPPER() en una columna cuando:

  • El DE de origen es grande y la comparación corre seguido. Normalización en momento de lectura está bien para queries one-shot; para producción, normalizá en momento de escritura.

Usá LEFT() / SUBSTRING() con cuidado cuando:

  • El largo de columna del destino es fijo. Corré el diagnóstico de conteo primero.

Andá a CHARINDEX en lugar de LIKE cuando:

  • Solo necesitás saber si un substring está presente (y no necesitás wildcards). Es más rápido que LIKE '%x%' y la intención es más clara.

Relacionado

  • Basics — subset de T-SQL soportado
  • SELECT — funciones de string en proyección
  • WHERE — funciones de string en filtros (y la trampa de matar el índice)
  • JOINLTRIM(RTRIM()) para seguridad de SubscriberKey
  • LIKE — pattern matching (relacionado pero distinto a CHARINDEX)
  • MC SQL gotchas — ver #5 (truncación de longitud), #9 (SubscriberKey trim/cast)

Próximas páginas de referencia de funciones: Date · Numeric · Conversion · Aggregate · Null Functions.

Más snippets how-to para debugging común en producción — sends de email, largo de valores, alcance de contactos, etc.