好的,所以我试图改进我的asp数据输入页面,以确保进入我的数据表的条目是唯一的.
所以在这个表中我有SoftwareName和SoftwareType.我试图得到它,如果条目页面发送插入查询与参数匹配表中的什么(所以相同的标题和类型),然后一个错误被抛出并且没有输入数据.
这样的事情
INSERT INTO tblSoftwareTitles( SoftwareName,SoftwareSystemType) VALUES(@SoftwareName,@SoftwareType) WHERE NOT EXISTS (SELECT SoftwareName FROM tblSoftwareTitles WHERE Softwarename = @SoftwareName AND SoftwareType = @Softwaretype)
所以这个语法非常适合将列从一个表中选择到另一个表中,而不会输入重复项,但似乎不希望使用参数化的插入查询.有人可以帮我吗?
干杯丹
编辑:
private void ExecuteInsert(string name,string type) { //Creates a new connection using the HWM string using (sqlConnection HWM = new sqlConnection(GetConnectionStringHWM())) { //Creates a sql string with parameters string sql = " INSERT INTO tblSoftwareTitles( " + " SoftwareName," + " SoftwareSystemType) " + " SELECT " + " @SoftwareName," + " @SoftwareType " + " WHERE NOT EXISTS " + " ( SELECT 1 " + " FROM tblSoftwareTitles " + " WHERE Softwarename = @SoftwareName " + " AND SoftwareSystemType = @Softwaretype); "; //Opens the connection HWM.Open(); try { //Creates a sql command using (sqlCommand addSoftware = new sqlCommand{ CommandType = CommandType.Text,Connection = HWM,CommandTimeout = 300,CommandText = sql}) { //adds parameters to the sql command addSoftware.Parameters.Add("@SoftwareName",sqlDbType.NVarChar,200).Value = name; addSoftware.Parameters.Add("@SoftwareType",sqlDbType.Int).Value = type; //Executes the sql addSoftware.ExecuteNonQuery(); } Alert.Show("Software title saved!"); } catch (System.Data.sqlClient.sqlException ex) { string msg = "Insert Error:"; msg += ex.Message; throw new Exception(msg); } } }
解决方法
我会这样做和IF语句:
IF NOT EXISTS ( SELECT 1 FROM tblSoftwareTitles WHERE Softwarename = @SoftwareName AND SoftwareSystemType = @Softwaretype ) BEGIN INSERT tblSoftwareTitles (SoftwareName,SoftwareSystemType) VALUES (@SoftwareName,@SoftwareType) END;
您可以在不使用SELECT的情况下执行此操作
INSERT tblSoftwareTitles (SoftwareName,SoftwareSystemType) SELECT @SoftwareName,@SoftwareType WHERE NOT EXISTS ( SELECT 1 FROM tblSoftwareTitles WHERE Softwarename = @SoftwareName AND SoftwareSystemType = @Softwaretype );
这两种方法都易于使用race condition,所以当我仍然使用上述方法之一插入时,但是您可以使用唯一的约束来保护重复的插入:
CREATE UNIQUE NONCLUSTERED INDEX UQ_tblSoftwareTitles_Softwarename_SoftwareSystemType ON tblSoftwareTitles (SoftwareName,SoftwareSystemType);
附录
在sql Server 2008或更高版本中,您可以使用MERGE与HOLDLOCK来消除竞争条件的机会(这仍然不能替代唯一约束).
MERGE tblSoftwareTitles WITH (HOLDLOCK) AS t USING (VALUES (@SoftwareName,@SoftwareType)) AS s (SoftwareName,SoftwareSystemType) ON s.Softwarename = t.SoftwareName AND s.SoftwareSystemType = t.SoftwareSystemType WHEN NOT MATCHED BY TARGET THEN INSERT (SoftwareName,SoftwareSystemType) VALUES (s.SoftwareName,s.SoftwareSystemType);