Получить RecordId из таблицы

Я новичок в SQL, у меня есть таблица с RecordId, которая автоматически увеличивается и является первичным ключом. Я хотел бы получить RecordId строки, которая была вставлена ​​в таблицу. Заранее спасибо за помощь.

myCommand.CommandText = "INSERT INTO " + tableName + " (DateRaised,RaisedBy,WeekNo,Platform,Department,Site,Process, Area,NavErrorNo,RootCauseDescription,Status) " +
    "VALUES ('" + currentDate.ToString(format) + "','" +
    sender + "'," +
    weekNumber + ",'" +
    comboBoxPlatform.SelectedItem + "','" +
    comboBoxDepartment.SelectedItem + "','" +
    comboBoxSite.SelectedItem + "','" +
    comboBoxProcess.SelectedItem + "','" +
    comboBoxArea.SelectedItem + "','" +
    textBoxNavError.Text + "','" +
    textBoxIssue.Text + "','Open')";
//int lastInsertedId = 
myCommand.ExecuteNonQuery();

lastInsertedId должно быть int от RecordId в моей таблице.


person Pawel G    schedule 02.08.2019    source источник
comment
Этот код представляет угрозу безопасности. Прочтите о SQL-инъекциях и параметризованных запросах. Не используйте несколько таблиц с одинаковой структурой (как следует из конкатенации имен таблиц).   -  person Zohar Peled    schedule 02.08.2019


Ответы (3)


Чтобы сделать это правильно (если это для SQL Server — вы не очень поняли это), я вижу два варианта:

Подход №1 – использование SCOPE_IDENTITY

Это хорошо работает, если вы вставляете только одну строку за раз - используйте что-то вроде этого:

// set up your query using *PARAMETERS** as you **ALWAYS** should! 
// Using SELECT SCOPE_IDENTITY() to get back the newly inserted "Id"
myCommand.CommandText = "INSERT INTO dbo.SomeTable (list-of-columns) " +
                        "VALUES (@param1, @param2, @param3, ...., @paramN); " +
                        "SELECT SCOPE_IDENTITY();";

// set up the parameters and theirs values

object result = myCommand.ExecuteScalar();

if (result != null)
{ 
    int lastInsertedId = Convert.ToInt32(result);
}

Подход №2 – использование предложения OUTPUT

Это хорошо работает, даже если вы вставляете несколько строк одновременно (обычно используя SELECT после INSERT):

// set up your query using *PARAMETERS** as you **ALWAYS** should! 
// Using SELECT SCOPE_IDENTITY() to get back the newly inserted "Id"
myCommand.CommandText = "INSERT INTO dbo.SomeTable (list-of-columns) " +
                        "OUTPUT Inserted.RecordId " + 
                        "VALUES (@param1, @param2, @param3, ...., @paramN); ";

// set up the parameters and theirs values

object result = myCommand.ExecuteScalar();

if (result != null)
{ 
    int lastInsertedId = Convert.ToInt32(result);
}
person marc_s    schedule 02.08.2019
comment
Я попробую подход 2, мне потребуется некоторое время, чтобы настроить параметры, поскольку я никогда раньше этого не делал. Спасибо @marc_s - person Pawel G; 02.08.2019

Во-первых, не рекомендуется вызывать прямую инструкцию SQL из кода, это может вызвать проблему для SQL-инъекции, как предложил @Zohar. Можно либо параметризованный пользователем запрос, либо sp.

Внутри sp вы можете использовать

SELECT @@IDENTITY AS 'Identity';

после оператора Insert он вернет последнее автоматически увеличенное значение для PK, затем вернет это значение в качестве выходного параметра и перехватит его после .ExecuteNonQuery(); в коде C#.

person Tarun Dudhatra    schedule 02.08.2019
comment
не могли бы вы изменить мой код, чтобы он был написан правильно, пожалуйста? - person Pawel G; 02.08.2019
comment
Я бы рекомендовал использовать SCOPE_IDENTITY() вместо чего-либо еще (например, @@IDENTITY), чтобы получить только что вставленное значение идентификатора. Объяснение ПОЧЕМУ см. в этом сообщении в блоге - person marc_s; 02.08.2019
comment
@marc_s это то, что я ищу, но понятия не имею, как изменить мой код на правильные методы. - person Pawel G; 02.08.2019
comment
@PawelG: добавил собственный ответ, показывающий допустимые способы сделать это, ИМХО - person marc_s; 02.08.2019

Это должно помочь вам

private void SelectLast()
        {

            string sqlLast = "SELECT TOP(1) RecordId FROM [YourtableName] ORDER BY 1 DESC";

            Connection.Open();
            using (SqlCommand cmd = new SqlCommand(sqlLast, Connection))
            {
                cmd.CommandType = CommandType.Text;
                {
                    int insertedID = Convert.ToInt32(cmdAdd.ExecuteScalar());
                    textBoxID.Text = Convert.ToString(insertedID);
                }
                Connection.Close();
            }

        }
person Kuba Do    schedule 02.08.2019