Maison  >  Questions et réponses  >  le corps du texte

Comment utiliser des curseurs pour extraire des données de plusieurs tables

<p>J'ai une requête qui renvoie plusieurs tables, quelque chose comme ceci : </p> <pre class="brush:php;toolbar:false;">SELECT Nom de la table, Nom de la base de données +'.'+ Nom de la table, Nom de la colonne DE DBC.Colonnes OÙ NomColonne = 'id'</pre> <p>Je dois parcourir ces tableaux en examinant les informations qui y sont stockées afin d'obtenir uniquement des tableaux spécifiques. </p> <p>J'ai essayé le code ci-dessous, en utilisant 'LOOP' et un curseur, mais il indique <code>Invalid query</code> (le code vient d'ici) : </p> <pre class="brush:php;toolbar:false;">DÉCLARE curseur_Tables CURSEUR POUR SELECT Nom de la base de données || DE DBC.Colonnes OÙ NomColonne ='id'; OUVRIR Curseur_Tables ; étiquette1 : BOUCLE FETCH curseur_Tables dans tbName ; SI (SQLSTATE ='02000') ALORS QUITTER l'étiquette1 ; FIN SI; CAS QUAND ( SÉLECTIONNER LE COMPTE(*) DE prd3_db_tmd.K_PTY_NK01 OÙ identifiant = 0 ) > ALORS tbName FIN Étiquette de FIN DE BOUCLE1 ; FERMER curseur_Tables ; FIN;≪/pré> <p>Comment dois-je résoudre ce problème ? Dois-je utiliser des procédures stockées supplémentaires ? Le SGBD est Teradata. </p>
P粉141035089P粉141035089430 Il y a quelques jours536

répondre à tous(2)je répondrai

  • P粉221046425

    P粉2210464252023-08-17 11:13:22

    S'il s'agit de SQL Server, vous pouvez consulter le Curseur SQL suivant, j'ai modifié la déclaration du curseur et le code qu'elle contient Bien qu'ils puissent être différents de vos exigences, je pense que vous pouvez facilement les modifier

    declare @sql nvarchar(max)
    declare @tablename nvarchar(100)
    
    DECLARE cursor_Tables CURSOR FOR     
        SELECT s.name + '.' + o.name 
            --s.name [schema], o.name [table]
        FROM   sys.Columns c
        inner join sys.objects o on c.object_id = o.object_id
        inner join sys.schemas s on s.schema_id = o.schema_id
        WHERE  c.Name  ='id' and o.type = 'U'
    
    /*
    SELECT TableName, DatabaseName +'.'+ TableName, ColumnName
    FROM DBC.Columns
    WHERE ColumnName = 'id'
    */
    OPEN cursor_Tables; 
    
    FETCH NEXT FROM cursor_Tables INTO @tablename
    
    WHILE @@FETCH_STATUS = 0
    BEGIN
    
    --  print @tablename
    set @sql = 'select case when count(*) > 0 then ''' + @tablename + ''' else '''' end from ' + @tablename
    exec sp_executesql @sql
    
     FETCH NEXT FROM cursor_Tables INTO @tablename
    END
    
    CLOSE cursor_Tables;
    DEALLOCATE cursor_Tables;

    répondre
    0
  • P粉752479467

    P粉7524794672023-08-17 09:39:26

    Vous avez besoin d'une procédure stockée car c'est le seul endroit où les curseurs peuvent être utilisés dans Teradata.

    REPLACE PROCEDURE testproc()
    DYNAMIC RESULT SETS 1
    BEGIN
       DECLARE tbName VARCHAR(257);
       DECLARE SqlStr VARCHAR(500);
    
       -- 临时表来存储结果集
       CREATE VOLATILE TABLE _vt_(tbName VARCHAR(257)) ON COMMIT PRESERVE ROWS;
    
       -- 您现有的查询来返回表名
       -- 最好使用ColumnsV而不是Columns
       FOR cursor_Tables AS    
           SELECT DatabaseName || '.' || TABLENAME AS tbName
           FROM   DBC.ColumnsV
           WHERE  ColumnName  ='id'
       DO -- 准备动态SQL ...
          SET SqlStr = 
             'insert into _vt_
              select ''' || cursor_tables.tbName || ''' 
              from ' || cursor_tables.tbName || '
              where id = 0 
              having count(*) > 0;
              ';
          -- ... 并执行它
          EXECUTE IMMEDIATE SqlStr;
       END FOR;
    
       BEGIN -- 返回结果集
          DECLARE resultset CURSOR WITH RETURN ONLY FOR S1;
          SET SqlStr = 'SELECT * FROM _vt_;';
          PREPARE S1 FROM SqlStr;
          OPEN resultset;
       END;
    
       DROP TABLE vt;
    END;

    répondre
    0
  • Annulerrépondre