1
votes

Ajouter une colonne d'identité à une table existante dans Snowflake?

J'ai une table "MY_TABLE" dans Snowflake à laquelle j'aimerais ajouter une colonne d'identité. J'ai essayé

SQL compilation error: Insert value list does not match column list expecting <x+1> but got <x>

Mais cela renvoie

CREATE OR REPLACE TABLE "MY_TABLE_TEMP" LIKE "MY_TABLE"
ALTER TABLE "MY_TABLE_TEMP" ADD COLUMN primary_key int IDENTITY(1,1)

INSERT INTO "MY_TABLE_TEMP"
    SELECT * FROM "MY_TABLE";

N'est-ce pas possible en flocon de neige?

Pour essayer d'obtenir autour de cette limitation, j'ai essayé de créer une version temporaire de la table

SQL compilation error: Cannot add column 'PRIMARY_KEY' with non-constant default to non-empty table 'MY_TABLE'.

Mais maintenant j'obtiens l'erreur

ALTER TABLE "MY_TABLE" 
    ADD COLUMN primary_key int IDENTITY(1,1);

Ce qui a du sens, puisque je ne passe pas la clé primaire. À ce stade, il semble que je puisse avoir à entrer manuellement la liste de x (qui est un nombre très élevé) de noms de colonnes dans la requête SQL, donc je me demande si je fais tout cela mal. Quelqu'un d'autre a-t-il rencontré un problème similaire?


1 commentaires

Snowflake ne semble pas aimer qu'une nouvelle colonne d'incrémentation automatique soit ajoutée à une table existante. Étant donné que votre table semble vide, vous pouvez simplement modifier votre instruction create.


3 Réponses :


0
votes

Juste une intuition, mais avez-vous essayé d'inclure le target_col_name dans l'instruction d'insertion. Je suppose que si vous ne les spécifiez pas, il attend la colonne supplémentaire que vous venez d'ajouter dans l'instruction select.


0 commentaires

2
votes

Pouvez-vous essayer ceci

CREATE TABLE TEST_TABLE_TEMP LIKE TEST_TABLE;
ALTER TABLE TEST_TABLE_TEMP ADD COLUMN primary_key int IDENTITY(1,1);

create or replace sequence seq_01 start = 1 increment = 1;

INSERT INTO TEST_TABLE_TEMP 
SELECT *,seq_01.NEXTVAL FROM TEST_TABLE;

SELECT * FROM TEST_TABLE_TEMP;


3 commentaires

Pas OP, mais j'ai le même problème et l'instruction ALTER TABLE échoue avec le message d'origine de OP.


En fait, il y a une raison pour laquelle snowflake ne devrait jamais activer la solution ALTER TABLE pour remplir la colonne IDENTITY pour une table non vide. La réponse se trouve dans l'architecture de SNOWFLAKE. Pensez au nombre de micro partitions qui devront être touchées et à ce que cela signifiera pour le coût de calcul?


Après un examen plus approfondi, je pense qu'il y a un problème. Cela semble utiliser une séquence différente pour la colonne d'identité et pour amorcer les valeurs initiales de cette colonne. La ligne suivante qui est insérée dans la table recommencera à 1. Je pourrais peut-être contourner ce problème en faisant IDENTITY (r, 1) où r est le nombre de lignes dans la table.



1
votes

Au lieu d'utiliser IDENTITY , vous pouvez utiliser votre propre SEQUENCE pour créer un identifiant unique pour chaque ligne.

Correction de l'exemple dans la question avec une séquence:

CREATE OR REPLACE SEQUENCE seq1;
CREATE OR REPLACE TABLE "MY_TABLE_TEMP" LIKE "MY_TABLE";

ALTER TABLE "MY_TABLE_TEMP" 
ADD COLUMN primary_key int DEFAULT seq1.nextval;


INSERT INTO "MY_TABLE_TEMP"
SELECT *, seq1.nextval 
FROM "MY_TABLE";

(après avoir posté cette réponse, j'ai remarqué qu'elle était très similaire à celle de Rajib)


1 commentaires

Pas OP, mais je suis un peu dans la même situation (en utilisant une séquence au lieu de l'identité EDIT: Et aussi avec l'identité), et j'obtiens la même erreur d'OP en essayant d'exécuter le ALTER TABLE que vous avez écrit ici.