2014-12-08 18 views
1

Мне нужно сравнить длину определения и фактическое значение в SQL.Получить максимальную длину каждого столбца динамически SQL

Например:

+--------------|---------------------|-------------+ 
    COLUMN_NAME | DefinitionMaxLength |ActualLength 
+--------------|---------------------|-------------+ 
COL 1   | 20     | 25 
COL 2   | 30     | 26 

Вот мой SQL для получения метаданных таблицы.

SELECT COLUMN_NAME, CHARACTER_MAXIMUM_LENGTH AS DefinitionMaxLength 
from INFORMATION_SCHEMA.COLUMNS as COL 
WHERE COL.DATA_TYPE ='varchar' AND COL.TABLE_NAME='TableSRC' 

Моя проблема теперь в том, как получить максимальную длину фактической таблицы. Я использовал Max(Len(COLUMN_NAME)), но это не сработает.

SELECT TABLE_NAME, COLUMN_NAME, CHARACTER_MAXIMUM_LENGTH AS DefinitionMaxLength, MAX(LEN(COLUMN_NAME)) 
from INFORMATION_SCHEMA.COLUMNS as COL 
WHERE COL.DATA_TYPE ='varchar' AND COL.TABLE_NAME='TableSRC' 

COLUMN_NAME основан на выходе метаданных.

+0

Я использую SQL Server. – MMakati

ответ

3

Попробуйте:

SELECT COLUMN_NAME, CHARACTER_MAXIMUM_LENGTH AS DefinitionMaxLength 
, N'SELECT @resultOUT = MAX(LEN(' + COLUMN_NAME + ')) FROM ' + COL.TABLE_NAME [query] 
, ORDINAL_POSITION 
, 0 [ActualMaxLength] 
INTO #tmp 
FROM INFORMATION_SCHEMA.COLUMNS as COL 
WHERE COL.DATA_TYPE ='varchar' AND COL.TABLE_NAME='TableSRC'; 

DECLARE 
    @pos int = (SELECT MIN(ORDINAL_POSITION) FROM #tmp), 
    @result int, 
    @query NVARCHAR(MAX) = N'', 
    @param_def NVARCHAR(100) = N'@resultOUT int OUTPUT'; 

WHILE EXISTS (SELECT * FROM #tmp WHERE ORDINAL_POSITION > @pos) 
BEGIN 
    SELECT @query = [query] FROM #tmp WHERE ORDINAL_POSITION = @pos; 
    EXECUTE sp_executesql @query, @param_def, @resultOUT = @result OUTPUT; 

    UPDATE #tmp SET [ActualMaxLength] = ISNULL(@result, 0) WHERE ORDINAL_POSITION = @pos; 

    SET @pos = (SELECT MIN(ORDINAL_POSITION) FROM #tmp WHERE ORDINAL_POSITION > @pos); 
END 

SELECT COLUMN_NAME, DefinitionMaxLength, ActualMaxLength FROM #tmp; 

DROP TABLE #tmp; 
0

Сделайте агрегацию в cte и присоединитесь к информационной_схеме.

with data_length(column_name, actual_max_length) as 
(
select 'col1', max(len(col1)) 
from t 
union all 
select 'col2', max(len(col2)) 
from t 
) 

select c.column_name, c.character_maximum_length, d.actual_max_length 
from information_schema.columns c 
join data_length do 
on d.column_name = c.column_name 
where c.table_name = 't' 
Смежные вопросы