SQL Server, как DROP COLUMN, если условие выполнено? - PullRequest
2 голосов
/ 22 августа 2010

Я тралял гугл за ответы на этот вопрос, но не повезло. Любая помощь будет отличной!

У меня есть таблица SQL: tblFeedback. Здесь хранятся ответы на вопросы обратной связи. Вопросы хранятся в другой таблице: tblQuestions. Вопросы в форме обратной связи можно изменить через пользовательский интерфейс, поэтому, когда пользователь редактирует вопросы или заменяет их, я переписываю вопросы в tblQuestions и предоставляю столбцы ответов в tblFeedback (по одному на каждый вопрос). Надеюсь, это достаточно легко понять.

Итак, у меня есть 3 вопроса. Мои столбцы tblFeedback выглядят так:
FeedbackID
Имя
Дата
Question_1
Question_2
Вопрос_3

Я хочу удалить эти столбцы и при необходимости заменить их новыми. Я иду по пути использования ALTER TABLE tblFeedback DROP COLUMN ... но я не могу добавить какие-либо критерии, используя WHERE или что-то еще .. Если бы я мог указать что-то вроде 'if column_name начинается с Question_%' или 'if column_ID> 3 'но если я добавлю ГДЕ после КОЛОННЫ, я получаю ошибки.

Я пишу это для приложения asp.net, используя c #.

Любая помощь в этом была бы очень признательна. Я иду на прогулку, чтобы успокоиться.

Ответы [ 5 ]

6 голосов
/ 22 августа 2010

Пожалуйста, пересмотрите ваш дизайн БД. Полностью удалите столбцы вопросов и добавьте таблицы

Question (QuestionID int identity, Deleted datetime, Text text)  
Answer (FeedbackID int FK to Feedback, QuestionID int FK to Question, Text text)

затем используйте Question.Deleted == null в качестве критерия для отображения или скрытия вопросов в форме.

4 голосов
/ 22 августа 2010
IF COLUMNPROPERTY(OBJECT_ID('myTable'), 'ColumnID', 'Question_1') IS NOT NULL
    ALTER TABLE tblFeedback DROP COLUMN Question_1

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

Если я вас правильно понимаю, я бы реализовал как дочернюю таблицуразрешить от 0 до n вопросов / ответов / отзывов с типом для определения вопросов / ответов / отзывов и т. д.

3 голосов
/ 22 августа 2010

Возможно, вам лучше использовать структуру базы данных в стиле EAV (entity attribute vaue) для таких вещей.

create table Question
(
    Id bigint not null primary key identity(1,1),
    Question nvarchar(max) not null
)

create table Feedback
(
    Id bigint not null primary key identity(1,1),
    Date datetime not null,
    Name nvarchar(512) not null,    
)

create table FeedbackAnswers
(
    Id bigint not null primary key identity(1,1),   
    FeedbackId bigint not null,
    QuestionId bigint not null,
    Answer nvarchar(max) not null
)

Возможно, вам понадобится что-то еще, чтобы "сгруппировать" вопросы вместе.

Это делает отчетность немного более сложной, хотя.

1 голос
/ 22 августа 2010

Вам потребуется использовать динамический SQL для этого и запросить sys.columns, если вы действительно хотите изменять структуру таблицы на основе имени столбца каждый раз, когда изменяется форма обратной связи. Это кажется необычным требованием, поскольку оно удаляет исторические данные, которые вы, по-видимому, по какой-то причине сохраняете в первую очередь

но если вы просто хотите автоматизировать то, что в противном случае вам нужно было бы сделать вручную ...

Пример синтаксиса

DECLARE @dynsql NVARCHAR(4000)

SELECT @dynsql = ISNULL(@dynsql + ',','') + QUOTENAME(name)
 FROM sys.columns WHERE name LIKE 'Question%'
 AND OBJECT_ID=OBJECT_ID('dbo.tblFeedback')

IF(@@ROWCOUNT > 0)
EXEC ('ALTER TABLE dbo.tblFeedback DROP COLUMN ' + @dynsql)
0 голосов
/ 21 июля 2014

В интересах тех, кто найдет этот вопрос позже, такие вещи возможны как основание для условного выполнения команды по результатам запроса (в этом случае проверка столбца не содержит ничего, кроме NULL перед выполнением действия как падение столбца):

IF (SELECT COUNT([my column]) FROM [my table] WHERE [my column] IS NOT NULL) = 0
  PRINT 'remove' ELSE PRINT 'keep';
...