Search code examples
sqlsql-servert-sqlsql-server-2008ordinal

Access columns of a table by index instead of name in SQL Server stored procedure


Is there a way to access columns by their index within a stored procedure in SQL Server?

The purpose is to compute lots of columns. I was reading about cursors, but I do not know how to apply them.

Let me explain my problem:

I have a row like:

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

I need to compute something like (field_1*field1) - (Sfield_1* Sfiled_1) / more...

So the result is stored in a table column d times.

So the result is a d column * d row table.

As the number of columns is variable, I was considering making dynamic SQL, getting the names of columns in a string and splitting the ones I need, but this approach makes the problem harder. I thought getting the column number by index could make life easier.


Solution

  • First, as OMG Ponies stated, you cannot reference columns by their ordinal position. This is not an accident. The SQL specification is not built for dynamic schema either in DDL or DML.

    Given that, I have to wonder why you have your data structured as you do. A sign of a mismatch between schema and the problem domain rears itself when you try to extract information. When queries are incredibly cumbersome to write, it is an indication that the schema does not properly model the domain for which it was designed.

    However, be that as it may, given what you have told us, an alternate solution would be something like the following: (I'm assuming that field_1*field1 was meant to be field_1 * field_1 or field_1 squared or 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
    

    Now your query looks like:

    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