Выберите последнюю строку в таблице SQL

Если бы это было идеальным миром, 100% кода были бы покрыты модульными тестами. Однако, так как это не идеальный мир, это - вопрос того, для чего у Вас есть время. В результате я рекомендую фокусироваться меньше на определенном проценте и сфокусироваться больше на критических областях. Если Ваш код правильно написан (или по крайней мере разумное факсимиле этого) должно быть несколько ключевых пунктов, где API представлены другому коду.

Фокус Ваши усилия по тестированию на этих API. Удостоверьтесь, что API 1) хорошо документируются и 2) записали тестовые сценарии, которые соответствуют документации. Если ожидаемые результаты не совпадают с документами, то у Вас есть ошибка или в Вашем коде, документации или в тестовых сценариях. Все из которых хороши для проверки.

Удачи!

6
задан Joel Coehoorn 14 July 2009 в 16:31
поделиться

7 ответов

с использованием поля автоматического увеличения ... и я хочу получить последнее, только что добавленное, чтобы соединить его с чем-то еще.

Ключ здесь - « только что добавлен » . Если у вас есть несколько разных пользователей, которые обращаются к базе данных одновременно, я не думаю, что вы хотите, чтобы пользователь A извлекал запись, созданную пользователем B. Это означает, что вы, вероятно, захотите использовать scope_identity () , чтобы получить этот идентификатор вместо того, чтобы сразу же снова запускать запрос к таблице.

В зависимости от контекста вам также может потребоваться @@ identity (будет включать триггеры) или identify_current ('вопросы' ) (ограничивается конкретной таблицей, но не конкретным объемом). Но scope_identity () почти всегда подходит для использования.


Вот пример:

DECLARE @NewOrderID int

INSERT INTO TABLE [Orders] (CustomerID) VALUES (1234)

SELECT @NewOrderID=scope_identity()

INSERT INTO TABLE [OrderLines] (OrderID, ProductID, Quantity) 
    SELECT @NewOrderID, ProductID, Quantity
    FROM [ShoppingCart]
    WHERE CustomerID=1234 AND SessionKey=4321

На основе опубликованного вами кода вы можете сделать что-то вроде этого:

// don't list the ID column: it should be an identity column that sql server will handle for you
const string QUERY = "INSERT INTO Questions (Question, Answer, CategoryID, Permission) " 
                   + "VALUES (@Question, @Answer, @CategoryID, @Permission);"
                   + "SELECT scope_identity();"; 

int NewQuestionID;
using (var cmd = new SqlCommand(QUERY, conn)) 
{ 
    cmd.Parameters.AddWithValue("@Question", question); 
    cmd.Parameters.AddWithValue("@Answer", answer); 
    cmd.Parameters.AddWithValue("@CategoryID", lastEdited);
    cmd.Parameters.AddWithValue("@Permission", categoryID);
    NewQuestionID = (int)cmd.ExecuteScalar(); 
}

См. Мой ответ на другой вопрос:
получить новый идентификатор записи SQL

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

Я также не поклонник метода .AddWithValue () - я предпочитаю явно определять типы параметров - но мы можем оставить это на другой день.

Наконец, уже поздно сейчас, но я хочу подчеркнуть, что действительно лучше попытаться сохранить все это в базе данных. Можно запускать несколько операторов в одной команде sql, и вы хотите уменьшить количество циклических обращений, которые вам нужно сделать для базы данных, и количество данных, которые необходимо передавать между базой данных и вашим приложением. Это также упрощает выполнение транзакций и позволяет сохранять атомарность там, где они должны быть.

19
ответ дан 8 December 2019 в 02:03
поделиться

Поскольку спрашивающий использует .NET, вот модифицированный пример того, как это сделать. (Я удалил ID из списка вставок, так как он автоинкремент - исходный пример не удастся. Я также предполагаю, что ID - это SQL int, а не bigint.)

        const string QUERY = @"INSERT INTO Questions (Question, Answer, CategoryID, Permission) "
                           + @"VALUES (@Question, @Answer, @CategoryID, @Permission);"
                           + @"SELECT @ID = SCOPE_IDENTITY();";

        using (var cmd = new SqlCommand(QUERY, conn)) 
        { 
            cmd.Parameters.AddWithValue("@Question", question); 
            cmd.Parameters.AddWithValue("@Answer", answer); 
            cmd.Parameters.AddWithValue("@CategoryID", lastEdited);
            cmd.Parameters.AddWithValue("@Permission", categoryID);
            cmd.Parameters.Add("@ID", System.Data.SqlDbType.Int).Direction = ParameterDirection.Output;
            cmd.ExecuteNonQuery();

            int id = (int)cmd.Parameters["@ID"].Value;
        }

EDITED: Я также предлагаю рассмотреть LINQ to SQL вместо ручное кодирование объектов SqlCommand - это намного лучше (быстрее кодировать, проще в использовании) для многих распространенных сценариев.

1
ответ дан 8 December 2019 в 02:03
поделиться

Небезопасно - может быть несколько операций вставки одновременно, и последняя строка, которую вы получите, может быть не вашей. Лучше использовать SCOPE_IDENTITY (), чтобы получить последний ключ, назначенный для вашей транзакции.

24
ответ дан 8 December 2019 в 02:03
поделиться

use

  • scope_identity () возвращает последнее значение идентификатора, сгенерированное в этом сеансе, и эта область
  • identity_current () возвращает последнее значение идентификатора, сгенерированное для конкретного таблица в любом сеансе и любой области

    select ident_current ('yourTableName')

вернет последний идентификатор, созданный другим сеансом.

В большинстве случаев вы должны использовать scope_identity () сразу после оператора вставки, например итак.

--insert statement
SET @id = CAST(SCOPE_IDENTITY() AS INT)
10
ответ дан 8 December 2019 в 02:03
поделиться

Мой любимый ресурс по интерполяции аудио (особенно в приложениях с передискретизацией) - это статья Олли Ниемитало «Слон» .

Я использовал пару таких, и они звучат потрясающе (намного лучше, чем прямое кубическое решение, которое относительно шумно). Есть шлицевые формы, формы Эрмита, Ватте, параболические и т.д. И они обсуждаются с точки зрения аудио . Это не просто обычная наивная подгонка полиномов.

И код включен!

Чтобы решить, что использовать, вы, вероятно, захотите начать с таблицы на стр. 60, которая группирует алгоритмы по сложности операторов (сколько умножений, и сколько добавляет). Затем выберите одно из лучших решений для соотношения сигнал-шум - используйте слух в качестве ориентира, чтобы сделать окончательный выбор. Примечание. Как правило,

4
ответ дан 8 December 2019 в 02:03
поделиться

С помощью простого выбора вы можете сделать что-то вроде этого:

SELECT *
FROM table_name
WHERE IDColumn=(SELECT max(IDColum) FROM table_name)
-1
ответ дан 8 December 2019 в 02:03
поделиться

Я не уверен в вашей версии SQL Server, но ищите Предложение OUTPUT оператора INSERT. Вы можете захватить набор строк с помощью этого предложения

1
ответ дан 8 December 2019 в 02:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: