Sql-server – Can you use dynamic sql in a select statement

dynamic-sqlsql server

I have the following code:

select
    [schema].[name]     [schema],
    [table].[name]      [table],
    [column].[name]     [column],
    [type].[name]       [type],
    [column].max_length [maxAllowedLength],
    exec('select max(len(' + [column].[name] + ')) from ' + [table].[name]) maxDataLength
from sys.schemas [schema]
    join sys.tables [table] on [schema].schema_id = [table].schema_id
        join sys.columns [column] on [table].object_id = [column].object_id
            join sys.types [type] on type.system_type_id = [column].system_type_id
where 1=1
and   [schema].[name] = 'dbo'
and   [table].[name]  = 'TableToAnalyze'
order by [schema].[name], [table].[name]

But it doesn't work. Can I do what I'm trying to do? I'd like to also add other information, like minimum length and whether there are any non-numbers, non-dates, dates, etc. to it as well, but that all depends on the basic framework.

In case it's not clear, I want one row per column in the table 'TableToAnalyze', and each row should have the schema, table, column, type, maximum allowable size, and (the part that's giving me trouble is) the maximum actual data length, all for each column in the table I'm analyzing.

It was recommended I use a cross apply, so I tried

select
    [schema].[name]     [schema],
    [table].[name]      [table],
    [column].[name]     [column],
    [type].[name]       [type],
    [column].max_length [maxAllowedLength],
    maxDataLength
from sys.schemas [schema]
    join sys.tables [table] on [schema].schema_id = [table].schema_id
        join sys.columns [column] on [table].object_id = [column].object_id
            join sys.types [type] on type.system_type_id = [column].system_type_id
            cross apply (exec('select max(len(' + [column] + ')) from ' + [table].[name])) maxDataLength
where 1=1
and   [schema].[name] = 'dbo'
and   [table].[name]  = 'TableToAnalyze'
order by [schema].[name], [table].[name]

But that doesn't work either.

Best Answer

You can never use dynamic SQL in a SELECT or in a function. The Query Optimizer for the outer query wouldn't know what your dynamic batch does, and it might try changing the database. In which case there's no way to build a correct query plan.