Как: автоматическое присвоение имени столбцу при построении таблицы

#sql-server #tsql

#sql-сервер #tsql

Вопрос:

Я видел некоторые ответы, которые казались близкими к моему решению, но они использовали код, и я бы предпочел сделать это в SQL, если смогу. Я примерно знаю, что нужно, но я никогда не видел, чтобы кто-то делал это раньше в SQL. Я создаю таблицу, но я не хочу настраивать имя каждого столбца вручную. Структура будет чем-то похожа на эту:

 ID - BIGINT - Primary Key - Seed Increment 1 start at 1
Email - NVARCHAR(500) do not allow null
Board_Name - NVARCHAR(100) - Do not allow null 
Tile_1 - BIT - Do Not Allow Null
Tile_2 - BIT - Do Not Allow Null
Tile_3 - BIT - Do Not Allow Null
Tile_4 - BIT - Do Not Allow Null
Tile_5 - BIT - Do Not Allow Null
Tile_6 - BIT - Do Not Allow Null
Tile_7 - BIT - Do Not Allow Null
Tile_8 - BIT - Do Not Allow Null
Tile_9 - BIT - Do Not Allow Null
Tile_10 - BIT - Do Not Allow Null
 

В таблице «Tile_X» мне нужно проделать это 348 раз. Так что, очевидно, я не хочу повторять это 348 раз.

  DECLARE @X INT

 SET @X = 1

 WHILE (@X <=348)
 BEGIN
     PRINT @X
     SET @X = @X   1

     ALTER TABLE [dbo].[Game_Board]
     ADD 'Tile_'   @X BIT NOT NULL;
 END
 GO
 

Выдает ошибку:

Сообщение 102, уровень 15, состояние 1, строка 11
Неправильный синтаксис рядом с ‘Tile_’.

Обновление: я уже создал таблицу, но еще не добавил столбцы плитки. Поэтому мне нужно выяснить, как исправить этот цикл, чтобы заставить его добавлять их.

Обновление: Также пробовал это:

 DECLARE @X INT
DECLARE @Column NVARCHAR(100)

SET @X = 1
SET @Column = 'Tile_'   @X

WHILE (@X <=348)
BEGIN
    PRINT @X    

    ALTER TABLE [dbo].[Game_Board]
    ADD @Column BIT NOT NULL;

    SET @X = @X   1
    SET @Column = 'Tile_'   @X
END
GO
 

Получить ошибку:

Сообщение 102, уровень 15, состояние 1, строка 12
Неправильный синтаксис рядом с «@Column».

Комментарии:

1. Вероятно, вам скорее нужна отдельная таблица для перечисления плиток и внешнего ключа к плате.

2. И вы должны пометить СУБД, которую вы используете, поскольку процедурный синтаксис и возможности между ними сильно различаются.

3. Google для первой нормальной формы.

4. «Таблица сильно изменится»!!! Остановитесь прямо здесь. Ваша схема не должна меняться вообще. Это основной антипаттерн, и он направит вас в сторону серьезной боли (которую вы уже испытываете!). Рассмотрим вторую таблицу, вызываемую tiles со столбцом: id | tile_number | value . Тогда вы можете расти в строках, а не в новых столбцах. Затем в вашей исходной таблице выше у вас есть id | email | board_name | tiles_id where tiles_id соответствует вашему tiles.id в вашей новой второй таблице. Помните… В базе данных мы масштабируем строки, а не таблицы или столбцы. Установите схему один раз.

5. Содержимое базы данных «сильно меняется», но структура базы данных должна меняться редко. Подумайте: в вашем проекте вам нужно изменить структуру базы данных только для добавления плитки. Вы действительно хотите создать tiles таблицу, как описано @JNevill.

Ответ №1:

Вы должны использовать динамический T-SQL, как показано в приведенном ниже коде

 DECLARE @X INT;
DECLARE @Column NVARCHAR(100);
SET @X = 1;
SET @Column = 'Tile_'   CAST(@X AS NVARCHAR(3));
DECLARE @tsql AS NVARCHAR(MAX)= '';
WHILE(@X <= 348)
    BEGIN
        SET @tsql = @tsql   ' ALTER TABLE [dbo].[Game_Board] '
        SET @tsql = @tsql   ' ADD '   @Column   ' BIT NOT NULL;';
        SET @X = @X   1;
        SET @Column = 'Tile_'   CAST(@X AS NVARCHAR(3));
    END;
--PRINT @tsql
EXEC sys.sp_executesql 
    @tsql;
GO
 

См. Также sp_executesql (Transact-SQL)