2015-12-18 66 views
0

我正在使用Windows窗體C#和SQL。我有一個表由兩個列:如何將列值保存到SQL C#中的變量?

column1的=本身份識別碼(主鍵和唯一ID)

列2 =日期時間。

下面的代碼插入日期/時間到表:

private void button1_Click(object sender, EventArgs e) 
    { 

SqlConnection cn = new SqlConnection("Data Source=PCN-TOSH;Initial Catalog=mydb;Integrated Security=True"); 
     cn.Open(); 
     SqlCommand cm = new SqlCommand("Insert into TableDate_Time (DateTime) values (@DateTime)"); 


     cm.Parameters.Add("@DateTime", SqlDbType.DateTime); 
     cm.Parameters["@DateTime"].Value = DateTime.Now; 
     cm.Connection = cn; 
     cm.ExecuteNonQuery(); 

    // something like: var varID = the current myID value 

    } 

我的問題是:我如何保存身份識別碼列的最後一行值成每當我按一下按鈕變量?任何想法?謝謝

+1

是本身份識別碼一個'IDENTITY'柱或者是一個'uniqueidentifer'列? –

+0

@ Scott張伯倫。它是獨特的。 – naouf

+0

你應該在你的問題中明確說明這個問題,使用SCOPE_IDENTITY()的答案不適用於這個問題。 –

回答

4

在SQL Server(和其他數據庫系統),你可以在同一文本傳遞了兩個命令。現在,T-SQL允許您使用命令「SELECT SCOPE_IDENTITY()」獲取爲連接生成的最後一個IDENTITY值。

因此,你的代碼將

private void button1_Click(object sender, EventArgs e) 
{ 
    string cmdText = @"Insert into TableDate_Time 
         (DateTime) values (@DateTime); 
         SELECT SCOPE_IDENTITY()"); 
    using(SqlConnection cn = new SqlConnection("....")) 
    using(SqlCommand cm = new SqlCommand(cmdText, cn)) 
    { 
     cn.Open(); 
     cm.Parameters.Add("@DateTime", SqlDbType.DateTime); 
     cm.Parameters["@DateTime"].Value = DateTime.Now; 
     int id = Convert.ToInt32(cm.ExecuteScalar()); 
     .... 
    } 
} 

相反的ExecuteNonQuery,調用ExecuteScalar返回第一行的第一列在這裏執行(該SELECT)的最後一個命令。需要注意的是附上每一個一次性的物體,像在使用語句的連接和命令在例外的情況下,(一個不會忘記處置這些對象)

爲您的代碼正確退出路徑的好做法

編輯

如果你的ID列不是IDENTITY列,但一個uniqueidentifier有更多的問題。我想,你的表已經定義了使用T-SQL

的NEWID()函數在這種情況下,你需要查詢更改爲

private void button1_Click(object sender, EventArgs e) 
{ 
    string cmdText = @"Insert into TableDate_Time 
         (DateTime) OUTPUT INSERTED.myID values (@DateTime)"; 
    using(SqlConnection cn = new SqlConnection("....")) 
    using(SqlCommand cm = new SqlCommand(cmdText, cn)) 
    { 
     cn.Open(); 
     cm.Parameters.Add("@DateTime", SqlDbType.DateTime); 
     cm.Parameters["@DateTime"].Value = DateTime.Now; 
     Guid id = (Guid)cm.ExecuteScalar(); 
     .... 
    } 
} 
+0

@Steve你不能傳遞2個或更多的命令嗎? –

+0

有一點需要注意,我遇到過問題,觸發器可以用直接輸出的輸出語句大肆渲染查詢。如果有觸發機會,最好輸出到變量,然後在單獨的選擇中打印變量。 –

+0

是的,只需在ad hoc表上測試以查看ExecuteScalar是否也返回Guid。太晚了,斯坦利先生已經回覆了 – Steve

1

這很容易列ID的默認值。只需添加以下代碼:

而在你的存儲過程(或SQL查詢)地址:

DECLARE @ID int = (Select SCOPE_IDENTITY()) 

RETURN @ID 
+0

我不知道'ReturnValue'是否適用於文本查詢,你需要在其中有'cm.CommandType = CommandType.StoredProcedure'工作(我認爲)。 –

+0

ReturnValue參數是從T-SQL中的RETURN語句而不是從SELECT中分配的,順便說一下,此代碼不會返回最後的標識值,這裏的存儲過程在哪裏? – Steve

+0

你對存儲過程是正確的。哎呦!也許我應該刪除,但我現在暫緩,看看OP是否可以澄清。 –

2

假設新ID是通過列默認數據庫生成的,你可以使用在OUTPUT子句返回ID的新記錄:

private void button1_Click(object sender, EventArgs e) 
{ 

    SqlConnection cn = new SqlConnection("Data Source=PCN-TOSH;Initial Catalog=mydb;Integrated Security=True"); 
    cn.Open(); 
    SqlCommand cm = new SqlCommand("INSERT INTO TableDate_Time (DateTime) OUTPUT inserted.myID VALUES (@DateTime)"); 

    cm.Parameters.Add("@DateTime", SqlDbType.DateTime); 
    cm.Parameters["@DateTime"].Value = DateTime.Now; 
    cm.Connection = cn; 
    Guid newID = (Guid)cm.ExecuteScalar(); 
} 

一些其他的事情要考慮的是不是你有密切關係你的問題:

  • 不要把直接的SQL邏輯,一個按鈕單擊事件處理程序 - 用於數據管理一個單獨的類
  • 環繞你,讓他們及時關閉,即使命令和using塊連接有是一個例外。
+0

有一點需要注意,我遇到過問題,觸發器可以用直接打印出來的輸出語句大肆渲染查詢。如果有觸發機會,最好輸出到變量,然後在單獨的選擇中打印變量。 –

相關問題