Casting du type NULL dans les mises à jour multi-lignes
Dans PostgreSQL, l'exécution d'une requête de mise à jour sur plusieurs lignes peut entraîner des erreurs lors du traitement de NULL valeurs si les types de colonnes ne sont pas explicitement convertis. Cet article explore plusieurs solutions à ce problème, en proposant des approches alternatives pour garantir une conversion de type appropriée lors des mises à jour sur plusieurs lignes.
Solution 1 : sélectionnez la limite 0 avec VALUES et UNION ALL
UPDATE foo f SET x = t.x , y = t.y FROM ( (SELECT pkid, x, y FROM foo LIMIT 0) -- Get column types UNION ALL VALUES (1, 20, NULL) -- No type casts , (2, 50, NULL) ) t -- Column names and types defined WHERE f.pkid = t.pkid;
Cette méthode combine une instruction SELECT avec une LIMIT de 0 pour récupérer les noms et types de colonnes, puis ajoute les lignes de données souhaitées à l'aide de l'opérateur UNION ALL. La première ligne de la sous-requête garantit que les types de colonnes appropriés sont définis pour les lignes suivantes.
Solution 2 : sélectionnez la limite 0 avec VALUES et UNION ALL SELECT
UPDATE foo f SET x = t.x , y = t.y FROM ( (SELECT pkid, x, y FROM foo LIMIT 0) -- Get column types UNION ALL SELECT 1, 20, NULL UNION ALL SELECT 2, 50, NULL ) t -- Column names and types defined WHERE f.pkid = t.pkid;
Semblable à la solution 1, cette approche utilise SELECT pour obtenir les types de colonnes, puis utilise des instructions SELECT individuelles pour ajouter des lignes de données, empêchant ainsi tout type prématuré. casting.
Solution 3 : Expression VALUES avec type par colonne
UPDATE foo f SET x = t.x , y = t.y FROM ( VALUES ((SELECT pkid FROM foo LIMIT 0) , (SELECT x FROM foo LIMIT 0) , (SELECT y FROM foo LIMIT 0)) -- Get type for each col individually , (1, 20, NULL) , (2, 50, NULL) ) t (pkid, x, y) -- Columns names not defined yet, only types. ...
Cette solution définit les types de colonnes dans l'expression VALUES elle-même, garantissant que les lignes suivantes sont convertis en ces types sans rencontrer d'erreurs dues aux hypothèses de type automatiques.
Solution 4 : VALUES Expression avec type de ligne
UPDATE foo f SET x = (t.r).x -- Parenthesis for unambiguous syntax , y = (t.r).y FROM ( VALUES ('(1,20,)'::foo) -- Columns need to be in table default order ,('(2,50,)') -- Nothing after last comma for NULL ) t (r) -- Column name for row type WHERE f.pkid = (t.r).pkid;
Cette approche utilise le type de ligne de la table spécifique, vous permettant de convertir implicitement les colonnes vers les types corrects. Vous pouvez accéder aux valeurs de colonnes individuelles à l'aide de la syntaxe de sélection de champ.
Solution 5 : Expression VALUES avec type de ligne décomposé
UPDATE foo f SET x = t.x , y = t.y FROM ( VALUES (('(1,20,)'::foo).*) -- Decomposed row of values , (2, 50, NULL) ) t(pkid, x, y) -- Arbitrary column names (match table columns) WHERE f.pkid = t.pkid; -- Eliminates 1st row with NULL values
Similaire à la solution 4, mais en utilisant des lignes décomposées pour spécifier les valeurs des données. Cela vous permet de fournir uniquement les colonnes pertinentes, éliminant ainsi le besoin de connaître l'ordre complet et les types de toutes les colonnes du tableau.
Le choix de la meilleure solution dépend de facteurs tels que les performances, la commodité et la disponibilité de informations sur les types de colonnes.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!