Problème SQL

Bonjour à tous,

Actuellement j'ai un problème sur SQL et je ne vois pas trop comment m'en sortir, je vous explique le contexte :

J'ai comme table source deux champs , un id et puis un calcul comme ceci :

Id_LIGNE CHAMP_CALCUL

1, +(CA_TOTTO+CA_TATA+CA_PAT)*(CA_TXXX)
2,+( CA_TOTTO)* CA_TXXX)

Le problème c'est que je dois extraire à partir du champ "CHAMP_CALCUL » tous les champs qui sont préfixés par CA,
Par exemple sur la première ligne je dois récupérer dans une table de sortie :

CHAMP_CALCUL_SORTIE
CA_TOTTO
CA_TATA
CA_PAT
CA_TXXX

Et je ne vois pas trop comment faire étant donné que les champs ne sont toujours pas dans la même position.

Merci de votre aide,

Teddy

6 réponses

  1. Bonjour,
    C'est marrant ça ressemble à ce sujet !
    Enfin, la solution proposée doit être à peu près identique pour l'adapter à ce problème-ci. Je fouille un peu et je reviens.
    0
    1. Bonjour Clément merci de votre retour, oui effectivement cela ressemble mais la problématique ici c'est que le nom des valeurs qui commencent par CA ne sont toujours pas à la même position et en plus ils n'ont pas forcement la même longueur, pas gagné.

      Merci de votre retour si jamais vous avez une piste.

      Cordialement,

      Ted
      0
      1. Oui, ça fonctionne à peu près comme je veux, mais je reste bloqué pour déterminer la longueur de la chaîne.
        Je continue de fouiller !
        0
    2. Hop et voilà :)
      Cependant, cette requête liste tous les mots préfixés par "CA_" de toutes les lignes.
      J'ai donc rajouté l'ID de la ligne dans la table de sortie pour pouvoir trier tout ça (et désolé pour l'indentation pourrie) (et la table csd_temp1 à la 8eme ligne est la table source, à adapter).

      if object_id('dbo.champ_calcul_sortie') is not null 
      begin 
        drop table dbo.champ_calcul_sortie 
        create table champ_calcul_sortie (ID int,champ_calcul nvarchar(50)) 
      end 
      
      select * into ##temptable from csd_temp1 
      
      declare @id int, @compteur int 
      declare db_cursor cursor for select id from csd_temp1 
      
      OPEN db_cursor   
      FETCH NEXT FROM db_cursor INTO @id 
      
      WHILE @@FETCH_STATUS = 0  
      BEGIN 
      
       DECLARE   
       @champ nvarchar(50), 
       @count integer,   
       @search varchar(10),   
       @long_string varchar(500),  
       @mot varchar (20), 
       @debut int, 
       @longueur int 
        
       SET @champ = (select champ_calcul from ##temptable where id = @id)   
       SET @search = 'CA_'   
       SET @long_string = @champ 
          
       SET @count = (DATALENGTH(@long_string) - DATALENGTH(REPLACE(@long_string, @search, ''))) / DATALENGTH(@search)   
        
       set @compteur = 1 
        
       if len(@champ)>3 
       begin 
        while @compteur<=@count 
        begin 
         set @longueur = 4 
         set @champ = (select champ_calcul from ##temptable where id = @id)   
         set @debut = charindex('CA_',@champ) 
          
         while substring(@champ,@debut+@longueur,1) not in ('+',')') begin 
          set @longueur = @longueur+1 
         end 
          
         set @mot = (select substring(@champ, @debut,@longueur) from ##temptable where ID = @id) 
          
         insert into champ_calcul_sortie values (@id,@mot) 
         update ##temptable set champ_calcul = replace(champ_calcul,@mot,'') where id = @id 
         set @compteur = @compteur + 1 
        end 
       end 
      
      FETCH NEXT FROM db_cursor INTO @id 
      
      END 
      CLOSE db_cursor   
      DEALLOCATE db_cursor  
      
      drop table ##temptable 
      


      -------------------
      Cordialement,
      Clément
      0
      1. Bonjour Clément, tout d'abord merci pour le retour.

        Je suis en train de tester le script mais j'ai un message d'erreur suivant :
        "
        Msg 208, Niveau 16, État 1, Ligne 66
        Nom d'objet 'champ_calcul_sortie' non valide.
        "
        Voici le script:

        use test

        IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[csd_temp1]') AND type in (N'U'))
        DROP TABLE [dbo].[csd_temp1]

        create table csd_temp1

        (ID INT,champ_calcul nvarchar(50))

        insert into csd_temp1

        SELECT 1, '((CA_TOTO*CA_TITI)/CA_TXi))'
        UNION ALL
        SELECT 2,'CA_CARA*CA_RIT+CA_KOKO'

        if object_id('dbo.champ_calcul_sortie') is not null
        begin
        drop table dbo.champ_calcul_sortie
        create table champ_calcul_sortie (ID int,champ_calcul nvarchar(50))
        end

        select * into ##temptable from csd_temp1

        declare @id int, @compteur int
        declare db_cursor cursor for select id from csd_temp1

        OPEN db_cursor
        FETCH NEXT FROM db_cursor INTO @id

        WHILE @@FETCH_STATUS = 0
        BEGIN

        DECLARE
        @champ nvarchar(50),
        @count integer,
        @search varchar(10),
        @long_string varchar(500),
        @mot varchar (20),
        @debut int,
        @longueur int

        SET @champ = (select champ_calcul from ##temptable where id = @id)
        SET @search = 'CA_'
        SET @long_string = @champ

        SET @count = (DATALENGTH(@long_string) - DATALENGTH(REPLACE(@long_string, @search, ''))) / DATALENGTH(@search)

        set @compteur = 1

        if len(@champ)>3
        begin
        while @compteur<=@count
        begin
        set @longueur = 4
        set @champ = (select champ_calcul from ##temptable where id = @id)
        set @debut = charindex('CA_',@champ)

        while substring(@champ,@debut+@longueur,1) not in ('+',')') begin
        set @longueur = @longueur+1
        end

        set @mot = (select substring(@champ, @debut,@longueur) from ##temptable where ID = @id)

        insert into champ_calcul_sortie values (@id,@mot)
        update ##temptable set champ_calcul = replace(champ_calcul,@mot,'') where id = @id
        set @compteur = @compteur + 1
        end
        end

        FETCH NEXT FROM db_cursor INTO @id

        END
        CLOSE db_cursor
        DEALLOCATE db_cursor

        drop table ##temptable

        Merci de votre retour

        Ted
        0
        1. Bonjour,
          Pour moi ce code fonctionne (je l'ai un peu modifié, pour prendre en compte les mots qui finissent la chaine de caractère et qui n'ont pas de signes après eux) :

          use DB_TEMP
          
          IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[csd_temp1]') AND type in (N'U'))
          DROP TABLE [dbo].[csd_temp1]
          
          create table csd_temp1(ID INT,champ_calcul nvarchar(50))
          
          insert into csd_temp1
          
          SELECT 1, '((CA_TOTO*CA_TITI)/CA_TXi))'
          UNION ALL
          SELECT 2,'CA_CARA*CA_RIT+CA_KOKO'
          
          
          if object_id('dbo.champ_calcul_sortie') is not null
          begin
          drop table dbo.champ_calcul_sortie
          create table champ_calcul_sortie (ID int,champ_calcul nvarchar(50))
          end
          
          select * into ##temptable from csd_temp1
          update ##temptable set champ_calcul = champ_calcul + ')'
          declare @id int, @compteur int
          declare db_cursor cursor for select id from csd_temp1
          
          OPEN db_cursor
          FETCH NEXT FROM db_cursor INTO @id
          
          WHILE @@FETCH_STATUS = 0
          BEGIN
          
          DECLARE
          @champ nvarchar(50),
          @count integer,
          @search varchar(10),
          @long_string varchar(500),
          @mot varchar (20),
          @debut int,
          @longueur int
          
          SET @champ = (select champ_calcul from ##temptable where id = @id)
          SET @search = 'CA_'
          SET @long_string = @champ
          
          SET @count = (DATALENGTH(@long_string) - DATALENGTH(REPLACE(@long_string, @search, ''))) / DATALENGTH(@search)
          
          set @compteur = 1
          
          if len(@champ)>3
          begin
          while @compteur<=@count
          begin
          set @longueur = 4
          set @champ = (select champ_calcul from ##temptable where id = @id)
          set @debut = charindex('CA_',@champ)
          
          while substring(@champ,@debut+@longueur,1) not in ('+',')','*','-') begin
          set @longueur = @longueur+1
          end
          
          set @mot = (select substring(@champ, @debut,@longueur) from ##temptable where ID = @id)
          
          insert into champ_calcul_sortie values (@id,@mot)
          update ##temptable set champ_calcul = replace(champ_calcul,@mot,'') where id = @id
          set @compteur = @compteur + 1
          end
          end
          
          FETCH NEXT FROM db_cursor INTO @id
          
          END
          CLOSE db_cursor
          DEALLOCATE db_cursor
          
          drop table ##temptable

          0
          1. BonjourClément merci de votre retour, je viens de créer une base DB_TEMP afin de tester le script , je l'execute mais j'ai toujours le même message d'erreur suivant
            «

            (2 ligne(s) affectée(s))

            (2 ligne(s) affectée(s))

            (2 ligne(s) affectée(s))
            Msg 208, Niveau 16, État 1, Ligne 63
            Nom d'objet 'champ_calcul_sortie' non valide.
            «

            Merci d'avance

            Teddy
            0
            1. Bonjour,
              Ce doit être ce bloc qui empêche la suite de la requête de tourner :
              if object_id('dbo.champ_calcul_sortie') is not null
              begin
              drop table dbo.champ_calcul_sortie
              create table champ_calcul_sortie (ID int,champ_calcul nvarchar(50))
              end


              Remplacez la par celui-ci, sans le test :
              drop table dbo.champ_calcul_sortie
              create table champ_calcul_sortie (ID int,champ_calcul nvarchar(50))

              J'attends votre retour :-)
              0
            2. Bonjour Clément, j'ai rajouté au niveau de la création

              IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[champ_calcul_sortie]') AND type in (N'U'))
              DROP TABLE [dbo].[champ_calcul_sortie]
              create table champ_calcul_sortie (ID int,champ_calcul nvarchar(50))

              Et cela marche bp mieux, je vous remercie est l'script s'exécute parfaitement. Vous m'avez bien dépanné.

              Cordialement,

              Teddy
              0