Heim  >  Fragen und Antworten  >  Hauptteil

So verwenden Sie Cursor zum Extrahieren von Daten aus mehreren Tabellen

<p>Ich habe eine Abfrage, die mehrere Tabellen zurückgibt, etwa so: </p> <pre class="brush:php;toolbar:false;">SELECT TableName, DatabaseName +'.'+ TableName, ColumnName VON DBC.Columns WHERE ColumnName = 'id'</pre> <p>Ich muss diese Tabellen durchlaufen und mir die darin gespeicherten Informationen ansehen, um nur bestimmte Tabellen zu erhalten. </p> <p>Ich habe den Code unten mit „LOOP“ und einem Cursor ausprobiert, aber er sagt <code>Ungültige Abfrage</code> (Code kommt von hier): </p> <pre class="brush:php;toolbar:false;">DECLARE Cursor_Tables CURSOR FOR SELECT Datenbankname ||. '.' VON DBC.Columns WHERE ColumnName ='id'; OPEN Cursor_Tables; Etikett1: SCHLEIFE FETCH Cursor_Tables in tbName; WENN (SQLSTATE ='02000') DANN LEAVE label1; ENDE WENN; FALL, WENN ( ZÄHLER AUSWÄHLEN(*) VON prd3_db_tmd.K_PTY_NK01 WHERE id = 0 ) > DANN tbName ENDE END LOOP label1; CLOSE Cursor_Tables; ENDE;</pre> <p>Wie soll ich dieses Problem lösen? Muss ich zusätzliche gespeicherte Prozeduren verwenden? Das DBMS ist Teradata. </p>
P粉141035089P粉141035089451 Tage vor554

Antworte allen(2)Ich werde antworten

  • P粉221046425

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

    如果这是SQL Server,您可以查看以下SQL游标,我编辑了游标声明和其中的代码 虽然它们可能与您的要求不同,但我认为您可以轻松修改

    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;

    Antwort
    0
  • P粉752479467

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

    您需要一个存储过程,因为这是在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;

    Antwort
    0
  • StornierenAntwort