在用户指定的动态列中插入数据

时间:2015-01-23 06:18:57

标签: sql sql-server

我的语言表包含isactive列,hindienglish,....

我正在创建一个用于插入新数据的存储过程:

create proc USP_Insertdata
   @lang varchar(20),
   @data nvarchar(50)
as
begin
   EXEC(N'insert into language(@lang, isactive) values(@data, 'true')') 
end

在exec中遇到问题

2 个答案:

答案 0 :(得分:3)

您需要动态绑定lang,因为无法对列名进行参数化,但是@data可以使用sp_executesql参数化:

create proc USP_Insertdata @lang varchar(20), @data nvarchar(50)
as 
begin
   declare @sql NVARCHAR(MAX) = N'insert into language(' + @lang + ',isactive) values(@data,''true'')';
   exec sp_executesql  @sql, N'@data nvarchar(50)', @data=@data
end

Sql Fiddle here。请注意以下关于验证列名(@lang)是否为表中有效列的注释,以防止像Sql Injection这样的恶意内容。鉴于必须有有限数量的列名称,我建议针对白名单验证@lang(即根据允许的值列表检查@lang

修改
诉诸动态Sql通常是一种嗅觉的标志。我不同意表设计,因为在使用上面的proc插入数据之后,这将导致稀疏数据类似于:

语言

English    French    Russian  IsAcive
Yes        NULL      NULL     true
NULL       Oui       NULL     true
NULL       NULL      Da       true

作为替代方案,您可以选择将语言取消为列,而是在首次创建可用语言的简单参考表后,将data插入标准化为语言:

LanguageType

ID(PK) Language
EN     English
FR     French
RU     Russian

在查找相应的语言代码后,原始Language表将标准化为:

LanguageData

LanguageId(FK) Data     IsActive
EN             Yes      1
FR             Oui      1
RU             Da       1

最后一点 - isactive似乎暗示了一个布尔值 - 将其建模为BIT or CHAR enumeration

更为常见

答案 1 :(得分:0)

使用此程序。

    create proc USP_Insertdata @lang varchar(20), @data nvarchar(50) as begin

EXEC(N'insert into language(' + @lang + ',isactive) values(' + @data + ',true)') end