IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement SQL Server Discussion :

Exécution d'une requête UPDATE dans une variable


Sujet :

Développement SQL Server

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 98
    Points : 61
    Points
    61
    Par défaut Exécution d'une requête UPDATE dans une variable
    Bonjour,
    J'ai la procédure ci-dessous, qui va chercher des infos dans l'AD et qui les stock ensuite dans une table temporaire pour un traitement ultérieur.
    Pour l'insertion des données, cela fonctionne bien, mais je souhaite faire un UPDATE également de temps en temps. Le truc c'est que je ne sais pas comment faire un update lorsqu'on utilise un EXEC(@myquery). CF. la partie 3.2, en rouge, de mon code. J'ai parcouru internet et pas trouvé d'exemple allant dans mon sens. Alors ce n'est peut être pas possible avec ce code, mais pouvez-vous me le confirmer et me dire comment est-ce que je devrais faire ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    ALTER  PROCEDURE [ITS_selectLdapUsers]
     
    AS 
    BEGIN 
          DECLARE @userName             AS NVARCHAR(50) 
          DECLARE @adsiquery            AS nvarchar(4000) 
          DECLARE @adspath              AS nvarchar(1000) 
    
    select @adspath = '<LDAP://DC=root,DC=myserveur,DC=myextension>' 
    
    SET NOCOUNT ON;
     
    
    -- 1. Get all the staff members 
    DECLARE rs CURSOR FOR
     
    SELECT SAMAccountName
    FROM OPENQUERY(ADSI,'<LDAP://DC=root,DC=myserveur,DC=myextension>;(&(objectCategory=person)  (objectClass=user) (givenname=*)  );SAMAccountName;subtree')
    ORDER BY SAMAccountName 
    
    OPEN rs
    
    -- 2. Get first value 
    FETCH NEXT FROM rs INTO @userName 
    
    
     
    -- 3. Start the loop for all employee department members 
    WHILE @@FETCH_STATUS = 0 
    BEGIN 
          -- 3.1 Read data from LDAP 
          set @adsiquery='( 
    
     SELECT  
                       SAMAccountName as         em_id  
                      ,givenname                    AS name_first 
                      ,sn                           AS name_last 
                      ,mail                        AS email 
    		  ,SUBSTRING(ADsPath,LEN(LEFT(ADsPath,CHARINDEX('','',ADsPath)+1)),LEN(ADsPath)-LEN(RIGHT(ADsPath,20))-LEN(LEFT(ADsPath,CHARINDEX('','',ADsPath)))) AS OU  
    
                FROM openquery 
    (ADSI, '''+@adspath+';(&(objectCategory=person)  (objectClass=user)(SAMAccountName='+@userName+') );SAMAccountName,givenName,sn,mail,ADsPath;subtree'') 
     )'
    
    
          -- 3.2 Insert / update data into gobal temp database 
     
    	IF NOT EXISTS (SELECT 1 FROM em_temp WHERE em_id = @userName)
             BEGIN
               INSERT INTO em_temp ( 
                      em_id 
                      ,name_first 
                      ,name_last 
                      ,email 
    		 ,OU ) 
    		EXEC (@adsiquery)  	
    	END
    	ELSE
    	BEGIN
    		  UPDATE em_temp 
                      SET name_first=????(givenname),  name_last=????(sn), email=???(mail)
                      WHERE em_id=@userName
    		EXEC (@adsiquery) 
    	END			  
    
    
    FETCH NEXT FROM rs INTO @userName 
    END
    
    CLOSE rs 
    DEALLOCATE rs 
    
    END

  2. #2
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    Vous ne pouvez pas utiliser les résultat d'un exec comme ceci. Tout au plus, vous pouvez insérer le résultat dans une table, mais pas l'utiliser comme une pseudo table.

    Vous povuez envisager d'inserer le tous vos résultat dans une table temporaire, et faire un MERGE au final.

    Voire directement faire une MERGE en utilisant les openquery comme source.

    Quelque chose dans ce genre, sans doute a adapter :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
    ALTER  PROCEDURE [ITS_selectLdapUsers]
     
    AS 
    BEGIN 
     
          DECLARE @adspath              AS nvarchar(1000) 
     
    select @adspath = '<LDAP://DC=root,DC=myserveur,DC=myextension>' 
     
    SET NOCOUNT ON;
     
          -- 3.2 Insert / update data into gobal temp database 
    MERGE em_temp c
    USING (
    	SELECT  
     
    		,SAMAccountName				as em_id  
    		,givenname                  AS name_first 
    		,sn                         AS name_last 
    		,mail                       AS email 
    		,SUBSTRING(ADsPath,LEN(LEFT(ADsPath,CHARINDEX('','',ADsPath)+1)),LEN(ADsPath)-LEN(RIGHT(ADsPath,20))-LEN(LEFT(ADsPath,CHARINDEX('','',ADsPath)))) AS OU  
    	FROM OPENQUERY(ADSI,'<LDAP://DC=root,DC=myserveur,DC=myextension>;(&(objectCategory=person)  (objectClass=user) (givenname=*)  );SAMAccountName;subtree')
    	CROSS APPLY openquery (ADSI, @adspath+';(&(objectCategory=person)  (objectClass=user)(SAMAccountName='+SAMAccountName+') );SAMAccountName,givenName,sn,mail,ADsPath;subtree') 
    ) s
    	ON s.em_id = c.em_id
    WHEN MATCHED THEN 
    	  UPDATE 
                 SET name_first=src.name_first
                 ,  name_last=src.name_last
                 , email=src.email
    WHEN NOT MATCHED BY TARGET THEN  
    	INSERT ( 
                em_id 
                ,name_first 
                ,name_last 
                ,email 
    			,OU ) 
    	VALUES ( 
                src.em_id 
                ,src.name_first 
                ,src.name_last 
                ,src.email 
    			,src.OU 
    		)
     
    ;
    END

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 98
    Points : 61
    Points
    61
    Par défaut
    Merci pour votre réponse. Etant un gros néophyte, je vais étudier cette fonction MERGE.

    La j'insère effectivement les données dans une table temporaire. Je me dit que de faire un update si les données sont déjà existantes dans cette table temporaire par rapport à l'AD, ca peut me faire gagner du temps de traitement par rapport à un delete / insert à chaque exécution de la procédure.

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 98
    Points : 61
    Points
    61
    Par défaut
    Hello,
    Voici ce que j'ai modifié et ca me donne un premier résultat prometteur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    ALTER  PROCEDURE [ITS_selectLdapUsers]  
     
    AS 
    BEGIN 
     
    SET NOCOUNT ON;
     
          -- 3.2 Insert / update data into gobal temp database 
    MERGE em_temp c
    USING (
    	SELECT  
                       SAMAccountName as         em_id  
                      ,givenname                    AS name_first 
                      ,sn                           AS name_last 
                      ,mail                        AS email
    				  ,[net-user-name]		AS net_user_name
    				  ,SUBSTRING(department,0,16) as dp_id
    				  ,ADsPath  AS OU
    				  --,SUBSTRING(ADsPath,LEN(LEFT(ADsPath,CHARINDEX('','',ADsPath)+1)),LEN(ADsPath)-LEN(RIGHT(ADsPath,20))-LEN(LEFT(ADsPath,CHARINDEX('','',ADsPath)))) AS OU 
     
    	FROM OPENQUERY(ADSI,'<LDAP://root.blabla:3268/DC=root,DC=blabla,DC=blibli>;(&(objectCategory=person)  (objectClass=user) (givenname=f*) );SAMAccountName,givenName,sn,mail,net-user-name,department,ADsPath;subtree')
    ) s
    	ON s.em_id COLLATE DATABASE_DEFAULT = c.em_id COLLATE DATABASE_DEFAULT
    WHEN MATCHED THEN 
    	  UPDATE 
                 SET name_first=s.name_first
                 ,  name_last=s.name_last
                 , email=s.email
    			,net_user_name = s.net_user_name
    			,dp_id=s.dp_id
    			,OU =s.ou	
    WHEN NOT MATCHED BY TARGET THEN  
    	INSERT ( 
                em_id 
                ,name_first 
                ,name_last 
                ,email
    			,net_user_name
    			,dp_id
    			,ou
    			 ) 
    	VALUES ( 
                s.em_id 
                ,s.name_first 
                ,s.name_last 
                ,s.email
    			,s.net_user_name
    			,s.dp_id
    			,s.ou	 
    		)
    WHEN NOT MATCHED BY SOURCE THEN
    	DELETE
     
     OUTPUT $action, Inserted.*, Deleted.*;
     
    END
    et donc merci infiniment
    Mais pour le coup je me retrouve avec 2 nouvelles difficultés:
    • l'utilisation des variables..
    • et ma fonction substring qui ne marche plus


    Le plus important:
    Comme je vais piocher dans l'AD; et qu'on est limité par le nb d'enregistrement retournés, je comptais utiliser cet attribut pour les filtres. Et en faire une variable, affectée via l'appelle de ma procédure. -->givenname=+@mavar
    Dans mon premier cas, j'ai mis toute la partie de la requête dans une variable adsiquery, alors ca fonctionnait. Ici je ne peux pas mettre de variable directement dans l'openquery.
    Quelle serait la marche à suivre ?
    J'ai essayé de mettre toute l'instruction SQL dans une variable adsiquery , mais lors de l'exec le système dit qu'il ne prend pas en charge MERGE. Je ne comprends pas pourquoi.

    Et c'est aussi lié avec ma ligne en commentaire ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SUBSTRING(ADsPath,LEN(LEFT(ADsPath,CHARINDEX('','',ADsPath)+1)),LEN(ADsPath)-LEN(RIGHT(ADsPath,20))-LEN(LEFT(ADsPath,CHARINDEX('','',ADsPath)))) AS OU
    Lorsqu'elle était dans la variable adsiquery , ca fonctionnait, et maintenant ,j'ai une erreur comme quoi charindex n'aime pas les varchar.
    mais bon ca c'est moins important. Ca m'affiche juste l'OU d'une façon plus lisible.

Discussions similaires

  1. [AC-2007] Sous-requête "Select" dans une requête "update"
    Par MatAllwhite dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 27/06/2013, 14h00
  2. Stocker une requête update dans une table
    Par bigtruck2010 dans le forum PL/SQL
    Réponses: 4
    Dernier message: 07/07/2011, 12h57
  3. erreur dans une requête sql dans une fonction php
    Par frboyer dans le forum Langage
    Réponses: 3
    Dernier message: 07/04/2009, 13h37
  4. [MySQL] Exécuter une requête UPDATE dans une boucle
    Par vacknov dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 24/10/2008, 17h46
  5. [Requête] Utilisation d'une fonction perso dans une requête
    Par Julien Dufour dans le forum Requêtes et SQL.
    Réponses: 5
    Dernier message: 16/03/2007, 09h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo