SQL Server,如果条件满足,如何DROP COLUMN?

时间:2010-08-22 13:50:45

标签: sql-server conditional alter-table alter

我一直在谷歌搜索谷歌的答案,但没有运气。任何帮助都会很棒!

我有一个SQL表:tblFeedback。它存储反馈问题的答案。问题保存在另一个表中:tblQuestions。反馈表上的问题可以通过用户界面进行更改,因此当用户编辑替换它们的问题时,我会将问题重写为tblQuestions并在tblFeedback中提供答案列(每个问题一个)。希望这很容易理解。

所以在那一刻我有3个问题。我的tblFeedback列看起来像:
FeedbackID
名称
日期
Question_1
Question_2
Question_3

我想删除这些列,并在必要时用新的列替换它们。我正在沿着使用ALTER TABLE tblFeedback DROP COLUMN的路径......但我无法使用WHERE或其他任何内容添加任何条件。如果我可以指定类似'如果column_name以Question_%开头'或'if column_ID> 3'但如果我在COLUMN之后添加WHERE我会收到错误。

我正在使用c#为这个asp.net应用程序写这个。

对此有任何帮助真的很感激。我去散步冷静下来。

5 个答案:

答案 0 :(得分:6)

请重新考虑您的数据库设计。完全删除问题列并添加表

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

然后使用Question.Deleted == null作为您在表单上显示或隐藏问题的标准。

答案 1 :(得分:4)

IF COLUMNPROPERTY(OBJECT_ID('myTable'), 'ColumnID', 'Question_1') IS NOT NULL
    ALTER TABLE tblFeedback DROP COLUMN Question_1

但是,这会丢弃所有行:你不能有一些带有Answer的行,有些带有Question的例子。

如果我理解正确,我会实现作为子表,允许0到n的问题/答案/反馈与类型来定义问题/答案/反馈等。

答案 2 :(得分:3)

对于这种事情,您可能会更好地使用EAV(实体属性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
)

您可能还需要其他东西来将问题“分组”在一起。

它确实使报告更加复杂。

答案 3 :(得分:1)

如果您真的想在每次反馈表单更改时根据列名更改表结构,则需要使用动态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)

答案 4 :(得分:0)

为了以后找到这个问题的人的好处,这种事情可以作为有条件地对查询结果执行命令的基础(在这种情况下,检查列除了NULL之前只包含IF (SELECT COUNT([my column]) FROM [my table] WHERE [my column] IS NOT NULL) = 0 PRINT 'remove' ELSE PRINT 'keep'; 像删除列一样的动作):

{{1}}