这是我创建曲目的第一行(此作品)
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,我需要它,所以我可以将它链接到其他东西(在这种情况下是一种类型。我已经在不同的表中指定了类型的名称,需要它们标识) 我现在正在尝试这个,但它不起作用,我不知道该怎么做。
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从数据库中取出并插入到不同的表中
答案 0 :(得分:2)
两种方法:
输出已插入.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 :(得分:-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
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
提到了什么。如果它是值并且需要传递到存储过程,那么您需要再添加一个参数来处理它。
答案 2 :(得分:-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
变量带到此处显示的代码中,用它替换第一个参数(并相应地调整插入查询)。
注意强>
使用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。
答案 3 :(得分:-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