Как создать/добавить столбцы, используя переменную в цикле

Я новичок в SQL и только что закончил читать Sams Teach Yourself SQL in 10 Minutes и это мое единственное знание SQL. Итак, теперь, когда я закончил с книгой, я пытаюсь создать несколько таблиц, чтобы поиграть с ними. Я могу легко создать таблицу с известным количеством столбцов и указанным заголовком. У меня возникают проблемы с созданием таблицы с неизвестным количеством столбцов и датой в качестве заголовка. То, что я пробовал до сих пор, это:

DECLARE @start_date AS DATE
DECLARE @end_date AS DATE
DECLARE @curr_date AS DATE
DECLARE @column_name AS CHAR(10)

SET @start_date = 2016-01-02
SET @end_date = 2016-12-31
SET @curr_date = @start_date

WHILE @curr_date < @end_date
    SET @curr_date = DATEADD(DD, 7, @curr_date)
    ALTER TABLE Project_1
        ADD @curr_date  DOUBLE

Здесь я пытался сделать начальную и конечную точки для цикла и использовать условие цикла, которое хранится в локальной переменной, в качестве заголовка моего столбца, поскольку это то, что мне нужно для заголовка столбца. Я также пытался использовать CAST, чтобы преобразовать его в char, но СУБД рада сообщить мне, что в этой последней строке (строке ADD) есть Incorrect syntax near '@curr_date', потому что ей не нравится, что я пытаюсь назвать столбец с помощью локальная переменная (я думаю). У меня нет образца вывода, но вывод должен быть таблицей с первым столбцом, определенным как CHAR и названным emp_name, потому что он будет содержать имена. Все остальные столбцы определены как тип DOUBLE и должны быть NULL, потому что они будут содержать определенное количество часов и должны иметь текущую дату в качестве заголовка @curr_date. Я думаю, что все столбцы, добавленные в таблицу с помощью метода ALTER, в любом случае по умолчанию имеют значение NULL. Я видел примеры динамического SQL, где вы объявляете переменную для хранения оператора select, но я действительно не понимаю, как они добавляют столбцы в таблицу. Я не уверен, что это можно сделать в операторе CREATE, но если это возможно, было бы здорово увидеть. Кроме того, это должно быть переменным в том факте, что я могу изменить @end_date, скажем, на... 2046 год.

Безопасность здесь не при чем


person Lacuna    schedule 06.07.2016    source источник
comment
Обычно это не то, что вы когда-либо делали, поскольку пользователи схемы обычно предпочитают фиксированные определения таблиц (а не динамические с переменным количеством столбцов в зависимости от диапазона дат). Однако вы можете создать строку sql (declare @sql varchar(2000)), заполнить ее оператором alter, а затем запустить ее, используя EXEC или sp_executesql.   -  person Igor    schedule 06.07.2016
comment
Что вы имеете в виду под заголовком? Это имя столбца? Вы НЕ хотите использовать даты в качестве имен столбцов. Мало того, что с ним больно работать, так это признак очень плохой конструкции. Кроме того, подумайте, сколько столбцов будет иметь столбец для каждого дня между сегодняшним днем ​​и 2046 годом. Вы превысите максимальное количество столбцов на несколько порядков.   -  person Sean Lange    schedule 06.07.2016
comment
пожалуйста, дайте нам пример использования, чтобы мы могли показать вам, как сделать лучший дизайн.   -  person Hogan    schedule 06.07.2016
comment
@Sean Lange Да, под заголовком столбца я имею в виду имя столбца. На самом деле мне не нужно, чтобы он переходил с настоящего момента на 2046 год, но я бы хотел, чтобы он проходил с начала одного года до конца того же года. Плюс мне нужно только 52 столбца для каждой таблицы. Я действительно не знаю ограничений SQL Server, так как я все еще очень новичок, но спасибо за комментарий, он заставил меня задуматься.   -  person Lacuna    schedule 06.07.2016
comment
Вам не нужны даты в качестве имен столбцов. Это указывает на наличие серьезных проблем с нормализацией. Поскольку вы указали 52, я предполагаю, что вам нужны данные за каждую неделю года? Обычно каждая неделя будет строкой в ​​таблице, а не другим столбцом.   -  person Sean Lange    schedule 06.07.2016
comment
Точно, мне нужны данные за каждую неделю года, и теперь я вижу, как я могу сделать лучшую таблицу, делая это по-вашему. Опять же, это моя первая таблица, и я не читал ни одной книги о проектировании баз данных. Но спасибо, что нашли время, чтобы оставить комментарий, так как это было действительно полезно.   -  person Lacuna    schedule 06.07.2016


Ответы (1)


Я согласен со всеми комментариями об использовании ROW без динамического добавления столбцов, вы всегда можете динамически поворачивать эти последние, и это будет более гибко. Так что, возможно, некоторые соображения по схеме, но просто чтобы ответить на ваш конкретный вопрос, вы были близки.....

DECLARE @start_date AS DATE
DECLARE @end_date AS DATE
DECLARE @curr_date AS DATE
DECLARE @column_name AS CHAR(10)

SET @start_date = '2016-01-02'
SET @end_date = '2016-12-31'
SET @curr_date = @start_date

WHILE @curr_date < @end_date
BEGIN
    DECLARE @SQL NVARCHAR(MAX)

    SET @curr_date = DATEADD(DD, 7, @curr_date)

    SET @SQL = 'ALTER TABLE TableB
        ADD [' + CAST(@curr_date AS VARCHAR(10)) + ']  FLOAT'

    --PRINT @SQL
    EXECUTE (@SQL)
END
person Matt    schedule 06.07.2016