3 votes

Comment mettre à jour une clé étrangère

Je possède 2 tables ; le design de la première table est le suivant :

Table 1 :

    id_Doc_line_sheet (pk), Numéro automatique
    DocNo (texte)
    lineNo (texte)
    Feuille n° (texte)

La combinaison des champs (DocNo, lineNo, Feuille n°) forme un index unique.

Le design de la deuxième table est le suivant :

Table 2 :

  id_Doc_line_trans (pk), Numéro automatique
  id_Doc_line_sheet (fk), Nombre
  nom

Maintenant dans la table 1, pour le champ lineNo, j'ai des enregistrements avec des espaces avant et sans espaces comme ci-dessous :

  id_Doc_line_sheet            DocNo        lineNo      Sheet No    
  ------------------------------------------------------------------
  1001                         doc-0001    line-0001    1
  1002                         doc-0001     line-0001   1
  1003                         doc-0001    line-0001    2
  1004                         doc-0001     line-0001   2
  1005                         doc-0002    line-0002    1
  1006                         doc-0002     line-0002   1
  1007                         doc-0001    line-0005    1
  1008                         doc-0001     line-0005   1

Et je veux supprimer ces enregistrements avec des espaces avant mais d'abord je veux mettre à jour (id_Doc_line_sheet) pour chaque unique (DocNo, lineNo, Feuille n°) vers le bon (sans espace au début). Je veux dire que si la table2 ressemble à ceci :

    id_Doc_line_trans     id_Doc_line_sheet     nom
    ---------------------------------------------------
     1                        1001              nom01
     2                        1002              nom02
     3                        1003              nom03
     4                        1004              nom04
     5                        1007              nom07
     6                        1008              nom08

Je mets à jour (id_Doc_line_sheet) comme ci-dessous :

id_Doc_line_trans     id_Doc_line_sheet     nom
---------------------------------------------------
 1                     1001                nom01
 2                     1001                nom02
 3                     1003                nom03
 4                     1003                nom04
 5                     1007                nom07
 6                     1007                nom08

Et ensuite je supprime les enregistrements avec des espaces avant dans la première table.

S'il vous plaît aidez-moi sur la manière de procéder ?

2voto

Monah Points 5515

Basé sur ce que j'ai compris, il semble que vous voulez mettre à jour le tableau2 en fonction du premier id utilisé dans le sheet_no. Si tel est le cas, vous pouvez utiliser ce qui suit:

Explication

  1. Vous devez obtenir le premier enregistrement dans tableau1 en fonction du sheet_no en utilisant report cte
  2. Recherchez le sheet_no correspondant pour chaque ligne dans tableau2
  3. Mettez à jour les entrées de tableau2row_number =1

Requête

;avec rapport comme (
   select row_number() over(partition by sheet_no order by id_doc_line_sheet) as [Rang],id_doc_line_sheet,sheet_no
   from tableau1       
   where line_no not like ' %' -- ici vous pouvez vous assurer que lin_no ne commence pas par un espace
), combiné comme (
    select t2.id_doc_line_trans,
           t2.id_doc_line_sheet,
           t1.sheet_no
    from tableau2 t2
    inner join tableau1 t1 on t2.id_doc_line_sheet = t1.id_doc_line_sheet
)

mettre à jour t set t.id_doc_line_sheet = r.id_doc_line_sheet
from rapport r 
inner join combiné c on r.sheet_no = c.sheet_no
inner join tableau2 t on t.id_doc_line_trans = c.id_doc_line_trans
where r.[Rang]=1

résultat après la mise à jour de tableau2

    id_doc_line_trans   id_doc_line_sheet   nom
    1   1001    nom01
    2   1001    nom02
    3   1003    nom03
    4   1003    nom04

Ensuite, vous pouvez appliquer l'instruction de suppression en fonction de vos besoins

Voici une démonstration fonctionnelle

J'espère que cela vous aidera

2voto

Tim Biegeleisen Points 53335

Voici une approche qui n'utilise pas de fonctions analytiques, qui était la manière la plus simple que j'avais en tête pour aborder ce problème. Nous pouvons agréger sur table1 et pivoter à la fois l'id des enregistrements avec et sans espace de tête. De plus, nous pouvons vérifier si un document/feuille donné contient une telle page. Ensuite, tout ce que nous avons à faire est de joindre table2 à cette première CTE pour obtenir les anciennes et nouvelles valeurs d'id dans un seul enregistrement.

AVEC cte1 AS (
    SELECT
        DocNo, [Sheet No],
        MAX(CASE WHEN [lineNo] LIKE ' %' THEN id_Doc_line_sheet END) AS id_old,
        MAX(CASE WHEN [lineNo] NOT LIKE ' %' THEN id_Doc_line_sheet END) AS id_new
    FROM table1
    GROUP BY DocNo, [Sheet No]
    HAVING SUM(CASE WHEN [lineNo] LIKE ' %' THEN 1 ELSE 0 END) > 0
),
cte2 AS (
    SELECT
        t1.id_Doc_line_trans, t1.id_Doc_line_sheet, t1.name, t2.id_old, t2.id_new
    FROM table2 t1
    INNER JOIN cte1 t2
        ON t1.id_Doc_line_sheet = t2.id_old
)

UPDATE cte2
SET id_Doc_line_sheet = id_new;

Notez que la logique de mise à jour est triviale; toutes les informations et les enregistrements d'intérêt étaient déjà inclus dans la deuxième CTE.

Démonstration

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X