2011-11-30 60 views
1

我正在寻找一种解决方案,使用3个参数在表中插入一些数据,第一个是表名,第二个是具有名称和值的类的List属性。 我有一个部分解决方案(下面),但我不认为这是建议,所以,我寻找一个最佳做法来做到这一点。SQL中无字段名称的动态插入

如果可能的话,我想建议使用参数来创建,以避免注入。

private void InsertMetada(string deviceType, List<DeviceFields> deviceFields) 
{ 
DataBaseConnection database = new DataBaseConnection(); 
database.Open(); 
StringBuilder strb = new StringBuilder(); 
stb.Append(string.Format("INSERT INTO DEVICE_{0} (", deviceType.ToString().ToUpper())); 
foreach (var item in deviceFields) 
{ 
    strb.Append(string.Format(" {0}, ",item.name.ToString()));    
} 
stb.Append(") VALUES ("); 
foreach (var item in deviceFields) 
{ 
    strb.Append(string.Format(" '{0}', ", item.value.ToString())); 
} 
strb.Append(")"); 
database.executeQuery(strb.ToString()); 
database.Close(); 
} 

编辑:我不认为我是在我的问题很清楚。 在这种情况下,DeviceFields.item.name与表字段的名称相同。

我在寻找的是保证创建不同的设备属性,为不同的表在不同的设备类型。也许我的观点不是正确的,但我想如果我有分开的表格,我可以执行快速搜索。 在这个例子中我的表(DEVICE_KEYBOARD)看起来是这样的:

> FIELD NAME | TYPE 
-------------|--------- 
language  | varchar 
key   | varchar 
isMultimedia | varchar 
deviceID  | varchar 

和列表看起来像

> DeviceFields[0]: 
name = language 
value = en-us 

> DeviceField[1]: 
name = key 
value = 102 

> DeviceField[2]: 
name = isMultimedia 
value = Yes 

> DeviceField[3]: 
name = deviceID 
value = 0000-0000-00000-00000 

,第二个表,例如是这样的:

TABLE DEVICE_SPEAKER 

> FIELD NAME | TYPE 
--------------|--------- 
rms   | varchar 
remoteControl | varchar 
subwoofer  | varchar 
deviceID  | varchar 

它具有第一个表中的所有设备字段,但是这个属性是针对每种设备的特定的...
这个想法是让op有机会创建一个新的属性创造一个新的列,当用户点击添加按钮,在此表中,前缀“DEVICE_ {DEVICE TYPE}”

我可以列出所有字段,当我准备列表时,我的问题是要知道是否有最好的选择来创建这个东西,什么可能是安全和快速的。

+0

想知道:您是否有权更改数据库设计(例如,将设备类型存储在字段中)?从我的观点来看,你所尝试的看起来很难。用手消毒输入可能是一种方法,但我几乎不认为这是建议的做法。 –

回答

1

我同意创建一个存储过程。如果你需要你的INSERT语句是动态的,这可以在sproc中完成。

http://www.codeproject.com/KB/database/Building_Dynamic_SQL.aspx

就个人而言,我最讨厌的动态SQL存储过程中,有些人会说这是不好的做法,但有时它是根据您的情况最好的选择。我只是把它扔在那里作为一个选项。

+0

在存储过程中使用动态SQL时,SQL注入问题尚未解决,是吗?或者SQL服务器做一些输入消毒?但是,一般来说,我也倾向于构建一个sproc,因此+1。 –

+1

SQL注入仍然是一种风险,但如果程序是仔细编写脚本的,可以进行管理。例如,如果期待数字输入,请使用INT数据类型而不是VARCHAR或其他字符串类型。对于基于文本的数据类型输入,值应该被转义。不言而喻的是,需要在数据库中设置适当的权限,以便网站正在使用的登录权限只能执行其所需的功能,而没有其他功能。以下是关于该主题的一些很好的信息:http://www.sommarskog.se/dynamic_sql.html#SQL_injection。因此,为什么我讨厌动态SQL :) – JOpuckman

1

我的建议是创建一个存储过程,参数名称将匹配每个deviceField的名称。缺点是存储的proc参数必须匹配(不区分大小写)您的字段名称。

0

作为一种改进。我想建立参数化查询的形式

Insert into {TableName} ({ColumnName1,ColumnName2..ColumnNameN}) 
Values(@ColumnName1,@ColumnName2.. @ColumnNameN) 

不知道同质你的数据是,如果你能做到以上每一次表,然后将参数添加到命令对象,然后通过列表迭代,并设置价值的参数。

没有辉煌但更好。我已经使用了上述技术,即使在表格基本上是一个属性包的传统东西中也没有列名。

+0

如果您发布代码,XML或数据样本,请**在文本编辑器中突出显示这些行,然后单击编辑器上的“代码示例”按钮(“{}”)工具栏以很好的格式和语法突出显示它! –