Accedere alle colonne di una tabella in base all'indice anziché al nome nella stored procedure di SQL Server

StackOverflow https://stackoverflow.com/questions/4882837

Domanda

Esiste un modo per accedere alle colonne in base al loro indice all'interno di una stored procedure in SQL Server?

Lo scopo è calcolare molte colonne.Stavo leggendo dei cursori, ma non so come applicarli.

Lascia che ti spieghi il mio problema:

Ho una riga del tipo:

field_1 field_2 field_3 field_4 ...field_d  Sfield_1 Sfield_2 Sfield_3...Sfield_n
1       2       3       4          d        10       20       30         n

Devo calcolare qualcosa come (field_1*field1) - (Sfield_1* Sfiled_1) / more...

Quindi il risultato viene memorizzato in una colonna della tabella d volte.

Quindi il risultato è una tabella d column * d row.

Poiché il numero di colonne è variabile, stavo valutando la possibilità di creare SQL dinamico, ottenere i nomi delle colonne in una stringa e suddividere quelli di cui ho bisogno, ma questo approccio rende il problema più difficile.Pensavo che ottenere il numero di colonna in base all'indice potesse semplificarti la vita.

È stato utile?

Soluzione

Innanzitutto, come affermato da OMG Ponies , non puoi fare riferimento alle colonne in base alla loro posizione ordinale.Questo non è un incidente.La specifica SQL non è creata per lo schema dinamico né in DDL né in DML.

Detto questo, mi chiedo perché hai i tuoi dati strutturati come fai.Un segno di una mancata corrispondenza tra lo schema e il dominio problematico si genera quando si tenta di estrarre le informazioni.Quando le query sono incredibilmente complicate da scrivere, è un'indicazione che lo schema non modella correttamente il dominio per il quale è stato progettato.

Comunque sia, dato quello che ci hai detto, una soluzione alternativa sarebbe qualcosa del genere: (presumo che field_1*field1 fosse pensato per essere field_1 * field_1 o field_1 squared o Power( field_1, 2 ))

Select 1 As Sequence, field_1 As [Field], Sfield_1 As [SField], Sfiled_1 As [SFiled]
Union All Select 2, field_2, Sfield_2, Sfiled_2
...
Union All Select n, field_n, Sfield_n, Sfiled_n

Ora la tua query avrà il seguente aspetto:

With Inputs As
    (
    Select 1 As Sequence, field_1 As [Field], Sfield_1 As [SField], Sfiled_1 As [SFiled]
    Union All Select 2, field_2, Sfield_2, Sfiled_2
    ....
    )
    ,  Results As
    (
    Select Case
            When Sequence = 1 Then Power( [Field], 2 ) - ( [SField] * [SFiled] ) 
            Else 1 / Power( [Field], 2 ) - ( [SField] * [SFiled] ) 
            End
            As Result
    From Inputs
    )
Select Exp( Sum( Log( Result ) ) )
From Results

Altri suggerimenti

No, non è possibile utilizzare la posizione ordinale (numerica) nella clausola SELECT.

Solo nella clausola ORDER BY è possibile utilizzare la posizione ordinale, perché si basa sulle colonne specificate nella clausola SELECT.

Questo potrebbe non essere il più elegante o efficiente ma funziona.Lo sto usando per creare una nuova tabella per mappature più veloci tra i dati di cui ho bisogno per analizzare tutte le colonne / righe.

DECLARE @sqlCommand varchar(1000)
DECLARE @columnNames TABLE (colName varchar(64), colIndex int)
DECLARE @TableName varchar(64) = 'YOURTABLE' --Table Name
DECLARE @rowNumber int = 2 -- y axis
DECLARE @colNumber int = 24 -- x axis

DECLARE @myColumnToOrderBy varchar(64) = 'ID' --use primary key

--Store column names in a temp table
INSERT INTO @columnNames (colName, colIndex)
SELECT COL.name AS ColumnName, ROW_NUMBER() OVER (ORDER BY (SELECT 1))
    FROM sys.tables AS TAB
    INNER JOIN sys.columns AS COL ON COL.object_id = TAB.object_id
    WHERE TAB.name = @TableName
    ORDER BY COL.column_id;

DECLARE @colName varchar(64)
SELECT @colName = colName FROM @columnNames WHERE colIndex = @colNumber

--Create Dynamic Query to retrieve the x,y coordinates from table
SET @sqlCommand = 'SELECT ' + @colName + ' FROM (SELECT ' + @colName + ', ROW_NUMBER() OVER (ORDER BY ' + @myColumnToOrderBy+ ') AS RowNum FROM ' + @tableName + ') t2 WHERE RowNum = ' + CAST(@rowNumber AS varchar(5))
EXEC(@sqlCommand)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top