Migrer de Teradata vers BigQuery : Document de référence sur la traduction du langage SQL

Dernière mise à jour : septembre 2020
Notes de version

Ce document décrit les similitudes et les différences de syntaxe SQL entre Teradata et BigQuery pour vous aider à accélérer la planification et l'exécution de la migration de votre entrepôt de données d'entreprise (EDW, Enterprise Data Warehouse) vers BigQuery dans Google Cloud. L'entreposage de données Teradata est conçu pour fonctionner avec la syntaxe SQL spécifique à Teradata. Vous devrez peut-être modifier les scripts écrits pour Teradata pour pouvoir les utiliser dans BigQuery, car les dialectes SQL varient selon les services. Les partenaires Google Cloud disposent d'outils permettant d'automatiser la conversion des scripts SQL Teradata. Si vous souhaitez en savoir plus, contactez votre responsable de compte.

La série consacrée aux spécificités de la transition depuis Teradata comprend les articles suivants :

Pour une présentation de la transition d'un entrepôt de données sur site vers BigQuery sur Google Cloud, consultez la série commençant par l'article Migrer des entrepôts de données vers BigQuery : Introduction et présentation.

Types de données

Cette section présente les équivalences entre les types de données Teradata et BigQuery.

Teradata BigQuery Remarques
INTEGER INT64
SMALLINT INT64
BYTEINT INT64
BIGINT INT64
DECIMAL NUMERIC Contrairement à Teradata, le type de données NUMERIC de BigQuery n'applique pas de limites de chiffres ou d'échelles personnalisées (contraintes).

Teradata vous permet d'insérer des valeurs plus précises et arrondit le résultat. Cependant, il conserve la haute précision des calculs. Cela peut entraîner un comportement inattendu en ce qui concerne les arrondis, par rapport à la norme ANSI.
FLOAT FLOAT64
NUMERIC NUMERIC Contrairement à Teradata, le type de données NUMERIC de BigQuery n'applique pas de limites de chiffres ou d'échelles personnalisées (contraintes).

Teradata vous permet d'insérer des valeurs plus précises et arrondit le résultat. Cependant, il conserve la haute précision des calculs. Cela peut entraîner un comportement inattendu en ce qui concerne les arrondis, par rapport à la norme ANSI.
NUMBER NUMERIC Contrairement à Teradata, le type de données NUMERIC de BigQuery n'applique pas de limites de chiffres ou d'échelles personnalisées (contraintes).

Teradata vous permet d'insérer des valeurs plus précises et arrondit le résultat. Cependant, il conserve la haute précision des calculs. Cela peut entraîner un comportement inattendu en ce qui concerne les arrondis, par rapport à la norme ANSI.
REAL FLOAT64
CHAR/CHARACTER STRING Contrairement aux types de données CHARACTER et CHAR de Teradata, le type de données STRING de BigQuery est de longueur variable et ne nécessite pas de définir manuellement un nombre maximal de caractères.
VARCHAR STRING Contrairement au type de données VARCHAR de Teradata, le type de données STRING de BigQuery est de longueur variable et ne nécessite pas de définir manuellement un nombre maximal de caractères.
CLOB STRING
JSON STRING
BLOB BYTES
BYTE BYTES
VARBYTE BYTES
DATE DATE BigQuery n'est pas compatible avec une mise en forme personnalisée semblable à celle qu'accepte Teradata avec DataForm dans SDF.
TIME TIME
TIME WITH TIME ZONE TIME Teradata stocke le type de données TIME au format UTC et vous permet de transmettre un décalage par rapport à l'heure UTC à l'aide de la syntaxe WITH TIME ZONE. Le type de données TIME de BigQuery représente une heure indépendante de toute date ou de tout fuseau horaire.
TIMESTAMP TIMESTAMP Les types de données TIMESTAMP de Teradata et BigQuery ont une précision de l'ordre de la microseconde (mais Teradata accepte les secondes intercalaires, contrairement à BigQuery).

Les types de données de Teradata et BigQuery sont généralement associés à un fuseau horaire UTC (en savoir plus).
TIMESTAMP WITH TIME ZONE TIMESTAMP Le type de données TIMESTAMP de Teradata peut être défini sur un fuseau horaire différent à l'échelle du système, par utilisateur ou par colonne (à l'aide de WITH TIME ZONE).

Le type de données TIMESTAMP de BigQuery suppose que la valeur est UTC si vous ne spécifiez pas explicitement de fuseau horaire. Veillez à exporter correctement les informations de fuseau horaire (ne concaténez pas les valeurs DATE et TIME sans informations de fuseau horaire) afin que BigQuery puisse les convertir lors de l'importation. Sinon, vous pouvez également convertir les informations de fuseau horaire au format UTC avant de les exporter.

BigQuery dispose du type de données DATETIME pour une abstraction entre le temps civil, qui n'affiche pas de fuseau horaire lors de la sortie, et TIMESTAMP, qui correspond à un moment précis qui affiche toujours le fuseau horaire UTC.
ARRAY ARRAY
MULTI-DIMENSIONAL ARRAY ARRAY Dans BigQuery, utilisez un tableau de structures, chaque structure contenant un champ de type ARRAY (pour en savoir plus, consultez la documentation BigQuery).
INTERVAL HOUR INT64
INTERVAL MINUTE INT64
INTERVAL SECOND INT64
INTERVAL DAY INT64
INTERVAL MONTH INT64
INTERVAL YEAR INT64
PERIOD(DATE) DATE, DATE PERIOD(DATE) doit être converti en deux colonnes DATE contenant la date de début et la date de fin, de sorte qu'elles puissent être utilisées avec des fonctions analytiques.
PERIOD(TIMESTAMP WITH TIME ZONE) TIMESTAMP, TIMESTAMP
PERIOD(TIMESTAMP) TIMESTAMP, TIMESTAMP
PERIOD(TIME) TIME, TIME
PERIOD(TIME WITH TIME ZONE) TIME, TIME
UDT STRING
XML STRING
TD_ANYTYPE STRING

Pour plus d'informations sur le casting des types de données, consultez la section suivante.

Mise en forme des types de données Teradata

Le langage SQL Teradata utilise un ensemble de formats par défaut pour afficher les expressions et les données des colonnes, ainsi que pour les conversions entre les types de données. Par exemple, un type de données PERIOD(DATE) en mode INTEGERDATE a le format par défaut YY/MM/DD. Nous vous recommandons d'utiliser le mode ANSIDATE dans la mesure du possible afin de garantir la conformité avec ANSI SQL, et d'en profiter pour nettoyer les anciens formats.

Teradata permet l'application automatique de formats personnalisés à l'aide de la clause FORMAT, sans modifier le stockage sous-jacent, en tant qu'attribut de type de données lorsque vous créez une table à l'aide du LDD ou dans une expression dérivée. Par exemple, une spécification de FORMAT 9.99 arrondit toute valeur FLOAT à deux chiffres. Dans BigQuery, cette fonctionnalité doit être convertie à l'aide de la fonction ROUND().

Cette fonctionnalité nécessite la gestion de cas spéciaux complexes. Par exemple, lorsque la clause FORMAT est appliquée à une colonne NUMERIC, vous devez tenir compte de règles d'arrondi et de mise en forme spéciales. Une clause FORMAT peut être utilisée pour caster implicitement une valeur epoch INTEGER dans un format DATE. Ou une spécification de FORMAT X(6) sur une colonne VARCHAR tronque la valeur de la colonne. Vous devez donc la convertir en fonction SUBSTR(). Ce comportement n'est pas compatible avec ANSI SQL. Par conséquent, nous vous recommandons de ne pas migrer les formats de colonnes vers BigQuery.

Si les formats de colonnes sont absolument obligatoires, utilisez des vues ou des fonctions définies par l'utilisateur (UDF).

Pour en savoir plus sur les formats par défaut utilisés par le langage SQL Teradata pour chaque type de données, consultez la documentation sur la mise en forme par défaut de Teradata.

Mise en forme des types d'horodatage et de date

Lorsque vous convertissez des éléments de mise en forme d'horodatages et de dates du langage SQL Teradata en langage SQL standard BigQuery, vous devez faire attention aux différences de fuseau horaire entre TIMESTAMP et DATETIME, comme résumé dans le tableau suivant.

Notez que les formats Teradata ne comportent pas de parenthèses, car les formats (CURRENT_*) sont des mots clés, et non des fonctions.

Teradata BigQuery
CURRENT_TIMESTAMP
CURRENT_TIME
Les informations TIME et TIMESTAMP dans Teradata peuvent avoir des informations de fuseau horaire différentes, définies à l'aide de WITH TIME ZONE. Si possible, utilisez CURRENT_TIMESTAMP(), qui est au format ISO. Toutefois, le format de sortie affiche toujours le fuseau horaire UTC. (En interne, BigQuery n'a pas de fuseau horaire.)

Notez les détails suivants concernant les différences du format ISO.

Le format de DATETIME repose sur des conventions de canal de sortie. Dans l'outil de ligne de commande BigQuery et la console BigQuery, il est mis en forme à l'aide d'un séparateur T conformément à la norme RFC 3339. Toutefois, dans Python et Java JDBC, un espace est utilisé comme séparateur.

Si vous souhaitez utiliser un format explicite, utilisez FORMAT_DATETIME(), qui permet de caster une chaîne de manière explicite. Par exemple, l'expression suivante renvoie toujours un espace comme séparateur :

CAST(CURRENT_DATETIME() AS STRING)

Teradata accepte un mot clé DEFAULT dans les colonnes TIME pour définir l'heure actuelle (horodatage). Cela n'est pas utilisé dans BigQuery.
CURRENT_DATE Les dates sont stockées dans Teradata en tant que valeurs INT64 à l'aide de la formule suivante :

(YEAR - 1900) * 10000 + (MONTH * 100) + DAY

Les dates peuvent être mises en forme sous forme d'entiers.
BigQuery possède un format DATE distinct qui renvoie toujours une date au format ISO 8601.

DATE_FROM_UNIX_DATE ne peut pas être utilisé, car il repose sur le nombre de secondes écoulées depuis le 1er janvier 1970.

Teradata accepte un mot clé DEFAULT dans les colonnes DATE pour définir la date actuelle. Cela n'est pas utilisé dans BigQuery.
CURRENT_DATE-3 Les valeurs de date sont représentées sous forme d'entiers. Teradata accepte les opérateurs arithmétiques pour les types de date. Pour les types de date, utilisez DATE_ADD() ou DATE_SUB().

BigQuery utilise des opérateurs arithmétiques pour les types de données suivants : INT64, NUMERIC et FLOAT64.
SYS_CALENDAR.CALENDAR Teradata fournit une vue pour les opérations d'agenda au-delà des opérations entières. Non utilisé dans BigQuery.
SET SESSION DATEFORM=ANSIDATE Définissez le format de date système ou de session sur ANSI (ISO 8601). BigQuery utilise toujours la norme ISO 8601. Par conséquent, veillez à convertir les dates et heures Teradata.

Syntaxe des requêtes

Cette section traite des différences de syntaxe des requêtes entre Teradata et BigQuery.

Instruction SELECT

La plupart des instructions SELECT Teradata sont compatibles avec BigQuery. Le tableau suivant contient une liste de différences mineures.

Teradata BigQuery
SEL Conversion en SELECT. BigQuery n'utilise pas l'abréviation SEL.
SELECT
  (subquery) AS flag,
  CASE WHEN flag = 1 THEN ...
Dans BigQuery, les colonnes ne peuvent pas faire référence à la sortie d'autres colonnes définies au sein de la même liste de sélection. Il vaut mieux déplacer une sous-requête dans une clause WITH.

WITH flags AS (
  subquery
),
SELECT
  CASE WHEN flags.flag = 1 THEN ...
SELECT * FROM table
WHERE A LIKE ANY ('string1', 'string2')
BigQuery n'utilise pas le prédicat logique ANY.

La même fonctionnalité peut être obtenue en utilisant plusieurs opérateurs OR :

SELECT * FROM table
WHERE col LIKE 'string1' OR
      col LIKE 'string2'


Dans ce cas, la comparaison de chaînes diffère également. Consultez la section Opérateurs de comparaison.
SELECT TOP 10 * FROM table BigQuery utilise LIMIT à la fin d'une requête au lieu de TOP n après le mot clé SELECT.

Opérateurs de comparaison

Le tableau suivant présente les opérateurs de comparaison qui sont spécifiques à Teradata et doivent être convertis en opérateurs compatibles avec ANSI SQL:2011 utilisés dans BigQuery.

Pour en savoir plus sur les opérateurs dans BigQuery, consultez la section Opérateurs de la documentation BigQuery.

Teradata BigQuery Remarques
exp EQ exp2
exp IN (exp2, exp3)
exp = exp2
exp IN (exp2, exp3)

Pour conserver une sémantique autre que ANSI pour NOT CASESPECIFIC, vous pouvez utiliser
RTRIM(UPPER(exp)) = RTRIM(UPPER(exp2))
En cas de comparaison de chaînes pour en vérifier l'égalité, Teradata peut ignorer les espaces blancs de fin, tandis que BigQuery considère qu'ils font partie de la chaîne. Par exemple, 'xyz'=' xyz' est TRUE dans Teradata, mais FALSE dans BigQuery.

Teradata fournit également un attribut de colonne NOT CASESPECIFIC qui indique à Teradata d'ignorer la casse lors de la comparaison de deux chaînes. BigQuery prend toujours en compte la casse lors de la comparaison de chaînes. Par exemple, 'xYz' = 'xyz' est TRUE dans Teradata, mais FALSE dans BigQuery.
exp LE exp2 exp <= exp2
exp LT exp2 exp < exp2
exp NE exp2 exp <> exp2
exp != exp2
exp GE exp2 exp >= exp2
exp GT exp2 exp > exp2

Conditions JOIN

BigQuery et Teradata acceptent les mêmes conditions JOIN, ON et USING. Le tableau suivant contient une liste de différences mineures.

Teradata BigQuery Remarques
FROM A LEFT OUTER JOIN B ON A.date > B.start_date AND A.date < B.end_date FROM A LEFT OUTER JOIN (SELECT d FROM B JOIN UNNEST(GENERATE_DATE_ARRAY(B.start_date, B.end_date)) d) B ON A.date = B.date BigQuery accepte les clauses JOIN d'inégalité pour toutes les jointures internes ou si au moins une condition d'égalité est spécifiée (=). En revanche, il n'accepte pas une seule condition d'inégalité (= et <) dans une jointure OUTER JOIN. Ce type de construction est parfois utilisé pour interroger des plages de dates ou d'entiers. BigQuery empêche les utilisateurs de créer par inadvertance des jointures croisées de grande taille.
FROM A, B ON A.id = B.id FROM A JOIN B ON A.id = B.id L'utilisation d'une virgule entre les tables dans Teradata équivaut à une jointure INNER JOIN, tandis que dans BigQuery, elle équivaut à une jointure CROSS JOIN (produit cartésien). Étant donné que la virgule dans l'ancien SQL de BigQuery est traitée comme un opérateur UNION, nous vous recommandons de rendre l'opération explicite pour éviter toute confusion.
FROM A JOIN B ON (COALESCE(A.id , 0) = COALESCE(B.id, 0)) FROM A JOIN B ON (COALESCE(A.id , 0) = COALESCE(B.id, 0)) Aucune différence pour les fonctions scalaires (constantes).
FROM A JOIN B ON A.id = (SELECT MAX(B.id) FROM B) FROM A JOIN (SELECT MAX(B.id) FROM B) B1 ON A.id = B1.id BigQuery empêche les utilisateurs d'utiliser des sous-requêtes, des sous-requêtes corrélées ou des agrégations dans les prédicats de jointure. Cela permet à BigQuery d'exécuter les requêtes en parallèle.

Casting et conversion des types de données

BigQuery propose des types de données moins nombreux, mais plus larges que Teradata, ce qui fait qu'il doit assurer un casting plus strict.

Teradata BigQuery Remarques
exp EQ exp2
exp IN (exp2, exp3)
exp = exp2
exp IN (exp2, exp3)

Pour conserver une sémantique autre que ANSI pour NOT CASESPECIFIC, vous pouvez utiliser
RTRIM(UPPER(exp)) = RTRIM(UPPER(exp2))
En cas de comparaison de chaînes pour en vérifier l'égalité, Teradata peut ignorer les espaces blancs de fin, tandis que BigQuery considère qu'ils font partie de la chaîne. Par exemple, 'xyz'=' xyz' est TRUE dans Teradata, mais FALSE dans BigQuery.

Teradata fournit également un attribut de colonne NOT CASESPECIFIC qui indique à Teradata d'ignorer la casse lors de la comparaison de deux chaînes. BigQuery prend toujours en compte la casse lors de la comparaison de chaînes. Par exemple, 'xYz' = 'xyz' est TRUE dans Teradata, mais FALSE dans BigQuery.
CAST(long_varchar_colum AS CHAR(6)) LPAD(long_varchar_colum, 6) Le casting d'une colonne de caractères dans Teradata est parfois utilisé comme un moyen non standard et non optimal de créer une sous-chaîne complétée.
CAST(92617 AS TIME) 92617 (FORMAT '99:99:99') PARSE_TIME("%k%M%S", CAST(92617 AS STRING))
Teradata effectue beaucoup plus de conversions implicites de types de données et d'arrondis que BigQuery, qui est généralement plus strict et applique les normes ANSI.
(Cet exemple renvoie 09:26:17)
CAST(48.5 (FORMAT 'zz') AS FLOAT) CAST(SUBSTR(CAST(48.5 AS STRING), 0, 2) AS FLOAT64)
Les types de données numériques et à virgule flottante peuvent nécessiter des règles d'arrondi spéciales lorsqu'ils sont appliqués avec des formats tels que les devises.
(Cet exemple renvoie 48)

Consultez également les sections sur les opérateurs de comparaison et les formats de colonnes. Les comparaisons et la mise en forme des colonnes peuvent se comporter de la même manière que des castings de types de données.

Clauses QUALIFY, ROWS

La clause QUALIFY de Teradata vous permet de filtrer les résultats pour des fenêtrages. Vous pouvez également utiliser une expression ROWS pour la même tâche. Elles fonctionnent de la même manière qu'une condition HAVING pour une clause GROUP, qui limite la sortie de ce que l'on appelle dans BigQuery des fonctions analytiques d'agrégation.

Teradata BigQuery
SELECT col1, col2
FROM table
QUALIFY ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY col2) = 1;
La clause QUALIFY de Teradata avec une fonction d'analyse telle que ROW_NUMBER(), SUM(), COUNT() et avec OVER PARTITION BY est exprimée dans BigQuery en tant que clause WHERE sur une sous-requête contenant la valeur d'analyse.

Avec ROW_NUMBER() :

SELECT col1, col2
FROM (
  SELECT col1, col2,
  ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY col2) RN
  FROM table
) WHERE RN = 1;


Avec ARRAY_AGG, qui accepte des partitions plus grandes :

SELECT
  result.*
FROM (
  SELECT
    ARRAY_AGG(table ORDER BY table.col2
      DESC LIMIT 1)[OFFSET(0)]
  FROM table
  GROUP BY col1
) AS result;
SELECT col1, col2
FROM table
AVG(col1) OVER (PARTITION BY col1 ORDER BY col2 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW);
SELECT col1, col2
FROM table
AVG(col1) OVER (PARTITION BY col1 ORDER BY col2 RANGE BETWEEN 2 PRECEDING AND CURRENT ROW);


Dans BigQuery, RANGE et ROWS peuvent être utilisés dans la clause de fenêtrage. Cependant, les clauses de fenêtrage ne peuvent être utilisées qu'avec des fonctions analytiques telles que AVG(), et non avec des fonctions de numérotation telles que ROW_NUMBER().

Mot clé NORMALIZE

Teradata fournit le mot clé NORMALIZE pour les clauses SELECT afin de fusionner les périodes ou les intervalles qui se chevauchent en une seule période ou un seul intervalle englobant toutes les valeurs de période individuelles.

BigQuery n'accepte pas le type PERIOD. Par conséquent, toute colonne de type PERIOD dans Teradata doit être insérée dans BigQuery sous la forme de deux champs DATE ou DATETIME distincts, qui correspondent au début et à la fin de la période.

Teradata BigQuery
SELECT NORMALIZE
    client_id,
    item_sid,
    BEGIN(period) AS min_date,
    END(period) AS max_date,
  FROM
    table;
SELECT
  t.client_id,
  t.item_sid,
  t.min_date,
  MAX(t.dwh_valid_to) AS max_date
FROM (
  SELECT
    d1.client_id,
    d1.item_sid,
    d1.dwh_valid_to AS dwh_valid_to,
    MIN(d2.dwh_valid_from) AS min_date
  FROM
    table d1
  LEFT JOIN
    table d2
  ON
    d1.client_id = d2.client_id
    AND d1.item_sid = d2.item_sid
    AND d1.dwh_valid_to >= d2.dwh_valid_from
    AND d1.dwh_valid_from < = d2.dwh_valid_to
  GROUP BY
    d1.client_id,
    d1.item_sid,
    d1.dwh_valid_to ) t
GROUP BY
  t.client_id,
  t.item_sid,
  t.min_date;

Fonctions

Les sections suivantes répertorient les correspondances entre les fonctions Teradata et leurs équivalents dans BigQuery.

Fonctions d'agrégation

Le tableau suivant met en correspondance les fonctions d'agrégation, d'agrégation statistique et d'agrégation approximative courantes de Teradata avec leurs équivalents dans BigQuery. BigQuery propose les fonctions d'agrégation supplémentaires suivantes :

Teradata BigQuery
AVG AVG
BITAND BIT_AND
BITNOT Opérateur NOT (PAS) au niveau du bit (~)
BITOR BIT_OR
BITXOR BIT_XOR
CORR CORR
COUNT COUNT
COVAR_POP COVAR_POP
COVAR_SAMP COVAR_SAMP
MAX MAX
MIN MIN
REGR_AVGX AVG(
  IF(dep_var_expression is NULL
     OR ind_var_expression is NULL,
     NULL, ind_var_expression)
)
REGR_AVGY AVG(
  IF(dep_var_expression is NULL
     OR ind_var_expression is NULL,
     NULL, dep_var_expression)
)
REGR_COUNT SUM(
  IF(dep_var_expression is NULL
     OR ind_var_expression is NULL,
     NULL, 1)
)
REGR_INTERCEPT AVG(dep_var_expression) - AVG(ind_var_expression) * (COVAR_SAMP(ind_var_expression,
              dep_var_expression)
   / VARIANCE(ind_var_expression))
REGR_R2 (COUNT(dep_var_expression)*
 SUM(ind_var_expression * dep_var_expression) -
 SUM(dep_var_expression) * SUM(ind_var_expression))
SQRT(
     (COUNT(ind_var_expression)*
      SUM(POWER(ind_var_expression, 2))*
      POWER(SUM(ind_var_expression),2))*
     (COUNT(dep_var_expression)*
      SUM(POWER(dep_var_expression, 2))*
      POWER(SUM(dep_var_expression), 2)))
REGR_SLOPE - COVAR_SAMP(ind_var_expression,
            dep_var_expression)
/ VARIANCE(ind_var_expression)
REGR_SXX SUM(POWER(ind_var_expression, 2)) - COUNT(ind_var_expression) *
  POWER(AVG(ind_var_expression),2)
REGR_SXY SUM(ind_var_expression * dep_var_expression) - COUNT(ind_var_expression)
  * AVG(ind_var_expression) * AVG(dep_var_expression)
REGR_SYY SUM(POWER(dep_var_expression, 2)) - COUNT(dep_var_expression)
  * POWER(AVG(dep_var_expression),2)
SKEW Fonction définie par l'utilisateur personnalisée.
STDDEV_POP STDDEV_POP
STDDEV_SAMP STDDEV_SAMP, STDDEV
SUM SUM
VAR_POP VAR_POP
VAR_SAMP VAR_SAMP, VARIANCE

Fonctions analytiques

Le tableau suivant met en correspondance les fonctions analytiques et les fonctions analytiques d'agrégation courantes de Teradata avec leurs équivalents dans BigQuery. BigQuery propose les fonctions analytiques supplémentaires suivantes :

Teradata BigQuery
ARRAY_AGG ARRAY_AGG
ARRAY_CONCAT, (|| operator) ARRAY_CONCAT_AGG, (|| operator)
BITAND BIT_AND
BITNOT Opérateur NOT (PAS) au niveau du bit (~)
BITOR BIT_OR
BITXOR BIT_XOR
CORR CORR
COUNT COUNT
COVAR_POP COVAR_POP
COVAR_SAMP COVAR_SAMP
CUME_DIST CUME_DIST
DENSE_RANK (ANSI) DENSE_RANK
FIRST_VALUE FIRST_VALUE
LAST_VALUE LAST_VALUE
MAX MAX
MIN MIN
PERCENT_RANK PERCENT_RANK
PERCENTILE_CONT PERCENTILE_DISC PERCENTILE_CONT PERCENTILE_DISC
RANK (ANSI) RANK
ROW_NUMBER ROW_NUMBER
STDDEV_POP STDDEV_POP
STDDEV_SAMP STDDEV_SAMP, STDDEV
SUM SUM
VAR_POP VAR_POP
VAR_SAMP VAR_SAMP, VARIANCE

Fonctions de date/heure

Le tableau suivant met en correspondance les fonctions de date/heure courantes de Teradata avec leurs équivalents dans BigQuery. BigQuery propose les fonctions de date/heure supplémentaires suivantes :

Teradata BigQuery
ADD_MONTHS DATE_ADD, TIMESTAMP_ADD
CURRENT_DATE CURRENT_DATE
CURRENT_TIME CURRENT_TIME
CURRENT_TIMESTAMP CURRENT_TIMESTAMP
DATE + k DATE_ADD(date_expression, INTERVAL k DAY)
DATE - k DATE_SUB(date_expression, INTERVAL k DAY)
EXTRACT EXTRACT(DATE), EXTRACT(TIMESTAMP)
FORMAT_DATE
FORMAT_DATETIME
FORMAT_TIME
FORMAT_TIMESTAMP
LAST_DAY LAST_DAY Remarque : Cette fonction accepte les expressions d'entrée DATE et DATETIME.
MONTHS_BETWEEN DATE_DIFF(date_expression, date_expression, MONTH)
NEXT_DAY DATE_ADD(
  DATE_TRUNC(
    date_expression,
    WEEK(day_value)
  ),
  INTERVAL 1 WEEK
)
OADD_MONTHS DATE_SUB(
  DATE_TRUNC(
    DATE_ADD(
      date_expression,
      INTERVAL num_months MONTH
    ),
    MONTH
  ),
  INTERVAL 1 DAY
)
td_day_of_month EXTRACT(DAY FROM date_expression)
EXTRACT(DAY FROM timestamp_expression)
td_day_of_week EXTRACT(DAYOFWEEK FROM date_expression)
EXTRACT(DAYOFWEEK FROM timestamp_expression)
td_day_of_year EXTRACT(DAYOFYEAR FROM date_expression)
EXTRACT(DAYOFYEAR FROM timestamp_expression)
td_friday DATE_TRUNC(
  date_expression,
  WEEK(FRIDAY)
)
td_monday DATE_TRUNC(
  date_expression,
  WEEK(MONDAY)
)
td_month_begin DATE_TRUNC(date_expression, MONTH)
td_month_end DATE_SUB(
  DATE_TRUNC(
    DATE_ADD(
      date_expression,
      INTERVAL 1 MONTH
    ),
    MONTH
  ),
  INTERVAL 1 DAY
)
td_month_of_calendar (EXTRACT(YEAR FROM date_expression) - 1900) * 12 + EXTRACT(MONTH FROM date_expression)
td_month_of_quarter EXTRACT(MONTH FROM date_expression)
- ((EXTRACT(QUARTER FROM date_expression) - 1) * 3)
td_month_of_year EXTRACT(MONTH FROM date_expression)
EXTRACT(MONTH FROM timestamp_expression)
td_quarter_begin DATE_TRUNC(date_expression, QUARTER)
td_quarter_end DATE_SUB(
  DATE_TRUNC(
    DATE_ADD(
      date_expression,
      INTERVAL 1 QUARTER
    ),
    QUARTER
  ),
  INTERVAL 1 DAY
)
td_quarter_of_calendar (EXTRACT(YEAR FROM date_expression)
- 1900) * 4
+ EXTRACT(QUARTER FROM date_expression)
td_quarter_of_year EXTRACT(QUARTER FROM date_expression)
EXTRACT(QUARTER FROM timestamp_expression)
td_saturday DATE_TRUNC(
  date_expression,
  WEEK(SATURDAY)
)
td_sunday DATE_TRUNC(
  date_expression,
  WEEK(SUNDAY)
)
td_thursday DATE_TRUNC(
  date_expression,
  WEEK(THURSDAY)
)
td_tuesday DATE_TRUNC(
  date_expression,
  WEEK(TUESDAY)
)
td_wednesday DATE_TRUNC(
  date_expression,
  WEEK(WEDNESDAY)
)
td_week_begin DATE_TRUNC(date_expression, WEEK)
td_week_end DATE_SUB(
  DATE_TRUNC(
    DATE_ADD(
      date_expression,
      INTERVAL 1 WEEK
    ),
    WEEK
  ),
  INTERVAL 1 DAY
)
td_week_of_calendar (EXTRACT(YEAR FROM date_expression) - 1900) * 52 + EXTRACT(WEEK FROM date_expression)
td_week_of_month EXTRACT(WEEK FROM date_expression)
- EXTRACT(WEEK FROM DATE_TRUNC(date_expression, MONTH))
td_week_of_year EXTRACT(WEEK FROM date_expression)
EXTRACT(WEEK FROM timestamp_expression)
td_weekday_of_month CAST(
  CEIL(
    EXTRACT(DAY FROM date_expression)
    / 7
  ) AS INT64
)
td_year_begin DATE_TRUNC(date_expression, YEAR)
td_year_end DATE_SUB(
  DATE_TRUNC(
    DATE_ADD(
      date_expression,
      INTERVAL 1 YEAR
    ),
    YEAR
  ),
  INTERVAL 1 DAY
)
td_year_of_calendar EXTRACT(YEAR FROM date_expression)
TO_DATE PARSE_DATE
TO_TIMESTAMP PARSE_TIMESTAMP
TO_TIMESTAMP_TZ PARSE_TIMESTAMP

Fonctions de chaîne

Le tableau suivant met en correspondance les fonctions de chaîne de Teradata avec leurs équivalents dans BigQuery. BigQuery propose les fonctions de chaîne supplémentaires suivantes :

Teradata BigQuery
ASCII TO_CODE_POINTS(string_expression)[OFFSET(0)]
CHAR2HEXINT TO_HEX
CHARACTER LENGTH CHAR_LENGTH
CHARACTER LENGTH CHARACTER_LENGTH
CHR CODE_POINTS_TO_STRING(
  [mod(numeric_expression, 256)]
)
CONCAT, (|| operator) CONCAT, (|| operator)
CSV Fonction définie par l'utilisateur personnalisée.
CSVLD Fonction définie par l'utilisateur personnalisée.
FORMAT FORMAT
INDEX STRPOS(string, substring)
INITCAP Fonction définie par l'utilisateur personnalisée.
INSTR Fonction définie par l'utilisateur personnalisée.
LEFT SUBSTR(source_string, 1, length)
LENGTH LENGTH
LOWER LOWER
LPAD LPAD
LTRIM LTRIM
NGRAM Fonction définie par l'utilisateur personnalisée.
NVP Fonction définie par l'utilisateur personnalisée.
OREPLACE REPLACE
OTRANSLATE Fonction définie par l'utilisateur personnalisée.
POSITION STRPOS(string, substring)
REGEXP_INSTR STRPOS(source_string,
REGEXP_EXTRACT(source_string, regexp_string))


Remarque : Renvoie la première occurrence.
REGEXP_REPLACE REGEXP_REPLACE
REGEXP_SIMILAR IF(REGEXP_CONTAINS,1,0)
REGEXP_SUBSTR REGEXP_EXTRACT,
REGEXP_EXTRACT_ALL
REGEXP_SPLIT_TO_TABLE Fonction définie par l'utilisateur personnalisée.
REVERSE REVERSE
RIGHT SUBSTR(source_string, -1, length)
RPAD RPAD
RTRIM RTRIM
STRTOK

Remarque : Chaque caractère de l'argument de chaîne "delimiter" est considéré comme un caractère de délimitation distinct. Le délimiteur par défaut est un espace.
SPLIT(instring, delimiter)[ORDINAL(tokennum)]

Remarque : L'argument de chaîne delimiter entier est utilisé comme un délimiteur unique. Le délimiteur par défaut est une virgule.
STRTOK_SPLIT_TO_TABLE Fonction définie par l'utilisateur personnalisée.
SUBSTRING SUBSTR SUBSTR
TRIM TRIM
UPPER UPPER

Fonctions mathématiques

Le tableau suivant met en correspondance les fonctions mathématiques de Teradata avec leurs équivalents dans BigQuery. BigQuery propose les fonctions mathématiques supplémentaires suivantes :

Teradata BigQuery
ABS ABS
ACOS ACOS
ACOSH ACOSH
ASIN ASIN
ASINH ASINH
ATAN ATAN
ATAN2 ATAN2
ATANH ATANH
CEILING CEIL
CEILING CEILING
COS COS
COSH COSH
EXP EXP
FLOOR FLOOR
GREATEST GREATEST
LEAST LEAST
LN LN
LOG LOG
MOD (opérateur %) MOD
NULLIFZERO NULLIF(expression, 0)
POWER (opérateur **) POWER, POW
RANDOM RAND
ROUND ROUND
SIGN SIGN
SIN SIN
SINH SINH
SQRT SQRT
TAN TAN
TANH TANH
TRUNC TRUNC
ZEROIFNULL IFNULL(expression, 0), COALESCE(expression, 0)

Syntaxe LMD

Cette section traite des différences de syntaxe du langage de manipulation de données entre Teradata et BigQuery.

Instruction INSERT

La plupart des instructions INSERT Teradata sont compatibles avec BigQuery. Le tableau suivant présente les exceptions.

Les scripts LMD dans BigQuery présentent une sémantique de cohérence légèrement différente de celle des instructions équivalentes dans Teradata. Pour obtenir une présentation de l'isolation d'instantané et de la gestion des sessions et des transactions, consultez la section CREATE INDEX plus loin dans ce document.

Teradata BigQuery
INSERT INTO table VALUES (...); INSERT INTO table (...) VALUES (...);

Teradata propose un mot clé DEFAULT pour les colonnes n'autorisant pas les valeurs nulles.

Remarque : Dans BigQuery, l'omission des noms de colonnes dans l'instruction INSERT ne fonctionne que si les valeurs de toutes les colonnes de la table cible sont incluses dans l'ordre croissant en fonction de leurs positions ordinales.
INSERT INTO table VALUES (1,2,3);
INSERT INTO table VALUES (4,5,6);
INSERT INTO table VALUES (7,8,9);
INSERT INTO table VALUES (1,2,3),
                         (4,5,6),
                         (7,8,9);

Teradata a un concept de requête multi-instructions (MSR, multi-statement request), qui envoie plusieurs instructions INSERT à la fois. Dans BigQuery, cela n'est pas recommandé en raison de la limite de transaction implicite entre les instructions. Utilisez plutôt une instruction INSERT multivaleur.

BigQuery autorise les instructions INSERT simultanées, mais peut mettre en file d'attente les instructions UPDATE. Pour améliorer les performances, pensez à recourir aux approches suivantes :
  • Combinez plusieurs lignes en une seule instruction INSERT au lieu d'avoir une ligne par opération INSERT.
  • Combinez plusieurs instructions LMD (y compris INSERT) à l'aide d'une instruction MERGE.
  • Utilisez CREATE TABLE ... AS SELECT pour créer et remplir de nouvelles tables au lieu de UPDATE ou DELETE, en particulier lors de l'interrogation de champs partitionnés ou de rollback ou restauration.

Instruction UPDATE

La plupart des instructions UPDATE Teradata sont compatibles avec BigQuery, à l'exception des éléments suivants :

  • Lorsque vous utilisez une clause FROM, l'ordre des clauses FROM et SET est inversé dans Teradata et BigQuery.
  • En langage SQL standard, chaque instruction UPDATE doit inclure le mot clé WHERE, suivi d'une condition. Pour mettre à jour toutes les lignes de la table, utilisez WHERE true.

Nous vous recommandons de regrouper plusieurs mutations LMD au lieu d'utiliser des instructions UPDATE et INSERT uniques. Les scripts LMD dans BigQuery présentent une sémantique de cohérence légèrement différente de celle des instructions équivalentes dans Teradata. Pour obtenir une présentation de l'isolation d'instantané et de la gestion des sessions et des transactions, consultez la section CREATE INDEX plus loin dans ce document.

Le tableau suivant présente les instructions UPDATE Teradata et les instructions BigQuery qui effectuent les mêmes tâches.

Pour en savoir plus sur l'instruction UPDATE dans BigQuery, consultez les exemples d'instructions UPDATE BigQuery dans la documentation sur le LMD.

Teradata BigQuery
UPDATE table_A
FROM table_A, table_B
SET
  y = table_B.y,
  z = table_B.z + 1
WHERE table_A.x = table_B.x
  AND table_A.y IS NULL;
UPDATE table_A
SET
  y = table_B.y,
  z = table_B.z + 1
FROM table_B
WHERE table_A.x = table_B.x
  AND table_A.y IS NULL;
UPDATE table alias
SET x = x + 1
WHERE f(x) IN (0, 1);
UPDATE table
SET x = x + 1
WHERE f(x) IN (0, 1);
UPDATE table_A
FROM table_A, table_B, B
SET z = table_B.z
WHERE table_A.x = table_B.x
  AND table_A.y = table_B.y;
UPDATE table_A
SET z = table_B.z
FROM table_B
WHERE table_A.x = table_B.x
  AND table_A.y = table_B.y;

Instructions DELETE, TRUNCATE

Les instructions DELETE et TRUNCATE permettent de supprimer des lignes d'une table sans que cela n'affecte son schéma ou ses index. TRUNCATE n'est utilisé ni dans Teradata, ni dans BigQuery. Cependant, vous pouvez utiliser les instructions DELETE pour obtenir le même effet.

Dans BigQuery, l'instruction DELETE doit comporter une clause WHERE. Pour supprimer (tronquer) toutes les lignes de la table, utilisez WHERE true. Pour accélérer les opérations de troncation des tables très volumineuses, nous vous recommandons d'utiliser l'instruction CREATE OR REPLACE TABLE ... AS SELECT, en utilisant LIMIT 0 sur la même table pour la remplacer. Cependant, veillez à ajouter manuellement les informations de partitionnement et de clustering lorsque vous utilisez cette instruction.

Teradata élimine les lignes supprimées ultérieurement. Cela signifie que les opérations DELETE sont au départ plus rapides que dans BigQuery, mais qu'elles nécessitent ensuite des ressources, en particulier les opérations DELETE à grande échelle qui ont un impact sur la majeure partie d'une table. Pour utiliser une approche similaire dans BigQuery, nous vous suggérons de réduire le nombre d'opérations DELETE, par exemple en copiant les lignes à ne pas supprimer dans une nouvelle table. Vous pouvez également supprimer des partitions entières. Ces deux options sont conçues pour être plus rapides que les mutations LMD atomiques.

Pour en savoir plus sur l'instruction DELETE dans BigQuery, consultez les exemples d'instructions DELETE dans la documentation sur le LMD.

Teradata BigQuery
BEGIN TRANSACTION;
LOCKING TABLE table_A FOR EXCLUSIVE;
DELETE FROM table_A;
INSERT INTO table_A SELECT * FROM table_B;
END TRANSACTION;
Le remplacement du contenu d'une table par un résultat de requête équivaut à une transaction. Pour ce faire, vous pouvez utiliser une opération de requête ou une opération de copie.

Avec une opération de requête :

bq query --replace --destination_table table_A 'SELECT * FROM table_B';

Avec une opération de copie :

bq cp -f table_A table_B
DELETE database.table ALL; DELETE FROM table WHERE TRUE;

Ou, pour les tables très volumineuses, une méthode plus rapide :
CREATE OR REPLACE table AS SELECT * FROM table LIMIT 0;

Instruction MERGE

L'instruction MERGE peut combiner les opérations INSERT, UPDATE et DELETE en une seule instruction "upsert" et effectuer les opérations de manière atomique. L'opération MERGE doit correspondre à une ligne source au maximum pour chaque ligne cible. BigQuery et Teradata suivent tous deux la syntaxe ANSI.

L'opération MERGE de Teradata est limitée à la mise en correspondance des clés primaires dans un processeur de module d'accès (AMP, access module processor). En revanche, BigQuery n'a aucune limite de taille ou de colonne pour les opérations MERGE. Par conséquent, l'utilisation de MERGE est une optimisation utile. Toutefois, si l'instruction MERGE est principalement une suppression de grande taille, consultez les optimisations pour DELETE plus loin dans ce document.

Les scripts LMD dans BigQuery présentent une sémantique de cohérence légèrement différente de celle des instructions équivalentes dans Teradata. Par exemple, les tables SET de Teradata en mode session peuvent ignorer les doubles lors d'une opération MERGE. Pour obtenir une présentation de la gestion des tables MULTISET et SET, de l'isolation d'instantané et de la gestion des sessions et des transactions, consultez la section CREATE INDEX plus loin dans ce document.

Variables affectées par les lignes

Dans Teradata, la variable ACTIVITY_COUNT est une extension ANSI SQL Teradata renseignée avec le nombre de lignes affectées par une instruction LMD.

La variable système @@row_count de la fonctionnalité de création de scripts offre une fonction similaire. Dans BigQuery, il est plus courant de vérifier la valeur renvoyée numDmlAffectedRows dans les journaux d'audit ou dans les vues INFORMATION_SCHEMA.

Syntaxe LDD

Cette section traite des différences de syntaxe du langage de définition de données entre Teradata et BigQuery.

Instruction CREATE TABLE

La plupart des instructions CREATE TABLE Teradata sont compatibles avec BigQuery, à l'exception des éléments de syntaxe suivants, qui ne sont pas utilisés dans BigQuery :

Pour en savoir plus sur l'instruction CREATE TABLE dans BigQuery, consultez les exemples d'instructions CREATE BigQuery dans la documentation sur le LMD.

Attributs et options de colonne

Les spécifications de colonne suivantes pour l'instruction CREATE TABLE ne sont pas utilisées dans BigQuery :

Teradata étend la norme ANSI avec une option de colonne TITLE. Cette fonctionnalité peut être mise en œuvre d'une manière similaire dans BigQuery à l'aide de la description de colonne, comme indiqué dans le tableau suivant. Notez que cette option n'est pas disponible pour les vues.

Teradata BigQuery
CREATE TABLE table (
col1 VARCHAR(30) TITLE 'column desc'
);
CREATE TABLE dataset.table (
  col1 STRING
OPTIONS(description="column desc")
);

Tables temporaires

Teradata accepte les tables volatiles, qui sont souvent utilisées pour stocker des résultats intermédiaires dans des scripts. Il existe plusieurs façons d'obtenir une fonctionnalité semblable aux tables volatiles dans BigQuery :

  • CREATE TEMPORARY TABLE peut être utilisé dans la fonctionnalité de création de scripts et est valide pendant la durée de vie du script. Si la table doit exister au-delà de la durée de vie d'un script, vous pouvez utiliser les autres options de cette liste.

  • Valeur TTL de l'ensemble de données : créez un ensemble de données ayant une durée de vie courte (par exemple, 1 heure) afin que les tables créées dans cet ensemble de données soient effectivement temporaires, car elles ne persisteront pas au-delà de la durée de vie d'un script. Vous pouvez ajouter le préfixe temp à tous les noms de tables de cet ensemble de données pour indiquer clairement que les tables sont temporaires.

  • Valeur TTL de la table : créez une table ayant une durée de vie courte à l'aide d'instructions LDD semblables à ce qui suit :

    CREATE TABLE temp.name (col1, col2, ...)
    OPTIONS(expiration_timestamp=TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR));
    
  • Clause WITH : si une table temporaire n'est nécessaire que dans le même bloc, utilisez un résultat temporaire à l'aide d'une sous-requête ou d'une instruction WITH. C'est l'option la plus efficace.

Un modèle souvent utilisé dans les scripts Teradata (BTEQ) consiste à créer une table permanente, à y insérer une valeur, à utiliser cette table comme table temporaire dans les instructions en cours, puis à la supprimer ou à la tronquer. En effet, la table est utilisée comme variable constante (sémaphore). Cette approche n'est pas efficace dans BigQuery, et nous vous recommandons d'utiliser plutôt des variables réelles dans la fonctionnalité de création de scripts ou CREATE OR REPLACE avec la syntaxe de requête AS SELECT pour créer une table contenant déjà des valeurs.

Instruction CREATE VIEW

Le tableau suivant présente les équivalences entre Teradata et BigQuery pour l'instruction CREATE VIEW. Les clauses de verrouillage de table telles que LOCKING ROW FOR ACCESS ne sont pas nécessaires dans BigQuery.

Teradata BigQuery Remarques
CREATE VIEW view_name AS SELECT ... CREATE VIEW view_name AS SELECT ...
REPLACE VIEW view_name AS SELECT ... CREATE OR REPLACE VIEW
view_name AS
SELECT ...
Non compatible CREATE VIEW IF NOT EXISTS
OPTIONS(view_option_list)
AS SELECT ...
Crée une vue uniquement si elle n'existe pas dans l'ensemble de données spécifié.

Instruction CREATE [UNIQUE] INDEX

Teradata requiert des index pour toutes les tables et requiert des solutions spéciales telles que les tables MULTISET et NoPI afin de pouvoir utiliser des données non uniques ou non indexées.

BigQuery ne nécessite pas d'index. Cette section décrit les méthodes dans BigQuery permettant de créer des fonctionnalités semblables à l'utilisation des index dans Teradata, en cas de besoin réel d'une logique métier.

Indexation à des fins de performances

Comme il s'agit d'une base de données orientée colonnes avec optimisation des requêtes et du stockage, BigQuery n'a pas besoin d'index explicites. BigQuery fournit des fonctionnalités telles que le partitionnement et le clustering, ainsi que des champs imbriqués, qui peuvent améliorer l'efficacité et les performances des requêtes en optimisant le stockage des données.

Teradata n'est pas compatible avec les vues matérialisées. Cependant, il propose des index de jointure à l'aide de l'instruction CREATE JOIN INDEX, qui matérialise essentiellement les données nécessaires à une jointure. BigQuery n'a pas besoin d'index matérialisés pour accélérer les performances, tout comme il n'a pas besoin d'espace de spool dédié aux jointures.

Pour les autres cas d'optimisation, vous pouvez utiliser des vues matérialisées.

Indexation à des fins de cohérence (UNIQUE, PRIMARY INDEX)

Dans Teradata, un index unique peut être utilisé pour empêcher que des lignes contiennent des clés non uniques dans une table. Si un processus tente d'insérer ou de mettre à jour des données ayant une valeur figurant déjà dans l'index, l'opération échoue avec une violation d'index (tables MULTISET) ou les ignore en mode silencieux (tables SET).

Comme BigQuery ne fournit pas d'index explicites, une instruction MERGE peut être utilisée à la place pour insérer uniquement des enregistrements uniques dans une table cible à partir d'une table intermédiaire tout en supprimant les enregistrements en double. Cependant, il est impossible d'empêcher un utilisateur disposant de droits de modification d'insérer un enregistrement en double, car BigQuery ne se verrouille jamais pendant les opérations INSERT. Pour générer une erreur liée à des enregistrements en double dans BigQuery, vous pouvez utiliser une instruction MERGE à partir d'une table intermédiaire, comme indiqué dans l'exemple suivant.

Teradata BigQuery
CREATE [UNIQUE] INDEX name; MERGE `prototype.FIN_MERGE` t
USING `prototype.FIN_TEMP_IMPORT` m
ON t.col1 = m.col1
  AND t.col2 = m.col2
WHEN MATCHED THEN
  UPDATE SET t.col1 = ERROR(CONCAT('Encountered error for ', m.col1, ' ', m.col2))
WHEN NOT MATCHED THEN
  INSERT (col1,col2,col3,col4,col5,col6,col7,col8) VALUES(col1,col2,col3,col4,col5,col6,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP());

Le plus souvent, les utilisateurs préfèrent supprimer les doubles indépendamment afin de détecter les erreurs dans les systèmes en aval.
BigQuery n'est pas compatible avec les colonnes DEFAULT et IDENTITY (séquences).

Indexation pour obtenir le verrouillage

Teradata fournit des ressources dans le processeur de module d'accès (AMP). Les requêtes peuvent consommer les ressources de tous les AMP, d'un seul AMP ou d'un groupe d'AMP. Les instructions LDD consomment les ressources de tous les AMP et sont donc semblables à un verrou LDD global. BigQuery ne dispose pas d'un mécanisme de verrouillage comme celui-ci et peut exécuter des requêtes simultanées et des instructions INSERT dans la limite de votre quota. Seules les instructions LMD UPDATE simultanées ont des conséquences en termes de simultanéité : les opérations UPDATE réalisées sur la même partition sont mises en file d'attente pour garantir l'isolation d'instantané. Vous n'avez donc pas besoin du verrouillage pour empêcher les lectures fantômes ou les mises à jour perdues.

En raison de ces différences, les éléments Teradata suivants ne sont pas utilisés dans BigQuery :

  • ON COMMIT DELETE ROWS;
  • ON COMMIT PRESERVE ROWS;

Instructions SQL procédurales

Cette section explique comment convertir les instructions SQL procédurales utilisées dans des procédures stockées, des fonctions et des déclencheurs de Teradata en scripts, procédures ou fonctions définies par l'utilisateur BigQuery. Les administrateurs système peuvent vérifier tous ces éléments à l'aide des vues INFORMATION_SCHEMA.

Instruction CREATE PROCEDURE

Les procédures stockées sont compatibles avec la fonctionnalité de création de scripts BigQuery.

Dans BigQuery, cette fonctionnalité fait référence à toute utilisation d'instructions de contrôle, tandis que les procédures sont des scripts nommés (avec des arguments, si nécessaire) qui peuvent être appelés à partir d'autres scripts et stockés de manière permanente, en cas de besoin. Une fonction définie par l'utilisateur peut également être écrite en JavaScript.

Teradata BigQuery
CREATE PROCEDURE CREATE PROCEDURE si un nom est requis. Sinon, utilisez l'instruction sous le bloc BEGIN ou sur une seule ligne avec CREATE TEMP FUNCTION.
REPLACE PROCEDURE CREATE OR REPLACE PROCEDURE
CALL CALL

Les sections suivantes décrivent comment convertir des instructions procédurales Teradata existantes en instructions de script BigQuery ayant des fonctionnalités similaires.

Déclaration et attribution de variables

Les variables BigQuery sont valides pendant toute la durée de vie du script.

Teradata BigQuery
DECLARE DECLARE
SET SET

Gestionnaires de conditions d'erreur

Teradata utilise des gestionnaires sur les codes d'état dans les procédures à des fins de contrôle des erreurs. Dans BigQuery, la gestion des erreurs est une fonctionnalité essentielle du flux de contrôle principal, semblable à ce que d'autres langages fournissent avec les blocs TRY ... CATCH.

Teradata BigQuery
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ... EXCEPTION WHEN ERROR THEN
SIGNAL sqlstate RAISE message
DECLARE CONTINUE HANDLER FOR SQLSTATE VALUE 23505; Les gestionnaires d'exceptions qui se déclenchent pour certaines conditions d'erreur ne sont pas utilisés par BigQuery.

Nous vous recommandons d'utiliser les instructions ASSERT dans lesquelles les conditions de sortie sont utilisées pour les vérifications préalables ou le débogage, car elles sont conformes à la norme ANSI SQL:2011.

La variable SQLSTATE de Teradata est semblable à la variable système @@error de BigQuery. Dans BigQuery, il est plus courant de rechercher les erreurs à l'aide de la journalisation d'audit ou des vues INFORMATION_SCHEMA.

Déclarations et opérations de curseurs

Étant donné que BigQuery n'accepte pas les curseurs ni les sessions, il n'utilise pas les instructions suivantes :

Instructions SQL dynamiques

La fonctionnalité de script de BigQuery est compatible avec les instructions SQL dynamiques telles que celles présentées dans le tableau suivant.

Teradata BigQuery
EXECUTE IMMEDIATE sql_str; EXECUTE IMMEDIATE sql_str;
EXECUTE stmt_id [USING var,...]; EXECUTE IMMEDIATE stmt_id USING var;

Les instructions SQL dynamiques suivantes ne sont pas utilisées dans BigQuery :

Instructions de flux de contrôle

La fonctionnalité de création de scripts de BigQuery accepte les instructions de flux de contrôle telles que celles présentées dans le tableau suivant.

Teradata BigQuery
IF condition THEN stmts ELSE stmts END IF IF condition THEN stmts ELSE stmts END IF
label: LOOP stmts END LOOP label; Les constructions de blocs de style GOTO ne sont pas utilisées dans BigQuery.

Nous vous recommandons de les réécrire en tant que fonctions définies par l'utilisateur ou d'utiliser des instructions ASSERT où elles sont utilisées pour le traitement des erreurs.
REPEAT stmts UNTIL condition END REPEAT; WHILE condition DO stmts END WHILE
LEAVE outer_proc_label; L'instruction LEAVE n'est pas utilisée pour les blocs de style GOTO. Elle est utilisée comme synonyme de BREAK pour quitter une boucle WHILE.
LEAVE label; L'instruction LEAVE n'est pas utilisée pour les blocs de style GOTO. Elle est utilisée comme synonyme de BREAK pour quitter une boucle WHILE.
WITH RECURSIVE temp_table AS ( ... ); Les requêtes récurrentes (également appelées expressions de table commune (CTE) récurrentes) ne sont pas utilisées dans BigQuery. Elles peuvent être réécrites à l'aide de tableaux de UNION ALL.

Les instructions de flux de contrôle suivantes ne sont pas utilisées dans BigQuery, car BigQuery n'utilise pas de curseur ni de session :

Instructions SQL de métadonnées et de transactions

Teradata BigQuery
HELP TABLE table_name;
HELP VIEW view_name;
SELECT
 * EXCEPT(is_generated, generation_expression, is_stored, is_updatable)
FROM
 mydataset.INFORMATION_SCHEMA.COLUMNS;
WHERE
 table_name=table_name


La même requête est valide pour obtenir des informations de colonne pour les vues.
Pour en savoir plus, consultez la vue Colonnes dans BigQuery INFORMATION_SCHEMA.
SELECT * FROM dbc.tables WHERE tablekind = 'T';

(vue DBC Teradata)
SELECT
 * EXCEPT(is_typed)
FROM
mydataset.INFORMATION_SCHEMA.TABLES;


Pour en savoir plus, consultez la page Présentation des vues INFORMATION_SCHEMA de BigQuery.
HELP STATISTICS table_name; APPROX_COUNT_DISTINCT(col)
COLLECT STATS USING SAMPLE ON table_name column (...); Non utilisé dans BigQuery.
LOCKING TABLE table_name FOR EXCLUSIVE; BigQuery utilise toujours l'isolation d'instantané. Pour en savoir plus, consultez la section Garanties de cohérence plus loin dans ce document.
SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL ... BigQuery utilise toujours l'isolation d'instantané. Pour en savoir plus, consultez la section Garanties de cohérence plus loin dans ce document.
BEGIN TRANSACTION;
SELECT ...
END TRANSACTION;
BigQuery utilise toujours l'isolation d'instantané. Pour en savoir plus, consultez la section Garanties de cohérence plus loin dans ce document.
EXPLAIN ... Non utilisé dans BigQuery.

L'explication du plan de requête dans l'interface utilisateur Web de BigQuery et l'allocation d'emplacements visible dans les vues INFORMATION_SCHEMA et dans la journalisation d'audit dans Cloud Monitoring sont des fonctionnalités similaires.

Instructions SQL multi-instructions et multilignes

Teradata accepte les transactions (sessions), et donc les instructions séparées par un point-virgule qui sont systématiquement exécutées ensemble. BigQuery les accepte également dans sa fonctionnalité de création de scripts, mais exécute ces instructions en tant que requêtes individuelles sans rollback.

Codes et messages d'erreur

Les codes d'erreur Teradata et BigQuery sont différents. En fournissant une API REST, BigQuery repose principalement sur des codes d'état HTTP et des messages d'erreur détaillés.

Si votre logique d'application détecte actuellement les erreurs suivantes, essayez d'éliminer la source de l'erreur, car BigQuery ne renverra pas les mêmes codes d'erreur.

  • SQLSTATE = '02000' : "Ligne introuvable"
  • SQLSTATE = '21000' : "Violation de cardinalité (index unique)"
  • SQLSTATE = '22000' : "Violation de données (type de données)"
  • SQLSTATE = '23000' : "Violation de contrainte"

Dans BigQuery, il est plus courant d'utiliser les vues INFORMATION_SCHEMA ou la journalisation d'audit pour afficher le détail des erreurs.

Pour en savoir plus sur la gestion des erreurs dans la fonctionnalité de création de scripts, consultez les sections suivantes.

Garanties de cohérence et isolation de transaction

Teradata et BigQuery sont tous deux atomiques, c'est-à-dire conformes à la norme ACID au niveau de chaque mutation sur de nombreuses lignes. Par exemple, une opération MERGE est complètement atomique, même avec plusieurs valeurs insérées et mises à jour.

Transactions

Teradata fournit le niveau d'isolation de transaction "Read Uncommitted" (lecture des données non validées) ou "Serializable" (sérialisable) lors de l'exécution en mode session (au lieu du mode autocommit). Dans le meilleur des cas, Teradata obtient une isolation strictement sérialisable en utilisant un verrouillage pessimiste sur un hachage de ligne dans toutes les colonnes de lignes de toutes les partitions. Les interblocages sont possibles. Le langage LDD impose toujours une limite de transaction. Les tâches Teradata FastLoad s'exécutent indépendamment, mais uniquement sur des tables vides.

BigQuery permet d'assurer un contrôle de simultanéité optimiste (le premier à effectuer un commit l'emporte) avec isolation d'instantané, où une requête lit les dernières données validées avant le démarrage de la requête. Cette approche garantit le même niveau de cohérence par ligne, par mutation et entre les lignes d'une même instruction LMD, tout en évitant les interblocages. Si plusieurs instructions UPDATE sont effectuées sur la même table, BigQuery bascule vers le contrôle de simultanéité pessimiste et met en file d'attente plusieurs instructions UPDATE, en effectuant de nouvelles tentatives en cas de conflits. Les instructions LMD INSERT et les tâches de chargement peuvent s'exécuter simultanément et indépendamment pour ajouter des données aux tables. Cependant, BigQuery ne fournit pas de session ni de limite de transaction manuelle explicite.

Rollback

Teradata accepte deux modes de rollback de session, le mode session ANSI et le mode session Teradata (SET SESSION CHARACTERISTICS et SET SESSION TRANSACTION), selon le mode de rollback souhaité. En cas d'échec, le rollback de la transaction peut ne pas être possible.

La fonctionnalité de création de scripts de BigQuery permet l'exécution dépendante et en série des instructions, mais n'effectue pas de rollback vers des mises à jour antérieures si des mises à jour plus récentes échouent.

Il n'y a ni instruction ABORT, ni instruction ROLLBACK dans BigQuery.

Comme il n'existe pas encore de limite de transaction explicite dans BigQuery, il ne comporte pas non plus de concept de rollback explicite. L'approche recommandée consiste à utiliser des décorateurs de table ou la clause FOR SYSTEM_TIME AS OF (fonctionnalités temporelles) dans BigQuery. De cette façon, vous pouvez définir explicitement un instantané discret avant une exécution par lot qui inclut les modifications du LDD. Les fonctionnalités temporelles sont toujours activées dans BigQuery sans frais supplémentaires. Par conséquent, il n'est pas nécessaire de spécifier explicitement FALLBACK ni d'optimiser le spooling ou la journalisation.

Limites des bases de données

Vérifiez toujours les derniers quotas et les dernières limites dans la documentation publique BigQuery. Les utilisateurs ayant un volume de requêtes important peuvent demander l'augmentation de nombreux quotas en contactant l'équipe d'assistance Cloud. Le tableau suivant présente une comparaison des limites de base de données pour Teradata et BigQuery.

Limite Teradata BigQuery
Tables par base de données Pas de restriction Pas de restriction
Colonnes par table 2 048 10 000
Taille maximale des lignes 1 Mo 100 Mo
Longueur des noms de colonnes et de tables 128 caractères Unicode 16 384 caractères Unicode
Nombre de lignes par table Illimité Illimité
Longueur maximale des requêtes SQL 1 Mo 1 Mo (longueur maximale des requêtes non résolues en SQL standard)
12 Mo (longueur maximale des requêtes résolues en ancien SQL et en SQL standard)

Traitement par flux :
  • 10 Mo (taille maximale des requêtes HTTP)
  • 10 000 (nombre maximal de lignes par requête)
Taille maximale des requêtes et des réponses 7 Mo (requête), 16 Mo (réponse) 10 Mo (requête) et 10 Go (réponse), ou presque illimitée si vous utilisez la pagination ou l'API Cloud Storage
Nombre maximal de sessions simultanées 120 par moteur d'analyse 100 requêtes simultanées (ce nombre peut être augmenté avec une réservation d'emplacement), 300 requêtes API simultanées par utilisateur
Nombre maximal de chargements (rapides) simultanés 30 (Valeur par défaut : 5) Aucune limite de simultanéité ; les tâches sont mises en file d'attente. 100 000 tâches de chargement par projet et par jour