2013-08-22 2 views
1

Например, я хочу INSERT данные в базе данных, а также UPDATE другой стол. Мой код такой:Как создать две команды в одном соединении?

SqlConnection con = new SqlConnection("**"); 
con.Open(); 
SqlCommand cmd = con.CreateCommand(); 
cmd.CommandText = "INSERT Borrowbook VALUES (@StudentID, @ISBN, @Title, @Date)"; 
SqlParameter p1 = new SqlParameter("@StudentID", SqlDbType.NChar); 
p1.Value = textBox2.Text; 
cmd.Parameters.Add(p1); 
SqlParameter p2 = new SqlParameter("@ISBN", SqlDbType.NVarChar); 
p2.Value = textBox4.Text; 
cmd.Parameters.Add(p2); 
SqlParameter p3 = new SqlParameter("@Title", SqlDbType.VarChar); 
p3.Value = textBox3.Text; 
cmd.Parameters.Add(p3); 
SqlParameter p4 = new SqlParameter("@Date", SqlDbType.DateTime); 
p4.Value = dateTimePicker1.Text; 
cmd.Parameters.Add(p4);  
cmd.ExecuteNonQuery(); 
con.Close(); 
MessageBox.Show("The books has been successfully borrowed!", 
    "Information ... ", 
    MessageBoxButtons.OK, 
    MessageBoxIcon.Information, 
    MessageBoxDefaultButton.Button1); 
+1

Почему вы не хотите делать это в двух отдельных командах? – FelProNet

+0

Я не совсем понимаю, в чем проблема. Чтобы создать две команды, вы можете просто вызвать 'con.CreateCommand()' дважды. –

+0

'new SqlCommand (« query », con);' –

ответ

4

Прежде всего, вы действительно должны использовать с помощью инструкций поэтому ваши соединения закрываются в случае исключения

using(SqlConnection con = new SqlConnection("**********************************************")) 
using(SqlCommand cmd = con.CreateCommand()) //The create command can happen before the open 
{ 
    con.Open(); 
    cmd.CommandText = "INSERT INTO Borrowbook ([Student ID], ISBN, Title, Date) VALUES ( @StudentID, @ISBN , @Title, @Date)"; 
    //(Snip adding parameters) 
    cmd.ExecuteNonQuery(); 
    //You don't need to call close if you are using "using" 
} 

Это из трех способов сделать это.

Вы можете поместить обе команды в один командный оператор.

using(SqlConnection con = new SqlConnection("**********************************************")) 
using(SqlCommand cmd = con.CreateCommand()) 
{ 
    con.Open(); 
    cmd.CommandText = @"INSERT INTO Borrowbook ([Student ID], ISBN, Title, Date) VALUES ( @StudentID, @ISBN , @Title, @Date); 
         INSERT INTO StudentActvitiy ([Student ID], Date) VALUES ( @StudentID, GETDATE())"; 
    //(Snip adding parameters) 
    cmd.ExecuteNonQuery(); 
} 

или вы могли бы изменить текст команды и запустить его снова

using(SqlConnection con = new SqlConnection("**********************************************")) 
using(SqlCommand cmd = con.CreateCommand()) 
{ 
    con.Open(); 
    cmd.CommandText = "INSERT INTO Borrowbook ([Student ID], ISBN, Title, Date) VALUES ( @StudentID, @ISBN , @Title, @Date)"; 
    //(Snip adding parameters) 
    cmd.ExecuteNonQuery(); 

    cmd.CommandText = "INSERT INTO StudentActvitiy ([Student ID], Date) VALUES ( @StudentID, GETDATE())" 
    cmd.ExecuteNonQuery(); 
} 

или вы могли бы сделать две команды

using(SqlConnection con = new SqlConnection("**********************************************")) 
using(SqlCommand cmd = con.CreateCommand()) 
using(SqlCommand cmd2 = con.CreateCommand()) 
{ 
    con.Open(); 
    cmd.CommandText = "INSERT INTO Borrowbook ([Student ID], ISBN, Title, Date) VALUES ( @StudentID, @ISBN , @Title, @Date)"; 
    //(Snip adding parameters) 
    cmd.ExecuteNonQuery(); 

    cmd2.CommandText = "INSERT INTO StudentActvitiy ([Student ID], Date) VALUES ( @StudentID, GETDATE())" 
    SqlParameter p21 = new SqlParameter("@StudentID", SqlDbType.NChar); 
    p21.Value = textBox2.Text; 
    cmd2.Parameters.Add(p21); 
    cmd2.ExecuteNonQuery(); 
} 

Для Tim's solution это вид комбинации из первых и 3-й.

using(SqlConnection con = new SqlConnection("**********************************************")) 
using(SqlCommand cmd = con.CreateCommand()) 
using(SqlCommand cmd2 = con.CreateCommand()) 
{ 
    con.Open(); 
    cmd.CommandText = @"INSERT INTO Borrowbook ([Student ID], ISBN, Title, Date) VALUES ( @StudentID, @ISBN , @Title, @Date); 
         SELECT CAST(SCOPE_IDENTITY AS INT);"; 
    //(Snip adding parameters) 
    var resultId = (int)cmd.ExecuteScalar(); 

    cmd2.CommandText = "INSERT INTO StudentActvitiy ([Student ID], Date, BorrowBookId) VALUES ( @StudentID, GETDATE(), @borrowBookId)" 
    SqlParameter p21 = new SqlParameter("@StudentID", SqlDbType.NChar); 
    p21.Value = textBox2.Text; 
    cmd2.Parameters.Add(p21); 

    SqlParameter p22 = new SqlParameter("@borrowBookId", SqlDbType.Int); 
    p22.Value = resultId; 
    cmd2.Parameters.Add(p22); 
    cmd2.ExecuteNonQuery(); 
} 
+0

+1 для использования заявления и приятных примеров. – Khan

+0

Использование оператора = немедленное +1 –

+0

Не было бы лучше избавиться от 'cmd' и' cmd2' сразу же после того, как они не понадобятся? В этом случае вы можете даже сохранить одно и то же имя (т. Е. 'Cmd'). – Neolisk

1

Вы можете. Не закрывайте соединение, прежде чем выполнять вторую команду.

Пример Шаги:

  1. Создать новое соединение
  2. Open Connection
  3. Создать команду 1
  4. Добавить PARAMS в Команда 1
  5. Execute Command 1
  6. команду Создать 2
  7. Добавить Титулы в Команда 2
  8. Execute Command 2
  9. Закрыть Connection
  10. Dispose товары
1

можно сделать следующим образом

 SqlConnection cn = new SqlConnection("********"); 
     string stmt = "insert projects(projectname) values('" + name + "')"; 
     string stmt1="update dept set deptid="+id; 

     SqlCommand cmd = new SqlCommand(stmt, cn); 
     sqlcommand cmd1=new sqlcommand(stmt1,cn);   

     cn.Open(); 
     cmd.ExecuteNonQuery(); 

     cmd1.ExecuteNonQuery(); 
     cn.close() 
+0

благодарю вас за ответы :) –

0

Когда я вижу такие вопросы, я почти всегда спрашиваю: «Почему вы не используете хранимую процедуру для этого?» Вы можете избежать дополнительных круглых поездок на сервер базы данных. Легче инкапсулировать транзакционную логику, и это отличное место для обеспечения использования бизнес-логики на основе данных.

Технические ответы хороши, но вы по-прежнему «делаете это неправильно», если вы не застряли в среде с несколькими базами данных, но в этом случае вы, вероятно, ошибаетесь, если не пишете уровень данных для обработки различий базы данных для вас.

Я также хотел бы добавить, что если вы используете хранимую процедуру proc и multiple, вам следует ссылаться на таблицы и т. Д. С квалифицированным именем dbo.tablename вместо tablename.Это оптимизирует производительность, избегая ненужных проверок безопасности в proc, но имеет решающее значение для формирования при использовании созданного клиентом динамического sql, потому что он покидает dbo. не позволяет серверу sql повторно использовать скомпилированный sql и очень быстро заполняет скомпилированный sql-кеш, если он вызывается часто.

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