#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
wheretiles_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)