2015-01-23 2 views
1

У меня есть таблица языка, имеющие колонны isactive, hindi, english, ....Вставка данные в динамической колонке задается пользователем

Я создаю хранимую процедуру для вставки новых данных, как это:

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

Получение проблемы в исполнении

+0

@lang является переменной, и я вещь, которая вызывает у вас проблему. Спокойной стороной может быть корпус Switch. Запишите запрос для каждого языка по-разному в CASE и примените переключатель на основе ввода от пользователя. –

+2

здесь вам не нужен динамический SQL. Просто создайте ветвь IF .. ELSE. указав разные имена столбцов для каждого языка. –

+0

@VishalGajjar: Серьезно? Если вам нужно поддерживать [более чем пару культур] (http://download1.parallels.com/SiteBuilder/Windows/docs/3.2/en_US/sitebulder-3.2-win-sdk-localization-pack-creation-guide/30801 .htm), у вас будет гигантское дерево 'IF .. ELSE'. Динамический SQL - это, безусловно, первый вариант, с которым я столкнулся в этой ситуации, если бы я не мог изменить дизайн БД. – Ellesedil

ответ

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)', @[email protected] 
end 

Sql Fiddle here. Обратите внимание на приведенные ниже комментарии в отношении проверки того, что имя столбца (@lang) является допустимым столбцом в таблице, чтобы предотвратить появление таких гадостей, как Sql Injection. Учитывая то, что должно быть конечное число имен столбцов, я хотел бы предложить проверки @lang против белого списка (т.е. проверка @lang против допустимо в списке значений)

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

Языка

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

В качестве альтернативы, вы может выбрать UNPIVOT языки, как колонны, и вместо того, чтобы нормализовать 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

+3

Привет @StuartLC Я бы также предложил QUOTENAME (@lang), или sp_ExcuteSQL обрабатывает инъекцию? –

+0

@VishalGajjar Вы правы - он будет обрабатывать только инъекции по параметризованным переменным, т. Е. '@ Data' безопасен, но @lang - нет. Поскольку число столбцов конечно, я должен проверять столбцы на белый список возможных столбцов, прежде чем делать это. – StuartLC

+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 
+0

«@lang» вызовет здесь, OP пытается передать имя столбца –

+0

@Vishal Gajjar: Я обновил результат. –

+0

'@ lang' восприимчив к инъекции. – Ellesedil

Смежные вопросы