2011-12-03 220 views
2

我創建SQL Server Management Studio中的表使用此代碼:C#:SQL Server查詢問題

CREATE TABLE contact(
ID INT IDENTITY NOT NULL, 
FIRSTNAME VARCHAR(100), 
LASTNAME VARCHAR(100) 
) 

,並在C#中我用這個代碼:

SqlConnection sc = new SqlConnection("Data Source=.\\SQLSERVER; Initial Catalog=BOSS; Integrated Security=TRUE"); 

SqlDataAdapter sd = new SqlDataAdapter(); 

sd.InsertCommand = new SqlCommand("INSERT INTO contact VALUES(@ID, @FIRSTNAME, @LASTNAME)"); 

sd.InsertCommand.Parameters.Add("@ID", SqlDbType.Int).Value = textBox1.Text; 
sd.InsertCommand.Parameters.Add("@FIRSTNAME", SqlDbType.VarChar).Value = textBox2.Text; 
sd.InsertCommand.Parameters.Add("@LASTNAME", SqlDbType.VarChar).Value = textBox3.Text; 

sc.Open(); 

sd.InsertCommand.ExecuteNonQuery(); 

sc.Close(); 

,但是當我添加值到數據庫中,我得到的錯誤:

"ExecuteNonQuery: Connection property has not been initialized"

,我加入sc給我的第一insertcommand固定它,但是當我運行程序我得到另一個錯誤:

An explicit value for the identity column in table 'contact' can only be specified when a column list is used and IDENTITY_INSERT is ON.

+4

您應該將連接創建封裝在'using'語句中。 – Oded

+0

您沒有將DataAdapter連接到連接 –

+0

爲什麼直接使用'DataAdapter'而不是'Command'? – Oded

回答

4

這樣來做:

using(SqlConnection sc = new SqlConnection("Data Source=.\\SQLSERVER; Initial Catalog=BOSS; Integrated Security=TRUE")) 
{ 

    using(SqlCommand command = new SqlCommand()) 
    { 
    command.CommandText = "INSERT INTO contact (FirstName, LastName) VALUES(@FIRSTNAME , @LASTNAME"); 
    command.CommandType = CommandType.Text; 
    command.Connection = sc; 

    command.Parameters.AddWithValue("@FIRSTNAME", textBox2.Text); 
    command.Parameters.AddWithValue("@LASTNAME", textBox3.Text); 

    sc.Open(); 

    command.ExecuteNonQuery(); 

    } 

} 

重要注意事項:

1)設置你的表最多有標識列作爲一個標識列,並設置自動增量爲真。當您插入時,這將自動生成數字ID

2)您試圖插入標識列 - 除非啓用標識插入,否則實際上無法執行此操作。我不會打擾 - 只需使用自動增量列並讓數據庫控制id生成步驟。

您可以生成你的表是這樣的:

CREATE TABLE Contact 
(
Id int PRIMARY KEY IDENTITY, 
FirstName varchar(100), 
LastName varchar(100) 
) 

得到一個自動增量的主鍵。

3)你不需要SqlDataAdapter。

+1

我通常避免使用'SqlParameter.AddWithValue(..)'調用 - ADO.NET需要猜測傳入的數據的類型,並在大多數情況下都正確 - 但它可能會出錯。我喜歡**明確**定義類型,以便我沒有討厭的驚喜..... –

+0

嗨marc_s,我從來沒有出錯,但那是因爲我通常只是懶惰,沒有定義整個參數,但是傳遞正確的類型 - 我知道該列是一個int,該列是一個字符串等等等等。它還使得使用KeyValuePair style方法編寫通用運行存儲過程變得很容易。公平的評論,特別是當用戶直接從用戶輸入驅動的字段調用存儲過程:-) – dash

+0

...或者 - 如果 - 無論出於何種原因 - 傳入的值是空值 - 哪種數據類型應該ADO。 NET *猜測*爲? –

3

您需要將您要使用到的SqlCommand

InsertCommand = new SqlCommand("INSERT INTO contact VALUES(@ID , @FIRSTNAME , @LASTNAME)", sc); 

您需要配置您的連接和命令,以及連接。這樣做的標準模式是:

using (SqlConnection conn = new SqlConnection("Data Source=.\\SQLSERVER; Initial Catalog=BOSS; Integrated Security=TRUE")){ 
    conn.Open(); 
    using (SqlCommand command = new SqlCommand(sqlString, conn)){ 
    //stuff... 
    command.ExecuteNonQuery(); 
    } 
} 
+0

噢是的,我不知道我是怎麼忘記它的,非常感謝 –

+0

關注評論downvote?我看不出有什麼問題嗎? –

2

SqlConnectionSqlDataAdapter沒有關係。其實你不需要SqlDataAdapter。您只需要SqlConnectionSqlCommand,您必須使用接受連接的構造函數重載。

1

你需要sd.InsertCommand = new SqlCommand("INSERT INTO contact VALUES(@ID , @FIRSTNAME , @LASTNAME)", sc);

2

由於IDINT IDENTITY字段,因此您不應(也不能)向其中插入值。但是,如果使用「通用」INSERT語句而沒有明確指定要插入值的列,則INSERT語句將嘗試將數據插入所有列 - 包括ID,您無法插入任何內容。

解決方案(我推薦使用總是)是明確定義其列值插入:

INSERT INTO dbo.contact(FirstName, LastName) VALUES(@FIRSTNAME, @LASTNAME) 

,如果你需要改變你的表並添加另一列這也適用 - 你原來的陳述將失敗,因爲表格現在突然有四列,但你的陳述只會提供三個值。如果您明確定義了要爲其提供值的列,那麼您的語句更健壯並且效果更好。

所以你完整的代碼應該是這樣的:

using(SqlConnection sc = new SqlConnection("Data Source=.\\SQLSERVER; Initial Catalog=BOSS; Integrated Security=TRUE")) 
using(SqlCommand cmdInsert = new SqlCommand("INSERT INTO dbo.Contact(FirstName, LastName) VALUES(@FIRSTNAME, @LASTNAME)", sc)) 
{ 
    cmdInsert.Parameters.Add("@FIRSTNAME", SqlDbType.VarChar, 100).Value = textBox2.Text; 
    cmdInsert.Parameters.Add("@LASTNAME", SqlDbType.VarChar, 100).Value = textBox3.Text; 

    sc.Open(); 
    cmdInsert.ExecuteNonQuery(); 
    sc.Close(); 
} 
1

你可以做任何方式:

一個。設置你的連接對象適配器的連接的InsertCommand:

sd.InsertCommand.Connection = sc; 

或者

灣在初始化插入命令時傳遞連接對象,如下所示:

sd.InsertCommand = 
new SqlCommand("INSERT INTO contact VALUES(@ID, @FIRSTNAME, @LASTNAME)", sc);