2013-12-09 4 views
6

Я просто придумал идею фрагмента кода, чтобы показать все отдельные значения для каждого столбца и подсчитать, сколько записей для каждого. Я хочу, чтобы код проходил через все столбцы.Цитирование по именам столбцов с динамическим SQL

Вот что я до сих пор ... Я новичок в SQL так терпите с noobness :)

Hard Код:

select [Sales Manager], count(*) 
    from [BT].[dbo].[test] 
    group by [Sales Manager] 
    order by 2 desc 

попытка динамического SQL:

Declare @sql varchar(max), 
@column as varchar(255) 

    set @column = '[Sales Manager]' 
    set @sql = 'select ' + @column + ',count(*) from [BT].[dbo].[test] group by ' + @column + 'order by 2 desc' 

    exec (@sql) 

Оба эти работы отлично. Как я могу сделать это через все столбцы? Я не возражаю, если мне придется жестко закодировать имена столбцов, и он прокладывает себе путь через subbing в каждом из них для @column.

Имеет ли это смысл?

Спасибо всем!

ответ

5

Вы можете использовать динамический SQL и получить все имена столбцов для таблицы. Затем создать сценарий:

Declare @sql varchar(max) = '' 
declare @tablename as varchar(255) = 'test' 

select @sql = @sql + 'select [' + c.name + '],count(*) as ''' + c.name + ''' from [' + t.name + '] group by [' + c.name + '] order by 2 desc; ' 
from sys.columns c 
inner join sys.tables t on c.object_id = t.object_id 
where t.name = @tablename 

EXEC (@sql) 

Изменение @tablename на имя вашей таблицы (без имени базы данных или схемы).

+1

Я пробовал этот код ... Казалось, что он работает, но я должен что-то добавить? Я не вижу там петли? Cheers, – Lucas

+1

Вам не нужен цикл, все запросы для всех столбцов находятся в переменной '@ sql'. – Szymon

+0

Эй, шимон. Ладно, я думаю, что понял ... ха-ха. Я получаю «команда завершена успешно», но результат не показан ... Какую часть кода я должен изменить на свои собственные значения? – Lucas

8

Это немного ответ XY, но если вы не возражаете против жесткого кодирования имен столбцов, я предлагаю вам сделать именно это и избежать динамического SQL - и цикла - полностью. Динамический SQL, как правило, считается последним, открывает проблемы безопасности (атаки SQL-инъекций), если они не являются осторожными, и часто может быть медленнее, если запросы и планы выполнения не могут быть кэшированы.

Если у вас есть тонна имен столбцов, вы можете написать быстрый фрагмент кода или слияние в Word, чтобы сделать замену для вас.


Однако, насколько, как получить имена столбцов, если предположить, это SQL Server, можно использовать следующий запрос:

SELECT c.name 
FROM sys.columns c 
WHERE c.object_id = OBJECT_ID('dbo.test') 

Таким образом, вы можете создать свой динамический SQL из этого запроса:

SELECT 'select ' 
    + QUOTENAME(c.name) 
    + ',count(*) from [BT].[dbo].[test] group by ' 
    + QUOTENAME(c.name) 
    + 'order by 2 desc' 
FROM sys.columns c 
WHERE c.object_id = OBJECT_ID('dbo.test') 

и петля с использованием курсора.

Или скомпилируйте все это вместе в одну партию и выполните. Здесь мы используем FOR XML PATH('') трюк:

DECLARE @sql VARCHAR(MAX) = (
    SELECT ' select ' --note the extra space at the beginning 
     + QUOTENAME(c.name) 
     + ',count(*) from [BT].[dbo].[test] group by ' 
     + QUOTENAME(c.name) 
     + 'order by 2 desc' 
    FROM sys.columns c 
    WHERE c.object_id = OBJECT_ID('dbo.test') 
    FOR XML PATH('') 
) 

EXEC(@sql) 

Примечание Я использую the built-in QUOTENAME function бежать имена столбцов, которые нужно убегающих.

Смежные вопросы