使用sql查询将值插入sql数据库

问题描述 投票:2回答:4

这是我创建轨道的第一行(此工作)

String TrackAdd = "INSERT INTO Track (Titel) VALUES (@Titel)";

using (SqlCommand sqlCmd = new SqlCommand(TrackAdd, connection))
{

    sqlCmd.Parameters.AddWithValue("@Titel", textBoxTitel.Text);
    sqlCmd.ExecuteNonQuery();
}

然后我想使用刚为这个Track创建的ID,我需要它,所以我可以将它链接到其他东西(在这种情况下是一个类型。我已经在不同的表中指定了类型的名称,需要他们的ID)我我现在正在尝试这个,但它不起作用,我真的不知道该怎么做。

using (var connection = Database.connection)
{
    String Track1Genre = "INSERT INTO TrackGenre (TrackId, GenreId) VALUES (@TrackId, @GenreId)";
    string Genre = listBoxGenre.GetItemText(listBoxGenre.SelectedItem);
    using (SqlCommand sqlCmd = new SqlCommand(Track1Genre, connection))
    {

        sqlCmd.Parameters.AddWithValue("@TrackId", "Select Id from Track WHERE Titel = textBoxTitel.Text");
        sqlCmd.Parameters.AddWithValue("@GenreId", "Select Id from Genre where Genre = Genre");
        sqlCmd.ExecuteNonQuery();
    }
}

注意:连接没有任何问题,我只需要帮助如何从数据库中取出ID并将它们插入到不同的表中

c# sql
4个回答
2
投票

两种方法:

输出Inserted.Id

INSERT INTO Track (Titel) VALUES output INSERTED.ID (@Titel)

在C#中,使用:

int lastId =(int)cmd.ExecuteScalar();

Identity_Insert On

SET IDENTITY_INSERT dbo.Track ON; 
INSERT INTO Track (Id, Titel) VALUES (1, @Titel)
SET IDENTITY_INSERT dbo.Track OFF; 

在此方法中,您已经知道要插入的Id,因此您可以使用它来更新TrackGenre表。但是,是的,你必须跟踪你的ID或者可能在使用select max(id) from Track执行检查最后一个id之前


-1
投票

你应该通过传递@Titel参数在下面的存储过程中写下这个。 只需复制并粘贴它,而不是所有代码。

USE [DataBaseName]
GO
/****** Object:  StoredProcedure [dbo].[CoCAddTypes]    Script Date: 12/21/2017 6:03:31 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[ADDTrack]
      @Titel nvarchar(Max)
AS
BEGIN
     DECLARE @TrackId int;
     DECLARE @GenreId int;
     INSERT INTO Track Values (@Titel);
       Set @TrackId =SCOPE_IDENTITY();
       Set @GenreId = (Select Id from Genre where Genre = Genre);             
     INSERT INTO TrackGenre (TrackId, GenreId) VALUES ( @TrackId,@GenreId)
END 

使用ADO.NET调用存储过程

using (SqlConnection con = new SqlConnection(dc.Con)) {
    using (SqlCommand cmd = new SqlCommand("ADDTrack", con)) {
      cmd.CommandType = CommandType.StoredProcedure;    
      cmd.Parameters.Add("@Titel", SqlDbType.VarChar).Value = textBoxTitel.Text;    
      con.Open();
      cmd.ExecuteNonQuery();
    }
  }

注意:我不知道你提到的Genre。如果它是值并且需要传递到存储过程,那么您需要再添加一个参数来处理它。


-1
投票

你很亲密您无法按照预期的方式注入SQL。您必须移动insert语句,以便查询根据您的参数对每个值执行选择。

让我们尝试研究一下,当你开始执行时,执行的SQL查询会是什么样子:

String Track1Genre = "INSERT INTO TrackGenre (TrackId, GenreId) VALUES (@TrackId, @GenreId)";
sqlCmd.Parameters.AddWithValue("@TrackId", "Select Id from Track WHERE Titel = textBoxTitel.Text");
sqlCmd.Parameters.AddWithValue("@GenreId", "Select Id from Genre where Genre = Genre");

请记住,将使用在参数上设置的任何(字符串)值,而不进行任何评估。所以上面的语句将导致这个sql被执行:

INSERT INTO TrackGenre (TrackId, GenreId) 
VALUES ('Select Id from Track WHERE Titel = textBoxTitel.Text', 
        'Select Id from Genre where Genre = Genre');

所以很好地防止了SqlInjection attack,但它没有将Id返回到表Track和Genre,事实上它会咆哮转换失败到数据类型int。

相反,您可以按原样传递选择参数,然后在查询中使用这些参数来获取您感兴趣的行的ID。

保持尽可能接近您目前拥有的,这将工作:

using (var connection = Database.connection)
{
    String Track1Genre = @"
      INSERT 
      INTO TrackGenre(TrackId, GenreId) 
      VALUES (
        (SELECT id FROM track WHERE titel = @titel), /* do a select for the ID */
        (SELECT id FROM genre WHERE genre = @genre))";

    string Genre = listBoxGenre.GetItemText(listBoxGenre.SelectedItem);
    using (SqlCommand sqlCmd = new SqlCommand(Track1Genre, connection))
    {

        // caution, better use Add, see the note
        sqlCmd.Parameters.AddWithValue("@titel", textBoxTitel.Text);
        sqlCmd.Parameters.AddWithValue("@Genre", Genre);
        sqlCmd.ExecuteNonQuery();
    }
}

请记住,如果您具有相同标题的曲目或具有相同名称的流派,则insert语句将失败。但这取决于你处理或防止上游发生。

如果您想100%确定从Track插入得到的Id,请参阅Sunil答案中的Output Inserted.Id选项。你必须将lastid变量带到我在这里显示的代码,用它替换第一个参数(并相应地调整insert查询)。

注意 使用AddWithValue可能存在问题,如JCoohorn的博文中所述:https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/

最好防止SqlParameter类猜错你的类型。考虑使用

sqlCmd.Parameters.Add("@titel", SqlDbType.NVarChar, 250).Value = textBoxTitel.Text;

代替。

如果你想首先尝试插入查询以了解它正在做什么,请分叉this SEDE query


-2
投票

我不知道这是一个错字还是真正的错误应该纠正

你的代码中的这一行

 sqlCmd.Parameters.AddWithValue("@TrackId", "Select Id from Track WHERE Titel = textBoxTitel.Text");

应该这样写

 sqlCmd.Parameters.AddWithValue("@TrackId", "Select Id from Track WHERE Titel = " + textBoxTitel.Text);

同样的问题是Genre太多了。如果您编写的代码是正确的,那么您的查询实际上是在搜索'textBoxTitel.Text'而不是trackid

© www.soinside.com 2019 - 2024. All rights reserved.