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.
    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
      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 !
    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
      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
        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

          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
            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 :-)
            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