SnowConvert AI - Redshift - SQL Statements¶
Translation reference for all the supported statements by SnowConvert AI for Redshift.
CALL¶
Description¶
Exécute une procédure stockée. La commande CALL doit inclure le nom de la procédure et les valeurs des arguments d’entrée. Vous devez appeler une procédure stockée en utilisant l’instruction CALL. (Référence linguistique Redshift SQL CALL).
Grammar Syntax¶
CALL sp_name ( [ argument ] [, ...] )
Modèles d’échantillons de sources¶
Scénario de base¶
Code d’entrée :¶
Redshift¶
CREATE PROCEDURE sp_insert_values(IN arg1 INT, IN arg2 DATE)
LANGUAGE plpgsql
AS
$$
BEGIN
INSERT INTO event VALUES (arg1, arg2);
END;
$$;
CALL sp_insert_values(1, CURRENT_DATE);
Code de sortie :¶
Redshift¶
CREATE PROCEDURE sp_insert_values (arg1 INT, arg2 DATE)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "07/11/2025", "domain": "no-domain-provided" }}'
AS
$$
BEGIN
INSERT INTO event
VALUES (:arg1, : arg2);
END;
$$;
CALL sp_insert_values(1, CURRENT_DATE());
Appel en mode paramètres de sortie (INOUT, OUT)¶
Code d’entrée :¶
Redshift¶
CREATE OR REPLACE PROCEDURE sp_calculate_sum_product(IN a NUMERIC, IN b NUMERIC, INOUT sum_result NUMERIC, INOUT product_result NUMERIC)
LANGUAGE plpgsql
AS $$
BEGIN
sum_result := a + b;
product_result := a * b;
END;
$$;
CREATE OR REPLACE PROCEDURE call_sp_calculate_sum_product()
LANGUAGE plpgsql
AS $$
DECLARE
sum_value NUMERIC DEFAULT null;
product_value NUMERIC DEFAULT null;
BEGIN
CALL sp_calculate_sum_product(FLOOR(20.5)::NUMERIC, CEIL(20.7)::NUMERIC, sum_value, product_value);
INSERT INTO test VALUES (sum_value, product_value);
END;
$$;
CALL call_sp_calculate_sum_product();
Code de sortie :¶
Redshift¶
CREATE OR REPLACE PROCEDURE sp_calculate_sum_product (a NUMERIC, b NUMERIC, sum_result OUT NUMERIC, product_result OUT NUMERIC)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "07/11/2025", "domain": "no-domain-provided" }}'
AS $$
BEGIN
sum_result := a + b;
product_result := a * b;
END;
$$;
CREATE OR REPLACE PROCEDURE call_sp_calculate_sum_product ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "07/11/2025", "domain": "no-domain-provided" }}'
AS $$
DECLARE
sum_value NUMERIC DEFAULT null;
product_value NUMERIC DEFAULT null;
BEGIN
CALL sp_calculate_sum_product(FLOOR(20.5)::NUMERIC, CEIL(20.7)::NUMERIC, : sum_value, : product_value);
INSERT INTO test
VALUES (:sum_value, : product_value);
END;
$$;
CALL call_sp_calculate_sum_product();
Problèmes connus¶
Output parameters from calls outside procedures won’t work.
CREATE DATABASE¶
Grammar Syntax¶
CREATE DATABASE database_name
[ { [ WITH ]
[ OWNER [=] db_owner ]
[ CONNECTION LIMIT { limit | UNLIMITED } ]
[ COLLATE { CASE_SENSITIVE | CASE_INSENSITIVE } ]
[ ISOLATION LEVEL { SERIALIZABLE | SNAPSHOT } ]
}
| { [ WITH PERMISSIONS ] FROM DATASHARE datashare_name ] OF [ ACCOUNT account_id ] NAMESPACE namespace_guid }
| { FROM { { ARN '<arn>' } { WITH DATA CATALOG SCHEMA '<schema>' | WITH NO DATA CATALOG SCHEMA } }
| { INTEGRATION '<integration_id>'} }
| { IAM_ROLE {default | 'SESSION' | 'arn:aws:iam::<account-id>:role/<role-name>' } }
Pour plus d’informations, veuillez vous référer à la [CREATE DATABASE
documentation Redshift] (https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_DATABASE.html).
Modèles d’échantillons de sources¶
Échantillons de base¶
Code d’entrée :¶
Redshift¶
CREATE DATABASE database_name;
Code de sortie :¶
Snowflake¶
CREATE DATABASE IF NOT EXISTS database_name
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "09/25/2024" }}';
Clause Collate¶
Code d’entrée :¶
Redshift¶
CREATE DATABASE database_collate
COLLATE CASE_INSENSITIVE;
Code de sortie :¶
Snowflake¶
CREATE DATABASE IF NOT EXISTS database_collate
DEFAULT_DDL_COLLATION='en-ci'
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "09/24/2024" }}';
Clause Connection Limit¶
Code d’entrée :¶
Redshift¶
CREATE DATABASE database_connection
CONNECTION LIMIT UNLIMITED;
Code de sortie :¶
Snowflake¶
CREATE DATABASE IF NOT EXISTS database_connection
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "09/24/2024" }}';
Avertissement
La clause de limite de connexion est supprimée puisque la connectivité dans Snowflake est gérée par l’entrepôt. Plus d’informations ici.
Clause From ARN¶
Code d’entrée :¶
Redshift¶
CREATE DATABASE database_fromARN
FROM ARN 'arn' WITH NO DATA CATALOG SCHEMA IAM_ROLE 'arn:aws:iam::<account-id>:role/<role-name';
Code de sortie :¶
Snowflake¶
CREATE DATABASE IF NOT EXISTS database_fromARN
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "09/24/2024" }}';
Avertissement
Cette clause est supprimée car elle sert à référencer des ressources Amazon, non valables dans Snowflake.
Clause Owner¶
Code d’entrée¶
Redshift¶
CREATE DATABASE database_Owner
OWNER db_owner
ENCODING 'encoding';
Code de sortie¶
Snowflake¶
CREATE DATABASE IF NOT EXISTS database_Owner
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "09/24/2024" }}';
Avertissement
Sachez que dans ce cas, la clause du propriétaire est supprimée du code car les bases de données de Snowflake sont détenues par des rôles, et non par des utilisateurs individuels. Pour plus d’informations, veuillez vous référer à la documentation de Snowflake GRANT OWNERSHIP
.
Clause Isolation Level¶
Code d’entrée¶
Redshift¶
CREATE DATABASE database_Isolation
ISOLATION LEVEL SNAPSHOT;
Code de sortie¶
Snowflake¶
CREATE DATABASE IF NOT EXISTS database_Isolation
ISOLATION LEVEL SNAPSHOT !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'IsolationLevelAttribute' NODE ***/!!!
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "09/24/2024" }}';
Note
La transformation du niveau d’isolement est planifiée pour être réalisée à l’avenir.
EWIs connexes¶
SSC-EWI-0073 : En attente de l’examen de l’équivalence fonctionnelle
CREATE EXTERNAL TABLE¶
Description ¶
Currently SnowConvert AI is transforming CREATE EXTERNAL TABLES
to regular tables, that implies additional effort because data stored in external RedShift tables must be transferred to the Snowflake database.
Grammar Syntax ¶
CREATE EXTERNAL TABLE
external_schema.table_name
(column_name data_type [, …] )
[ PARTITIONED BY (col_name data_type [, … ] )]
[ { ROW FORMAT DELIMITED row_format |
ROW FORMAT SERDE 'serde_name'
[ WITH SERDEPROPERTIES ( 'property_name' = 'property_value' [, ...] ) ] } ]
STORED AS file_format
LOCATION { 's3://bucket/folder/' | 's3://bucket/manifest_file' }
[ TABLE PROPERTIES ( 'property_name'='property_value' [, ...] ) ]
CREATE EXTERNAL TABLE
external_schema.table_name
[ PARTITIONED BY (col_name [, … ] ) ]
[ ROW FORMAT DELIMITED row_format ]
STORED AS file_format
LOCATION { 's3://bucket/folder/' }
[ TABLE PROPERTIES ( 'property_name'='property_value' [, ...] ) ]
AS
{ select_statement }
Cliquez ici pour accéder à la spécification de cette syntaxe.
Modèles d’échantillons de sources¶
Code d’entrée :¶
Redshift¶
CREATE EXTERNAL TABLE
external_schema.sales_data
(
sales_id INT,
product_id INT,
sales_amount DECIMAL(10, 2),
sales_date DATE
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS TEXTFILE
LOCATION 's3://mybucket/sales_data/';
Code de sortie :¶
Snowflake¶
--** SSC-FDM-0004 - EXTERNAL TABLE TRANSLATED TO REGULAR TABLE **
CREATE TABLE external_schema.sales_data
(
sales_id INT,
product_id INT,
sales_amount DECIMAL(10, 2),
sales_date DATE
)
--ROW FORMAT DELIMITED
--FIELDS TERMINATED BY ','
--STORED AS TEXTFILE
--LOCATION 's3://mybucket/sales_data/'
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "09/17/2024" }}'
;
Créer une table externe AS¶
Code d’entrée :¶
Redshift¶
CREATE EXTERNAL TABLE spectrum.partitioned_lineitem
PARTITIONED BY (l_shipdate, l_shipmode)
STORED AS parquet
LOCATION 'S3://amzn-s3-demo-bucket/cetas/partitioned_lineitem/'
AS SELECT l_orderkey, l_shipmode, l_shipdate, l_partkey FROM local_table;
Code de sortie :¶
Snowflake¶
--** SSC-FDM-0004 - EXTERNAL TABLE TRANSLATED TO REGULAR TABLE **
CREATE TABLE spectrum.partitioned_lineitem
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "09/17/2024" }}'
--PARTITIONED BY (l_shipdate, l_shipmode)
--STORED AS parquet
--LOCATION 'S3://amzn-s3-demo-bucket/cetas/partitioned_lineitem/'
AS SELECT l_orderkey, l_shipmode, l_shipdate, l_partkey FROM
local_table;
Recommandations¶
Pour l’utilisation de Create External Table dans Snowflake, vous pouvez vous référer à la documentation de Snowflake.
EWIs connexes¶
SSC-FDM-0004 : table externe traduite en table normale
CREATE MATERIALIZED VIEW¶
Description¶
In SnowConvert AI, Redshift Materialized Views are transformed into Snowflake Dynamic Tables. To properly configure Dynamic Tables, two essential parameters must be defined: TARGET_LAG and WAREHOUSE. If these parameters are left unspecified in the configuration options, SnowConvert AI will default to preassigned values during the conversion, as demonstrated in the example below.
Pour plus d’informations sur les vues matérialisées, cliquez ici
Pour plus de détails sur les paramètres nécessaires pour les tables dynamiques, cliquez ici.
Grammar Syntax¶
Voici la syntaxe SQL pour créer une vue dans Amazon Redshift. Cliquez ici pour accéder à la spécification de Redshift pour cette syntaxe.
CREATE MATERIALIZED VIEW mv_name
[ BACKUP { YES | NO } ]
[ table_attributes ]
[ AUTO REFRESH { YES | NO } ]
AS query
Modèles d’échantillons de sources¶
Code d’entrée :¶
Redshift¶
CREATE MATERIALIZED VIEW mv_baseball AS
SELECT ball AS baseball FROM baseball_table;
Code de sortie :¶
Snowflake¶
CREATE DYNAMIC TABLE mv_baseball
--** SSC-FDM-0031 - DYNAMIC TABLE REQUIRED PARAMETERS SET BY DEFAULT **
TARGET_LAG='1 day'
WAREHOUSE=UPDATE_DUMMY_WAREHOUSE
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "11/26/2024", "domain": "test" }}'
AS
SELECT ball AS baseball FROM
baseball_table;
Note
Pour la documentation sur les attributs des tables, vous pouvez consulter la documentation suivante :
Avertissement
Les clauses BACKUP et AUTO REFRESH sont supprimées car elles ne sont pas applicables au tableau dynamique de Snowflake
Related Ewis¶
SSC-FDM-0031 : Paramètres requis de la table dynamique définis par défaut
CREATE SCHEMA¶
Grammar Syntax¶
CREATE SCHEMA [ IF NOT EXISTS ] schema_name [ AUTHORIZATION username ]
[ QUOTA {quota [MB | GB | TB] | UNLIMITED} ] [ schema_element [ ... ]
CREATE SCHEMA AUTHORIZATION username [ QUOTA {quota [MB | GB | TB] | UNLIMITED} ]
[ schema_element [ ... ] ]
Pour plus d’informations, veuillez vous référer à la documentation Redshift CREATE SCHEMA
.
Modèles d’échantillons de sources¶
Échantillons de base¶
Code d’entrée :¶
Redshift¶
CREATE SCHEMA s1;
CREATE SCHEMA IF NOT EXISTS s2;
CREATE SCHEMA s3
CREATE TABLE t1
(
col1 INT
)
CREATE VIEW v1 AS SELECT * FROM t1;
Code de sortie :¶
Snowflake¶
CREATE SCHEMA IF NOT EXISTS s1
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "09/23/2024" }}'
;
CREATE SCHEMA IF NOT EXISTS s2
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "09/23/2024" }}'
;
CREATE SCHEMA IF NOT EXISTS s3
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "09/23/2024" }}'
;
CREATE TABLE t1
(
col1 INT
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "09/23/2024" }}'
;
CREATE VIEW v1
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "09/23/2024" }}'
AS SELECT * FROM
t1;
Clause Quota¶
Code d’entrée :¶
Redshift¶
CREATE SCHEMA s1 QUOTA UNLIMITED;
CREATE SCHEMA s2 QUOTA 10 TB;
Code de sortie :¶
Snowflake¶
CREATE SCHEMA IF NOT EXISTS s1
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "09/23/2024" }}'
;
CREATE SCHEMA IF NOT EXISTS s2
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "09/23/2024" }}'
;
Note
Dans Snowflake, il n’est pas possible de définir un quota par régime. La gestion du stockage se fait au niveau du compte et de l’entrepôt, et Snowflake s’en charge automatiquement. C’est pourquoi il est supprimé du code.
EWIs connexes¶
Il n’y a pas de problème connu.
CREATE FUNCTION¶
Description¶
This command defines a user-defined function (UDF) within the database. These functions encapsulate reusable logic that can be invoked within SQL queries.
Grammar Syntax¶
Voici la syntaxe SQL pour créer une vue dans Amazon Redshift. Cliquez ici pour accéder à la spécification de Redshift pour cette syntaxe.
CREATE [ OR REPLACE ] FUNCTION f_function_name
( { [py_arg_name py_arg_data_type |
sql_arg_data_type } [ , ... ] ] )
RETURNS data_type
{ VOLATILE | STABLE | IMMUTABLE }
AS $$
{ python_program | SELECT_clause }
$$ LANGUAGE { plpythonu | sql }
SQL Language¶
Volatility category¶
In Snowflake, VOLATILE
and IMMUTABLE
function volatility are functionally equivalent. Given that STABLE
is inherently transformed to the default VOLATILE
behavior, explicit use of STABLE
will be delete.
Code d’entrée :¶
Redshift¶
CREATE OR REPLACE FUNCTION get_sale(INTEGER)
RETURNS FLOAT
STABLE
AS $$
SELECT price FROM sales where id = $1
$$ LANGUAGE SQL;
Code de sortie :¶
Snowflake¶
CREATE OR REPLACE FUNCTION get_sale (SC_ARG1 INTEGER)
RETURNS FLOAT
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "07/11/2025", "domain": "no-domain-provided" }}'
AS $$
SELECT price FROM
sales
where id = SC_ARG1
$$
;
Python Language¶
Within the SnowConvert AI scope, the Python language for CREATE FUNCTION
statements is not supported. Consequently, the language plpythonu
will be flagged with an EWI (SSC-EWI-0073), and its body could appear with parsing errors.
Code d’entrée :¶
Redshift¶
create function f_py_greater (a float, b float)
returns float
stable
as $$
if a > b:
return a
return b
$$ language plpythonu;
Code de sortie :¶
Snowflake¶
create function f_py_greater (a float, b float)
returns float
language plpythonu !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'LANGUAGE PLPythonU' NODE ***/!!!
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "07/11/2025", "domain": "no-domain-provided" }}'
as $$
-- ** SSC-EWI-0001 - UNRECOGNIZED TOKEN ON LINE '5' COLUMN '3' OF THE SOURCE CODE STARTING AT 'if'. EXPECTED 'STATEMENT' GRAMMAR. LAST MATCHING TOKEN WAS 'if' ON LINE '5' COLUMN '3'. **
-- if a > b:
-- return a
-- return b
$$
;
EWIs connexes¶
Il n’y a pas de problème connu.
CREATE VIEW¶
Description¶
Cette commande crée une vue dans une base de données, qui est exécutée chaque fois que la vue est référencée dans une requête. En utilisant la clause WITH NO SCHEMA BINDING, vous pouvez créer des vues sur une table externe ou sur des objets qui n’existent pas encore. Cette clause exige toutefois que vous indiquiez le nom qualifié de l’objet ou de la table auquel vous faites référence.
Grammar Syntax¶
Voici la syntaxe SQL pour créer une vue dans Amazon Redshift. Cliquez ici pour accéder à la spécification de Redshift pour cette syntaxe.
CREATE [ OR REPLACE ] VIEW name [ ( column_name [, ...] ) ] AS query
[ WITH NO SCHEMA BINDING ]
Modèles d’échantillons de sources¶
Compte tenu des clauses obligatoires et facultatives de la commande Redshift, la sortie après migration vers Snowflake est très similaire.
Code d’entrée :¶
Redshift¶
CREATE VIEW myuser
AS
SELECT lastname FROM users;
CREATE VIEW myuser2
AS
SELECT lastname FROM users2
WITH NO SCHEMA BINDING;
Code de sortie :¶
Snowflake¶
CREATE VIEW myuser
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "01/16/2025", "domain": "test" }}'
AS
SELECT lastname FROM
users;
CREATE VIEW myuser2
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "01/16/2025", "domain": "test" }}'
AS
SELECT lastname FROM
users2
!!!RESOLVE EWI!!! /*** SSC-EWI-RS0003 - WITH NO SCHEMA BINDING STATEMENT CAN NOT BE REMOVED DUE TO MISSING REFERENCES. ***/!!!
WITH NO SCHEMA BINDING;
Il existe cependant quelques exceptions d’une clause non prise en charge de Redshift, c’est pourquoi un EWI a été mise en œuvre pour couvrir ce cas.
EWIs connexes¶
SSC-EWI-RS0003 : l’instruction « With no schema binding » n’est pas prise en charge dans Snowflake.
DELETE¶
Description¶
Supprime les lignes des tables. (Référence linguistique Redshift SQL instruction Delete).
Note
Cette syntaxe est entièrement prise en charge par Snowflake.
Grammar Syntax¶
[ WITH [RECURSIVE] common_table_expression [, common_table_expression , ...] ]
DELETE [ FROM ] { table_name | materialized_view_name }
[ USING table_name, ... ]
[ WHERE condition ]
Modèles d’échantillons de sources¶
Setup data¶
Redshift¶
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
department VARCHAR(255),
manager_id INT REFERENCES employees(id)
);
INSERT INTO employees (id, name, department, manager_id) VALUES
(1, 'Alice', 'Sales', 2),
(2, 'Bob', 'Sales', 1),
(3, 'Charlie', 'Sales', 1),
(4, 'David', 'Marketing', 2),
(5, 'Eve', 'Marketing', 4),
(6, 'Frank', 'Marketing', 4),
(7, 'Grace', 'Engineering', 6),
(8, 'Helen', 'Engineering', 7),
(9, 'Ivy', 'Engineering', 7),
(10, 'John', 'Sales', 3),
(11, 'Joe', 'Engineering', 5);
CREATE TABLE departments (
department_name VARCHAR(255)
);
INSERT INTO departments (department_name) VALUES
('Sales'),
('Marketing'),
('Engineering');
Clause From¶
Mettez à jour une table en référençant des informations provenant d’autres tables. Dans Redshift, le mot-clé FROM est facultatif, mais dans Snowflake, il est obligatoire. Par conséquent, il sera ajouté dans les cas où elle est manquante.
Code d’entrée :¶
Redshift¶
DELETE employees;
SELECT * FROM employees ORDER BY id;
Result¶
ID |
NAME |
DEPARTMENT |
MANAGER_ID |
---|---|---|---|
Code de sortie :¶
Snowflake¶
DELETE FROM
employees;
SELECT * FROM employees ORDER BY id;
Result¶
ID |
NAME |
DEPARTMENT |
MANAGER_ID |
---|---|---|---|
Clause Where¶
Limite les mises à jour aux lignes qui répondent à une condition. Lorsque la condition est remplie, les colonnes SET spécifiées sont mises à jour. La condition peut être un simple prédicat sur une colonne ou une condition basée sur le résultat d’une sous-requête. Cette clause est pleinement équivalente dans Snowflake.
Code d’entrée :¶
Redshift¶
DELETE FROM employees
WHERE department = 'Marketing';
SELECT * FROM employees
ORDER BY id;
Result¶
ID |
NAME |
DEPARTMENT |
MANAGER_ID |
---|---|---|---|
1 |
Alice |
Sales |
2 |
2 |
Bob |
Sales |
1 |
3 |
Charlie |
Sales |
1 |
7 |
Grace |
Engineering |
6 |
8 |
Helen |
Engineering |
7 |
9 |
Ivy |
Engineering |
7 |
10 |
John |
Sales |
3 |
11 |
Joe |
Engineering |
5 |
Code de sortie :¶
Snowflake¶
DELETE FROM
employees
WHERE department = 'Marketing';
SELECT * FROM
employees
ORDER BY id;
Result¶
ID |
NAME |
DEPARTMENT |
MANAGER_ID |
---|---|---|---|
1 |
Alice |
Sales |
2 |
2 |
Bob |
Sales |
1 |
3 |
Charlie |
Sales |
1 |
7 |
Grace |
Engineering |
6 |
8 |
Helen |
Engineering |
7 |
9 |
Ivy |
Engineering |
7 |
10 |
John |
Sales |
3 |
11 |
Joe |
Engineering |
5 |
Clause Using¶
Cette clause introduit une liste de tables lorsque des tables supplémentaires sont référencées dans la condition de la clause WHERE. Cette clause est pleinement équivalente dans Snowflake.
Code d’entrée :¶
Redshift¶
DELETE FROM employees
USING departments d
WHERE employees.department = d.department_name
AND d.department_name = 'Sales';
SELECT * FROM employees ORDER BY id;
Result¶
ID |
NAME |
DEPARTMENT |
MANAGER_ID |
---|---|---|---|
4 |
David |
Marketing |
2 |
5 |
Eve |
Marketing |
4 |
6 |
Frank |
Marketing |
4 |
7 |
Grace |
Engineering |
6 |
8 |
Helen |
Engineering |
7 |
9 |
Ivy |
Engineering |
7 |
11 |
Joe |
Engineering |
5 |
Code de sortie :¶
Snowflake¶
DELETE FROM employees
USING departments d
WHERE employees.department = d.department_name
AND d.department_name = 'Sales';
SELECT * FROM employees ORDER BY id;
Result¶
ID |
NAME |
DEPARTMENT |
MANAGER_ID |
---|---|---|---|
4 |
David |
Marketing |
2 |
5 |
Eve |
Marketing |
4 |
6 |
Frank |
Marketing |
4 |
7 |
Grace |
Engineering |
6 |
8 |
Helen |
Engineering |
7 |
9 |
Ivy |
Engineering |
7 |
11 |
Joe |
Engineering |
5 |
Clause WITH¶
Cette clause spécifie une ou plusieurs expressions de table communes (CTE). Les noms des colonnes de sortie sont facultatifs pour les CTEs non récursifs, mais obligatoires pour ceux qui sont récursifs.
Cette clause ne pouvant être utilisée dans une instruction DELETE, elle est transformée en tables temporaires avec leurs requêtes correspondantes. Après l’exécution de l’instruction DELETE, ces tables temporaires sont supprimées afin de faire le ménage, de libérer des ressources et d’éviter les collisions de noms lors de la création de tables au cours de la même session. En outre, s’il existe une table normale portant le même nom, elle sera à nouveau prioritaire, puisque la table temporaire a la priorité sur toute autre table portant le même nom dans la même session.
CTE non récursif¶
Code d’entrée :¶
Redshift¶
WITH sales_employees AS (
SELECT id
FROM employees
WHERE department = 'Sales'
), engineering_employees AS (
SELECT id
FROM employees
WHERE department = 'Engineering'
)
DELETE FROM employees
WHERE id IN (SELECT id FROM sales_employees)
OR id IN (SELECT id FROM engineering_employees);
SELECT * FROM employees ORDER BY id;
Result¶
ID |
NAME |
DEPARTMENT |
MANAGER_ID |
---|---|---|---|
4 |
David |
Marketing |
2 |
5 |
Eve |
Marketing |
4 |
6 |
Frank |
Marketing |
4 |
Code de sortie :¶
Snowflake¶
CREATE TEMPORARY TABLE sales_employees AS
SELECT id
FROM employees
WHERE department = 'Sales';
CREATE TEMPORARY TABLE engineering_employees AS
SELECT id
FROM employees
WHERE department = 'Engineering';
DELETE FROM
employees
WHERE id IN (SELECT id FROM sales_employees)
OR id IN (SELECT id FROM engineering_employees);
DROP TABLE sales_employees;
DROP TABLE engineering_employees;
SELECT * FROM
employees
ORDER BY id;
Result¶
ID |
NAME |
DEPARTMENT |
MANAGER_ID |
---|---|---|---|
4 |
David |
Marketing |
2 |
5 |
Eve |
Marketing |
4 |
6 |
Frank |
Marketing |
4 |
CTE récursif¶
Code d’entrée :¶
Redshift¶
WITH RECURSIVE subordinate_hierarchy(id, name, department, level) AS (
SELECT id, name, department, 0 as level
FROM employees
WHERE department = 'Marketing'
UNION ALL
SELECT e.id, e.name, e.department, sh.level + 1
FROM employees e
INNER JOIN subordinate_hierarchy sh ON e.manager_id = sh.id
)
DELETE FROM employees
WHERE id IN (SELECT id FROM subordinate_hierarchy);
Result¶
ID |
NAME |
DEPARTMENT |
MANAGER_ID |
---|---|---|---|
1 |
Alice |
Sales |
2 |
2 |
Bob |
Sales |
1 |
3 |
Charlie |
Sales |
1 |
10 |
John |
Sales |
3 |
Code de sortie :¶
Snowflake¶
CREATE TEMPORARY TABLE subordinate_hierarchy AS
WITH RECURSIVE subordinate_hierarchy(id, name, department, level) AS (
SELECT id, name, department, 0 as level
FROM
employees
WHERE department = 'Marketing'
UNION ALL
SELECT e.id, e.name, e.department, sh.level + 1
FROM
employees e
INNER JOIN
subordinate_hierarchy sh ON e.manager_id = sh.id
)
SELECT
id,
name,
department,
level
FROM
subordinate_hierarchy;
DELETE FROM
employees
WHERE id IN (SELECT id FROM
subordinate_hierarchy
);
DROP TABLE subordinate_hierarchy;
Result¶
ID |
NAME |
DEPARTMENT |
MANAGER_ID |
---|---|---|---|
1 |
Alice |
Sales |
2 |
2 |
Bob |
Sales |
1 |
3 |
Charlie |
Sales |
1 |
10 |
John |
Sales |
3 |
Supprimer une vue matérialisée¶
Dans Redshift, vous pouvez appliquer l’instruction DELETE aux vues matérialisées utilisées pour l”ingestion de flux. Dans Snowflake, ces vues sont transformées en tables dynamiques et l’instruction DELETE ne peut pas être utilisée sur des tables dynamiques. Pour cette raison, un EWI sera ajouté.
Code d’entrée :¶
Redshift¶
CREATE MATERIALIZED VIEW emp_mv AS
SELECT id, name, department FROM employees WHERE department = 'Engineering';
DELETE FROM emp_mv
WHERE id = 2;
Code de sortie :¶
Snowflake¶
CREATE DYNAMIC TABLE emp_mv
--** SSC-FDM-0031 - DYNAMIC TABLE REQUIRED PARAMETERS SET BY DEFAULT **
TARGET_LAG='1 day'
WAREHOUSE=UPDATE_DUMMY_WAREHOUSE
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "02/11/2025", "domain": "test" }}'
AS
SELECT id, name, department FROM
employees
WHERE department = 'Engineering';
!!!RESOLVE EWI!!! /*** SSC-EWI-RS0008 - MATERIALIZED VIEW IS TRANSFORMED INTO A DYNAMIC TABLE, AND THE DELETE STATEMENT CANNOT BE USED ON DYNAMIC TABLES. ***/!!!
DELETE FROM
emp_mv
WHERE id = 2;
Problèmes connus ¶
La réplication de la fonctionnalité de la clause
WITH
nécessite la création de tables temporaires reflétant chaque expression de table commune (CTE). Toutefois, cette approche échoue si une table temporaire portant le même nom existe déjà dans la session en cours, ce qui provoque une erreur.
EWIs connexes¶
SSC-FDM-0031 : Table dynamique paramètres requis définis par défaut.
SSC-EWI-RS0008 : l’instruction Delete ne peut pas être utilisée sur les tables dynamiques.
EXECUTE¶
Description¶
The
EXECUTE
IMMEDIATE
statement builds and runs a dynamic SQL statement in a single operation.Native dynamic SQL uses the
EXECUTE
IMMEDIATE
statement to process most dynamic SQL statements. (Redshift Language Reference EXECUTE Statement)
Grammar Syntax¶
EXECUTE command-string [ INTO target ];
Modèles d’échantillons de sources¶
Concated Example
Code d’entrée
Redshift¶
CREATE OR REPLACE PROCEDURE create_dynamic_table(table_name VARCHAR)
AS $$
DECLARE
sql_statement VARCHAR;
BEGIN
sql_statement := 'CREATE TABLE IF NOT EXISTS ' || table_name || ' (id INT, value VARCHAR);';
EXECUTE sql_statement;
END;
$$ LANGUAGE plpgsql;
Code de sortie
Snowflake¶
CREATE OR REPLACE PROCEDURE create_dynamic_table (table_name VARCHAR)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "07/11/2025", "domain": "no-domain-provided" }}'
AS $$
DECLARE
sql_statement VARCHAR;
BEGIN
sql_statement := 'CREATE TABLE IF NOT EXISTS ' || table_name || ' (id INT, value VARCHAR)';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE sql_statement;
END;
$$;
Function Transformation¶
Code d’entrée¶
Redshift¶
CREATE OR REPLACE PROCEDURE insert_with_dynamic()
AS $$
DECLARE
sql_statement VARCHAR;
BEGIN
sql_statement := 'insert into orders(order_date) values ("getdate"());';
EXECUTE sql_statement;
END;
$$ LANGUAGE plpgsql;
Code de sortie¶
Snowflake¶
CREATE OR REPLACE PROCEDURE insert_with_dynamic ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "07/11/2025", "domain": "no-domain-provided" }}'
AS $$
DECLARE
sql_statement VARCHAR;
BEGIN
sql_statement := 'insert into orders (order_date) values (GETDATE())';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE sql_statement;
END;
$$;
Error In Query Parsing¶
Code d’entrée¶
Redshift¶
CREATE OR REPLACE PROCEDURE bad_statement(table_name VARCHAR)
AS $$
DECLARE
sql_statement VARCHAR;
BEGIN
sql_statement := 'bad statement goes here';
EXECUTE sql_statement;
END;
$$ LANGUAGE plpgsql;
Code de sortie¶
Snowflake¶
CREATE OR REPLACE PROCEDURE bad_statement (table_name VARCHAR)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "07/11/2025", "domain": "no-domain-provided" }}'
AS $$
DECLARE
sql_statement VARCHAR;
BEGIN
sql_statement := 'bad statement goes here';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!!!!RESOLVE EWI!!! /*** SSC-EWI-0027 - THE FOLLOWING STATEMENT USES A VARIABLE/LITERAL WITH AN INVALID QUERY AND IT WILL NOT BE EXECUTED ***/!!!
EXECUTE IMMEDIATE sql_statement;
END;
$$;
INTO Clause¶
Code d’entrée¶
Redshift¶
CREATE OR REPLACE PROCEDURE get_max_id(table_name VARCHAR, OUT max_id INTEGER)
AS $$
DECLARE
sql_statement VARCHAR;
BEGIN
sql_statement := 'SELECT MAX(id) FROM ' || table_name || ';';
EXECUTE sql_statement INTO max_id;
END;
$$ LANGUAGE plpgsql;
Code de sortie¶
Snowflake¶
CREATE OR REPLACE PROCEDURE get_max_id (table_name VARCHAR, max_id OUT INTEGER)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "07/11/2025", "domain": "no-domain-provided" }}'
AS $$
DECLARE
sql_statement VARCHAR;
BEGIN
sql_statement := 'SELECT
MAX(id) FROM
' || table_name;
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE sql_statement
!!!RESOLVE EWI!!! /*** SSC-EWI-PG0007 - INTO CLAUSE IN DYNAMIC SQL IS NOT SUPPORTED IN SNOWFLAKE. ***/!!! INTO max_id;
END;
$$;
Problèmes connus¶
1. Execution results cannot be stored in variables.¶
SnowScripting does not support INTO nor BULK COLLECT INTO clauses. For this reason, results will need to be passed through other means.
2. Dynamic SQL Execution queries may be marked incorrectly as non-runnable.¶
In some scenarios there an execute statement may be commented regardless of being safe or non-safe to run so please take this into account:
EWIs connexes¶
SSC-EWI-0027: Variable with invalid query.
SSC-EWI-0030: The statement below has usages of dynamic SQL.
INSERT¶
Description¶
Insère de nouvelles lignes dans une table.(Référence linguistique Redshift SQL instruction Insert).
Avertissement
Cette syntaxe est partiellement prise en charge par Snowflake.
Grammar Syntax¶
INSERT INTO table_name [ ( column [, ...] ) ]
{DEFAULT VALUES |
VALUES ( { expression | DEFAULT } [, ...] )
[, ( { expression | DEFAULT } [, ...] )
[, ...] ] |
query }
Modèles d’échantillons de sources¶
Setup data¶
Redshift¶
CREATE TABLE employees (
id INTEGER IDENTITY(1,1),
name VARCHAR(100),
salary INT DEFAULT 20000,
department VARCHAR(50) DEFAULT 'Marketing'
);
CREATE TABLE new_employees (
name VARCHAR(100),
salary INT,
department VARCHAR(50)
);
INSERT INTO new_employees (name, salary, department)
VALUES
('Grace Lee', 32000, 'Operations'),
('Hannah Gray', 26000, 'Finance');
Valeurs par défaut¶
Cela insère une ligne complète avec ses valeurs par défaut. Si certaines colonnes n’ont pas de valeurs par défaut, les valeurs NULL sont insérées dans ces colonnes.
This clause cannot specify individual columns; it always inserts a complete row with its default values. Additionally, columns with the NOT NULL constraint cannot be included in the table definition. To replicate this behavior in Snowflake, SnowConvert AI insert a column with a DEFAULT value in the table. This action inserts a complete row, using the default value for every column.
Code d’entrée :¶
Redshift¶
CREATE TABLE employees (
id INTEGER IDENTITY(1,1),
name VARCHAR(100),
salary INT DEFAULT 20000,
department VARCHAR(50) DEFAULT 'Marketing'
);
INSERT INTO employees
DEFAULT VALUES;
SELECT * FROM employees ORDER BY id;
Result¶
ID |
NAME |
SALARY |
DEPARTMENT |
---|---|---|---|
1 |
NULL |
20000 |
Marketing |
Code de sortie :¶
Snowflake¶
CREATE TABLE employees (
id INTEGER IDENTITY(1,1) ORDER,
name VARCHAR(100),
salary INT DEFAULT 20000,
department VARCHAR(50) DEFAULT 'Marketing'
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "03/03/2025", "domain": "test" }}';
INSERT INTO employees (id)
VALUES (DEFAULT);
SELECT * FROM
employees
ORDER BY id;
Result¶
ID |
NAME |
SALARY |
DEPARTMENT |
---|---|---|---|
1 |
NULL |
20000 |
Marketing |
Requête¶
Insérez une ou plusieurs lignes dans la table à l’aide d’une requête. Toutes les lignes produites par la requête seront insérées dans la table. La requête doit renvoyer une liste de colonnes compatible avec les colonnes de la table, bien que les noms des colonnes ne doivent pas nécessairement correspondre. Cette fonctionnalité est entièrement équivalente dans Snowflake.
Code d’entrée :¶
Redshift¶
INSERT INTO employees (name, salary, department)
SELECT name, salary, department FROM new_employees;
Result¶
ID |
NAME |
SALARY |
DEPARTMENT |
---|---|---|---|
1 |
Grace Lee |
32000 |
Opérations |
2 |
Hannah Gray |
26000 |
Finances |
Code de sortie :¶
Snowflake¶
INSERT INTO employees (name, salary, department)
SELECT name, salary, department FROM
new_employees;
Result¶
ID |
NAME |
SALARY |
DEPARTMENT |
---|---|---|---|
1 |
Grace Lee |
32000 |
Opérations |
2 |
Hannah Gray |
26000 |
Finances |
Problèmes connus ¶
Certaines expressions ne peuvent pas être utilisées dans la clause VALUES de Snowflake. Par exemple, dans Redshift, la fonction JSON_PARSE peut être utilisée dans la clause VALUES pour insérer une valeur JSON dans un type de données SUPER. Dans Snowflake, cependant, la fonction PARSE_JSON ne peut pas être utilisée dans la clause VALUES pour insérer une valeur JSON dans un type de données VARIANT. Une requête peut être utilisée à la place de la clause VALUES. Pour plus de références, veuillez vous référer à la documentation de Snowflake. Vous pouvez également consulter l”article suivant pour de plus amples informations.
EWIs connexes¶
Il n’y a pas de problème connu.
MERGE¶
Grammar Syntax¶
MERGE INTO target_table
USING source_table [ [ AS ] alias ]
ON match_condition
[ WHEN MATCHED THEN { UPDATE SET col_name = { expr } [,...] | DELETE }
WHEN NOT MATCHED THEN INSERT [ ( col_name [,...] ) ] VALUES ( { expr } [, ...] ) |
REMOVE DUPLICATES ]
Pour plus d’informations, veuillez vous référer à la documentation MERGE de Redshift.
Modèles d’échantillons de sources¶
UPDATE - INSERT¶
Il n’y a pas de différences entre les deux langues. Le code est conservé dans sa forme originale.
Code d’entrée :¶
Redshift¶
MERGE INTO target USING source ON target.id = source.id
WHEN MATCHED THEN UPDATE SET id = source.id, name = source.name
WHEN NOT MATCHED THEN INSERT VALUES (source.id, source.name);
Code de sortie :¶
Snowflake¶
--** SSC-FDM-RS0005 - REDSHIFT MERGE STATEMENT DOESN'T ALLOW DUPLICATES IN THE SOURCE TABLE. SNOWFLAKE BEHAVIOR MAY DIFFER IF THERE ARE DUPLICATE VALUES. **
MERGE INTO target USING source ON target.id = source.id
WHEN MATCHED THEN UPDATE SET id = source.id, name = source.name
WHEN NOT MATCHED THEN INSERT VALUES (source.id, source.name);
DELETE - INSERT¶
Il n’y a pas de différences entre les deux langues. Le code est conservé dans sa forme originale.
Code d’entrée :¶
Redshift¶
MERGE INTO target USING source ON target.id = source.id
WHEN MATCHED THEN DELETE
WHEN NOT MATCHED THEN INSERT VALUES (source.id, source.name);
Code de sortie :¶
Snowflake¶
--** SSC-FDM-RS0005 - REDSHIFT MERGE STATEMENT DOESN'T ALLOW DUPLICATES IN THE SOURCE TABLE. SNOWFLAKE BEHAVIOR MAY DIFFER IF THERE ARE DUPLICATE VALUES. **
MERGE INTO target USING source ON target.id = source.id
WHEN MATCHED THEN DELETE
WHEN NOT MATCHED THEN INSERT VALUES (source.id, source.name);
REMOVE DUPLICATES¶
La clause REMOVE DUPLICATES n’est pas prise en charge dans Snowflake, mais il existe une solution de contournement qui permet d’émuler le comportement original.
Le code de sortie comportera trois nouvelles instructions :
Une page TEMPORARY TABLE contenant les valeurs en double des tables source et cible qui correspondent à la condition
Une instruction INSERT qui ajoute les valeurs en attente à la table cible après la fusion
Une instruction DROP qui supprime la table temporaire générée.
Celles-ci sont nécessaires car le comportement DROP DUPLICATES supprime les valeurs en double de la table cible et insère ensuite les valeurs correspondant à la condition dans la table source.
Code d’entrée :¶
Redshift¶
CREATE TABLE target (id INT, name CHAR(10));
CREATE TABLE source (id INT, name CHAR(10));
INSERT INTO target VALUES (30, 'Tony'), (30, 'Daisy'), (11, 'Alice'), (23, 'Bill'), (23, 'Nikki');
INSERT INTO source VALUES (23, 'David'), (22, 'Clarence');
MERGE INTO target USING source ON target.id = source.id REMOVE DUPLICATES;
Results¶
ID |
NAME |
---|---|
30 |
Daisy |
22 |
Clarence |
30 |
Tony |
11 |
Alice |
23 |
David |
Code de sortie :¶
Snowflake¶
CREATE TABLE target (id INT, name CHAR(10))
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "03/03/2025", "domain": "test" }}';
CREATE TABLE source (id INT, name CHAR(10))
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "redshift", "convertedOn": "03/03/2025", "domain": "test" }}';
INSERT INTO target
VALUES (30, 'Tony'), (30, 'Daisy'), (11, 'Alice'), (23, 'Bill'), (23, 'Nikki');
INSERT INTO source
VALUES (23, 'David'), (22, 'Clarence');
CREATE TEMPORARY TABLE source_duplicates AS
SELECT DISTINCT
source.*
FROM
source
INNER JOIN
target
ON target.id = source.id;
--** SSC-FDM-RS0005 - REDSHIFT MERGE STATEMENT DOESN'T ALLOW DUPLICATES IN THE SOURCE TABLE. SNOWFLAKE BEHAVIOR MAY DIFFER IF THERE ARE DUPLICATE VALUES. **
MERGE INTO target
USING source ON target.id = source.id
WHEN MATCHED THEN
DELETE
WHEN NOT MATCHED THEN
INSERT
VALUES (source.id, source.name);
INSERT INTO target
SELECT
*
FROM
source_duplicates;
DROP TABLE IF EXISTS source_duplicates CASCADE;
Results¶
ID |
NAME |
---|---|
22 |
Clarence |
30 |
Tony |
30 |
Daisy |
11 |
Alice |
23 |
David |
Problèmes connus¶
Il n’y a pas de problème connu.
EWIs connexes¶
SSC-EWI-RS0009 : information sémantique non trouvée pour le tableau source.
SSC-FDM-RS0005 : les doublons ne sont pas autorisés dans le tableau source.
UPDATE¶
Description¶
Met à jour les valeurs d’une ou plusieurs colonnes de la table lorsqu’une condition est remplie. (Référence linguistique Redshift SQL instruction Update).
Note
Cette syntaxe est entièrement prise en charge par Snowflake.
Grammar Syntax¶
[ WITH [RECURSIVE] common_table_expression [, common_table_expression , ...] ]
UPDATE table_name [ [ AS ] alias ] SET column = { expression | DEFAULT } [,...]
[ FROM fromlist ]
[ WHERE condition ]
Modèles d’échantillons de sources¶
Setup data¶
Redshift¶
CREATE TABLE employees (
id INTEGER IDENTITY(1,1),
name VARCHAR(100),
salary DECIMAL DEFAULT 20000,
department VARCHAR(50) DEFAULT 'Marketing'
);
INSERT INTO employees (name, salary, department)
VALUES
('Alice', 500000, 'HR'),
('Bob', 600000, 'Engineering'),
('Charlie', 700000, 'Engineering'),
('David', 400000, 'Marketing'),
('Eve', 450000, 'HR'),
('Frank', 750000, 'Engineering'),
('Grace', 650000, 'Engineering'),
('Helen', 390000, 'Marketing'),
('Ivy', 480000, 'HR'),
('Jack', 420000, 'Engineering'),
('Ken', 700000, 'Marketing'),
('Liam', 600000, 'Engineering'),
('Mona', 470000, 'HR');
CREATE TABLE department_bonus (
department VARCHAR(100),
bonus DECIMAL
);
INSERT INTO department_bonus (department, bonus)
VALUES
('HR', 10000),
('Engineering', 50000),
('Marketing', 20000),
('Sales', 5000);
Alias¶
Bien que la grammaire de Snowflake ne spécifie pas qu’un alias de table peut être utilisé, c’est un code valide dans Snowflake.
Code d’entrée :¶
Redshift¶
UPDATE employees AS e
SET salary = salary + 5000
WHERE e.salary < 600000;
Result¶
ID |
NAME |
SALARY |
DEPARTMENT |
---|---|---|---|
1 |
Alice |
505000 |
HR |
2 |
Bob |
600000 |
Engineering |
3 |
Charlie |
700000 |
Engineering |
4 |
David |
405000 |
Marketing |
5 |
Eve |
455000 |
HR |
6 |
Frank |
750000 |
Engineering |
7 |
Grace |
650000 |
Engineering |
8 |
Helen |
395000 |
Marketing |
9 |
Ivy |
485000 |
HR |
10 |
Jack |
425000 |
Engineering |
11 |
Ken |
700000 |
Marketing |
12 |
Liam |
600000 |
Engineering |
13 |
Mona |
475000 |
HR |
Code de sortie :¶
Snowflake¶
UPDATE employees AS e
SET salary = salary + 5000
WHERE e.salary < 600000;
Result¶
ID |
NAME |
SALARY |
DEPARTMENT |
---|---|---|---|
1 |
Alice |
505000 |
HR |
2 |
Bob |
600000 |
Engineering |
3 |
Charlie |
700000 |
Engineering |
4 |
David |
405000 |
Marketing |
5 |
Eve |
455000 |
HR |
6 |
Frank |
750000 |
Engineering |
7 |
Grace |
650000 |
Engineering |
8 |
Helen |
395000 |
Marketing |
9 |
Ivy |
485000 |
HR |
10 |
Jack |
425000 |
Engineering |
11 |
Ken |
700000 |
Marketing |
12 |
Liam |
600000 |
Engineering |
13 |
Mona |
475000 |
HR |
Clause WITH¶
Cette clause spécifie une ou plusieurs expressions de table communes (CTE). Les noms des colonnes de sortie sont facultatifs pour les CTEs non récursifs, mais obligatoires pour ceux qui sont récursifs.
Cette clause ne pouvant être utilisée dans une instruction UPDATE, elle est transformée en tables temporaires avec leurs requêtes correspondantes. Après l’exécution de l’instruction UPDATE, ces tables temporaires sont supprimées afin de faire le ménage, de libérer des ressources et d’éviter les collisions de noms lors de la création de tables au cours de la même session. En outre, s’il existe une table normale portant le même nom, elle sera à nouveau prioritaire, puisque la table temporaire a la priorité sur toute autre table portant le même nom dans la même session.
CTE non récursif¶
Code d’entrée :¶
Redshift¶
WITH avg_salary_cte AS (
SELECT AVG(salary) AS avg_salary FROM employees
)
UPDATE employees
SET salary = (SELECT avg_salary FROM avg_salary_cte)
WHERE salary < 500000;
Result¶
ID |
NAME |
SALARY |
DEPARTMENT |
---|---|---|---|
1 |
Alice |
500000 |
HR |
2 |
Bob |
600000 |
Engineering |
3 |
Charlie |
700000 |
Engineering |
4 |
David |
546923 |
Marketing |
5 |
Eve |
546923 |
HR |
6 |
Frank |
750000 |
Engineering |
7 |
Grace |
650000 |
Engineering |
8 |
Helen |
546923 |
Marketing |
9 |
Ivy |
546923 |
HR |
10 |
Jack |
546923 |
Engineering |
11 |
Ken |
700000 |
Marketing |
12 |
Liam |
600000 |
Engineering |
13 |
Mona |
546923 |
HR |
Code de sortie :¶
Snowflake¶
CREATE TEMPORARY TABLE avg_salary_cte AS
SELECT AVG(salary) AS avg_salary FROM
employees;
UPDATE employees
SET salary = (SELECT avg_salary FROM
avg_salary_cte
)
WHERE salary < 500000;
DROP TABLE avg_salary_cte;
Result¶
ID |
NAME |
SALARY |
DEPARTMENT |
---|---|---|---|
1 |
Alice |
500000 |
HR |
2 |
Bob |
600000 |
Engineering |
3 |
Charlie |
700000 |
Engineering |
4 |
David |
546923 |
Marketing |
5 |
Eve |
546923 |
HR |
6 |
Frank |
750000 |
Engineering |
7 |
Grace |
650000 |
Engineering |
8 |
Helen |
546923 |
Marketing |
9 |
Ivy |
546923 |
HR |
10 |
Jack |
546923 |
Engineering |
11 |
Ken |
700000 |
Marketing |
12 |
Liam |
600000 |
Engineering |
13 |
Mona |
546923 |
HR |
CTE récursif¶
Code d’entrée :¶
Redshift¶
WITH RECURSIVE bonus_updates(id, name, department, salary, level) AS (
SELECT e.id,
e.name,
e.department,
e.salary + CASE
WHEN db.bonus IS NOT NULL THEN db.bonus
ELSE 0
END AS new_salary,
1 AS level
FROM employees e
LEFT JOIN department_bonus db ON e.department = db.department
UNION ALL
SELECT e.id,
e.name,
e.department,
e.salary + CASE
WHEN db.bonus IS NOT NULL THEN db.bonus
ELSE 0
END + (e.salary * 0.05) AS new_salary,
bu.level + 1
FROM employees e
JOIN department_bonus db ON e.department = db.department
JOIN bonus_updates bu ON e.id = bu.id
WHERE bu.level < 3
)
UPDATE employees
SET salary = bu.new_salary
FROM (SELECT id, AVG(salary) as new_salary FROM bonus_updates GROUP BY id) as bu
WHERE employees.id = bu.id
AND bu.new_salary > employees.salary;
Result¶
ID |
NAME |
SALARY |
DEPARTMENT |
---|---|---|---|
1 |
Alice |
526666 |
HR |
2 |
Bob |
670000 |
Engineering |
3 |
Charlie |
773333 |
Engineering |
4 |
David |
433333 |
Marketing |
5 |
Eve |
475000 |
HR |
6 |
Frank |
825000 |
Engineering |
7 |
Grace |
721666 |
Engineering |
8 |
Helen |
423000 |
Marketing |
9 |
Ivy |
506000 |
HR |
10 |
Jack |
484000 |
Engineering |
11 |
Ken |
743333 |
Marketing |
12 |
Liam |
670000 |
Engineering |
13 |
Mona |
495668 |
HR |
Code de sortie :¶
Snowflake¶
CREATE TEMPORARY TABLE bonus_updates AS
--** SSC-FDM-0007 - MISSING DEPENDENT OBJECTS "employees", "department_bonus" **
WITH RECURSIVE bonus_updates(id, name, department, salary, level) AS (
SELECT e.id,
e.name,
e.department,
e.salary + CASE
WHEN db.bonus IS NOT NULL THEN db.bonus
ELSE 0
END AS new_salary,
1 AS level
FROM
employees e
LEFT JOIN
department_bonus db ON e.department = db.department
UNION ALL
SELECT e.id,
e.name,
e.department,
e.salary + CASE
WHEN db.bonus IS NOT NULL THEN db.bonus
ELSE 0
END + (e.salary * 0.05) AS new_salary,
bu.level + 1
FROM
employees e
JOIN
department_bonus db ON e.department = db.department
JOIN
bonus_updates bu ON e.id = bu.id
WHERE bu.level < 3
)
SELECT
id,
name,
department,
salary,
level
FROM
bonus_updates;
UPDATE employees
SET salary = bu.new_salary
FROM (SELECT id, AVG(salary) as new_salary
FROM bonus_updates
GROUP BY id) as bu
WHERE employees.id = bu.id
AND bu.new_salary > employees.salary;
DROP TABLE bonus_updates;
Result¶
ID |
NAME |
SALARY |
DEPARTMENT |
---|---|---|---|
1 |
Alice |
526667 |
HR |
2 |
Bob |
670000 |
Engineering |
3 |
Charlie |
773333 |
Engineering |
4 |
David |
433333 |
Marketing |
5 |
Eve |
475000 |
HR |
6 |
Frank |
825000 |
Engineering |
7 |
Grace |
721667 |
Engineering |
8 |
Helen |
423000 |
Marketing |
9 |
Ivy |
506000 |
HR |
10 |
Jack |
484000 |
Engineering |
11 |
Ken |
743333 |
Marketing |
12 |
Liam |
670000 |
Engineering |
13 |
Mona |
495667 |
HR |
Valeurs SET DEFAULT¶
Code d’entrée :¶
Redshift¶
UPDATE employees
SET salary = DEFAULT, department = 'Sales'
WHERE department = 'HR';
Result¶
ID |
NAME |
SALARY |
DEPARTMENT |
---|---|---|---|
1 |
Alice |
20000 |
Sales |
2 |
Bob |
600000 |
Engineering |
3 |
Charlie |
700000 |
Engineering |
4 |
David |
400000 |
Marketing |
5 |
Eve |
20000 |
Sales |
6 |
Frank |
750000 |
Engineering |
7 |
Grace |
650000 |
Engineering |
8 |
Helen |
390000 |
Marketing |
9 |
Ivy |
20000 |
Sales |
10 |
Jack |
420000 |
Engineering |
11 |
Ken |
700000 |
Marketing |
12 |
Liam |
600000 |
Engineering |
13 |
Mona |
20000 |
Sales |
Code de sortie :¶
Snowflake¶
UPDATE employees
SET salary = DEFAULT, department = 'Sales'
WHERE
department = 'HR';
Result¶
ID |
NAME |
SALARY |
DEPARTMENT |
---|---|---|---|
1 |
Alice |
20000 |
Sales |
2 |
Bob |
600000 |
Engineering |
3 |
Charlie |
700000 |
Engineering |
4 |
David |
400000 |
Marketing |
5 |
Eve |
20000 |
Sales |
6 |
Frank |
750000 |
Engineering |
7 |
Grace |
650000 |
Engineering |
8 |
Helen |
390000 |
Marketing |
9 |
Ivy |
20000 |
Sales |
10 |
Jack |
420000 |
Engineering |
11 |
Ken |
700000 |
Marketing |
12 |
Liam |
600000 |
Engineering |
13 |
Mona |
20000 |
Sales |
Clause SET¶
Il est responsable de la modification des valeurs dans les colonnes. Comme pour Snowflake, les requêtes de mise à jour avec des correspondances multiples par ligne génèrent une erreur lorsque le paramètre de configuration ERROR_ON_NONDETERMINISTIC_UPDATE est défini sur True. Cet indicateur fonctionne de la même manière dans Snowflake, et il utilise même le même nom, ERROR_ON_NONDETERMINISTIC_UPDATE.
Toutefois, lorsque cet indicateur est désactivé, aucune erreur n’est renvoyée et l’une des lignes correspondantes est utilisée pour mettre à jour la ligne cible. La ligne jointe sélectionnée est non déterministe et arbitraire dans les deux langues ; le comportement peut ne pas être cohérent d’une exécution à l’autre, ce qui pourrait entraîner des incohérences dans les données.
Données de configuration :¶
Redshift¶
CREATE TABLE target (
k INT,
v INT
);
CREATE TABLE src (
k INT,
v INT
);
INSERT INTO target (k, v) VALUES (0, 10);
INSERT INTO src (k, v) VALUES
(0, 14),
(0, 15),
(0, 16);
Code d’entrée :¶
Redshift¶
UPDATE target
SET v = src.v
FROM src
WHERE target.k = src.k;
SELECT * FROM target;
Result¶
K |
V |
---|---|
0 |
16 |
Code de sortie :¶
Snowflake¶
UPDATE target
SET v = src.v
FROM src
WHERE target.k = src.k;
SELECT * FROM target;
Result¶
K |
V |
---|---|
0 |
14 |
Problèmes connus ¶
Les requêtes de mise à jour avec plusieurs correspondances par ligne peuvent entraîner des incohérences dans les données. Bien que les deux plateformes aient l’indicateur ERROR_ON_NONDETERMINISTIC_UPDATE, ces valeurs seront toujours non déterministes. Snowflake propose des recommandations pour gérer ces scénarios. Cliquez ici pour plus de détails.
La réplication de la fonctionnalité de la clause
WITH
nécessite la création de tables temporaires reflétant chaque expression de table commune (CTE). Toutefois, cette approche échoue si une table temporaire portant le même nom existe déjà dans la session en cours, ce qui provoque une erreur.
EWIs connexes¶
Il n’y a pas de problème connu.