La creazione di istruzioni SQL UPDATE al volo

Io sono in mezzo a l’aggiornamento dei dati in più tabelle. Attualmente ho una tabella che contiene un campo, “fonti”, che è solo un elenco di tutte le tabelle che includono il campo “itemid”. Anche io ho una tabella con 2 campi, “itemid” e “olditemid”. In TSQL, vorrei scorrere le fonti e creare le istruzioni di aggiornamento al volo. Qui è quello che stavo cercando di fare, ma mi da alcuni errori nell’istruzione update che la mia variabile non dichiarata. Io non sono sicuro che questo è anche vicino il modo corretto devo fare questo. Idee?

DECLARE @tblName varchar(50)

DECLARE process_cursor CURSOR FOR 
    SELECT source 
    FROM tmpTableNames

OPEN process_cursor

FETCH NEXT FROM processcursor 
INTO @tblName

WHILE @@FETCH_STATUS = 0

    UPDATE @tblName 
        SET itemid = r.itemid 
        FROM @tblName v, itemref r
        WHERE r.olditemid = v.itemid

    FETCH NEXT FROM process_cursor
    INTO @tblName

END
CLOSE processcursor
DEALLOCATE processcursor
  • dovrebbe essere di tipo sysname che è il giusto tipo e la lunghezza per i nomi degli oggetti. varchar(50) è troppo breve per alcuni oggetti, e i nomi delle tabelle sono permesso di contenere caratteri unicode.
InformationsquelleAutor SDC | 2009-09-09

 

5 Replies
  1. 4

    Quello che stai cercando di fare è indicato come “SQL dinamico”. Mentre siete sulla strada giusta, non si può semplicemente attaccare una variabile al posto del nome di un oggetto e di eseguire la query. Lascio le insidie di SQL dinamico a qualcun altro. Quello che stai cercando è questo:

    DECLARE @tblName varchar(50)
    
    DECLARE process_cursor CURSOR FOR 
        SELECT source 
        FROM tmpTableNames
    
    OPEN process_cursor
    
    FETCH NEXT FROM processcursor 
    INTO @tblName
    
    WHILE @@FETCH_STATUS = 0
    BEGIN
        DECLARE @sql NVARCHAR(500)
    
        SELECT @sql = 'UPDATE [' + @tbleName + '] SET itemid = r.itemid FROM [' + @tbleName + '] v, itemref r WHERE r.ilditemid = v.itemid'
    
        EXEC sp_executesql @sql
        FETCH NEXT FROM process_cursor
        INTO @tblName
    
    END
    CLOSE processcursor
    DEALLOCATE processcursor

    Quello che fa è accendere la tua query di aggiornamento in una stringa, poi passa SQL contenute nella stringa per il sp_executesql stored procedure (questo è il metodo consigliato per l’esecuzione di sql dinamico, piuttosto che EXEC('foo')).

    • Si dovrebbe sempre usare QUOTENAME per avvolgere i nomi di oggetti, come il tavolo in un vero e proprio [ e ] staffe.
    • Buona pesca. Corretto.
  2. 3

    Non credo che si può fare uso di una variabile di simile. Si potrebbe utilizzare SQL dinamico per l’aggiornamento:

    DECLARE @sql VARCHAR(1000)
    
    SET @sql = 'UPDATE' + @tableName + etc..
    
    EXEC ( @sql )

    E solo fare questo all’interno del vostro cursore.

  3. 1

    Non è possibile eseguire sql dinamico come questo, è necessario passare un generati dinamicamente la stringa nella funzione exec come questo:

    DECLARE @tblName varchar(50)
    
    DECLARE process_cursor CURSOR FOR 
        SELECT source 
        FROM tmpTableNames
    
    OPEN process_cursor
    
    FETCH NEXT FROM processcursor 
    INTO @tblName
    
    WHILE @@FETCH_STATUS = 0
    
        Declare @sql varchar(5000)
        Select @sql = 'UPDATE ' + @tblName +  
            'SET itemid = r.itemid 
            FROM ' + @tblName + ' v, itemref r
            WHERE r.olditemid = v.itemid'
    
        Exec @sql
        FETCH NEXT FROM process_cursor
        INTO @tblName
    
    END
    CLOSE processcursor
    DEALLOCATE processcursor
  4. 0

    hai provato
    DECLARE @tblName varchar(50)?
    Penso che dovrebbe fare.

    • Ho fatto dichiarare fino in alto.
    • Si può avere perso la dichiarazione di non formattato codice.
  5. 0

    Non ho mai avuto successo con la variabile di base di istruzioni di AGGIORNAMENTO (cioè, AGGIORNAMENTO @tblName), a meno che ho catturato in una stringa ed eseguito questi in modo dinamico, come in:

    EXEC 'UPDATE ' + @tblName + '
    SET ItemId = (SELECT r.ItemId FROM itemref r WHERE r.OldItemId = ' + @tblName + '.itemId)'

    Per la tabella TheTable, questo dovrebbe espandere a:

    EXEC 'UPDATE TheTable
          SET ItemId = (SELECT r.ItemId FROM itemref r WHERE r.OldItemId = TheTable.ItemId)'

Lascia un commento