Как получить последнюю / последнюю вставленную запись в oracle [duplicate]

В Java все переменные, которые вы объявляете, на самом деле являются «ссылками» на объекты (или примитивы), а не самими объектами.

При попытке выполнить один метод объекта , ссылка просит живой объект выполнить этот метод. Но если ссылка ссылается на NULL (ничего, нуль, void, nada), то нет способа, которым метод будет выполнен. Тогда runtime сообщит вам об этом, выбросив исключение NullPointerException.

Ваша ссылка «указывает» на нуль, таким образом, «Null -> Pointer».

Объект живет в памяти виртуальной машины пространство и единственный способ доступа к нему - использовать ссылки this. Возьмем этот пример:

public class Some {
    private int id;
    public int getId(){
        return this.id;
    }
    public setId( int newId ) {
        this.id = newId;
    }
}

И в другом месте вашего кода:

Some reference = new Some();    // Point to a new object of type Some()
Some otherReference = null;     // Initiallly this points to NULL

reference.setId( 1 );           // Execute setId method, now private var id is 1

System.out.println( reference.getId() ); // Prints 1 to the console

otherReference = reference      // Now they both point to the only object.

reference = null;               // "reference" now point to null.

// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );

// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...

Это важно знать - когда больше нет ссылок на объект (в пример выше, когда reference и otherReference оба указывают на null), тогда объект «недоступен». Мы не можем работать с ним, поэтому этот объект готов к сбору мусора, и в какой-то момент VM освободит память, используемую этим объектом, и выделит другую.

22
задан Ben 12 June 2014 в 13:30
поделиться

5 ответов

В таблице нет такой вещи, как «последняя» строка, так как таблица Oracle не имеет понятия порядка.

Однако, предполагая, что вы хотите найти последний вставленный первичный ключ и , что этот первичный ключ является увеличивающимся числом, вы можете сделать что-то вроде этого:

select *
  from ( select a.*, max(pk) over () as max_pk
           from my_table a
                )
 where pk = max_pk

Если у вас есть дата создания каждой строки, это станет, если столбец named created:

select *
  from ( select a.*, max(created) over () as max_created
           from my_table a
                )
 where created = max_created

В качестве альтернативы вы можете использовать агрегированный запрос, например:

select *
  from my_table
 where pk = ( select max(pk) from my_table )

Вот немного SQL Fiddle для продемонстрировать.

42
ответ дан Ben 18 August 2018 в 08:49
поделиться
  • 1
    Я получил эту ошибку при ее попытке (средний запрос) в таблице с ~ 3 миллиардами строк ORA-01652: не удалось продлить временный сегмент на 128 в табличном пространстве TEMP 01652. 00000 - «не удалось продлить временный сегмент на% s в табличном пространстве % s & Quot; * Причина: Не удалось выделить необходимое количество блоков для временного сегмента в указанном табличном пространстве. * Действие: Используйте инструкцию ALTER TABLESPACE ADD DATAFILE, чтобы добавить один или несколько файлов в указанное табличное пространство. – Sambit Tripathy 12 April 2016 в 19:36
  • 2
    У вас есть таблица строк 3bn, и вы пытаетесь найти последнюю строку @Sambit? Я могу гарантировать, что вам не понадобится найти последнюю строку. Прежде всего, пересмотреть требования. Если вам действительно нужно найти последнюю строку, вам нужен способ ее однозначного определения или вам нужно увеличить количество пространства пробелов (что является причиной вашей ошибки) – Ben 12 April 2016 в 21:15
  • 3
    Вы правы, я попробовал со столом с 1 миллиардом строк, и это сработало! К сожалению, я хочу найти rowid из последней добавленной строки, и я никак не могу понять последнюю метку времени. Однако я немного изменил ваш запрос, и он сработал. Вместо «выберите a. *, Max (созданный) ...». Я использовал «select a.rowid, max (created) ..), и он работал для таблицы 3 B. – Sambit Tripathy 12 April 2016 в 22:53
  • 4
    Запрос, который работал для таблицы 3 B: выберите rowid from (выберите a.rowid, max (created) over () как max_created из my_table a), где created = max_created, а затем используйте select * from my_table, где rowid = 'sdasdasdas' – Sambit Tripathy 12 April 2016 в 22:54
  • 5
    Я бы предположил, что вы не сохраняете свой MY_ID в столбце с числовым типом данных @vapcguy, двоичная сортировка по строкам будет объяснять поведение, которое вы видите. Если нет, то, вероятно, лучше задать новый вопрос с помощью [mvce]. Пинг меня, если да, мне было бы интересно узнать, в чем проблема. Если вы только когда-либо вставляете прямые вставки в нераспределенную таблицу кучи, которую вы никогда не изменяете каким-либо образом (включая стандартный администратор) и где у вас есть только один файл данных с свободным пространством и никогда не выполняете какую-либо другую операцию, возможно , что ряды будут находиться в «восходящем» ... – Ben 13 August 2016 в 09:28
1
ответ дан lpfx 18 August 2018 в 08:49
поделиться
$sql = "INSERT INTO table_name( field1, field2 )  VALUES ('foo','bar') 
        RETURNING ID INTO :mylastid";
$stmt = oci_parse($db, $sql);
oci_bind_by_name($stmt, "mylastid", $last_id, 8, SQLT_INT);
oci_execute($stmt);

echo "last inserted id is:".$last_id;

Совет: вам нужно использовать имя столбца id в {your_id_col_name} ниже ...

"RETURNING {your_id_col_name} INTO :mylastid"
-1
ответ дан melisozmen 18 August 2018 в 08:49
поделиться

Последняя строка в соответствии со строгим полным порядком по составному ключу K (k1, ..., kn):

SELECT  *
FROM    TableX AS o
WHERE   NOT EXISTS (
            SELECT  *
            FROM    TableX AS i
            WHERE   i.k1 > o.k1
                OR  (i.k1 = o.k1 AND i.k2 > o.k2)
                ...
                OR  (i.k1 = o.k1 AND i.k2 = o.k2 AND i.k3 = o.k3 AND ... AND i.kn > o.kn)
        )
;

Учитывая частный случай, когда K является простым (т. е. не композитным) приведенное выше сокращено до:

SELECT  *
FROM    TableX AS o
WHERE   NOT EXISTS (
            SELECT  *
            FROM    TableX AS i
            WHERE   i.k1 > o.k1
        )
;

Обратите внимание, что для этого запроса, чтобы вернуть только одну строку, ключ должен заказывать без связей. Если ссылки разрешены, этот запрос вернет все строки, привязанные к наибольшему ключу.

3
ответ дан rslemos 18 August 2018 в 08:49
поделиться
  • 1
    downvote без комментариев? Мне любопытно. – rslemos 13 June 2014 в 02:39
  • 2
    Не знаю, это правильно. Однако используемый вами язык довольно плотный. Не теряйте точность, но чем больше людей понимают ваш ответ, тем лучше. – Ben 13 June 2014 в 07:14
SELECT * FROM (
    SELECT * FROM table_name ORDER BY sortable_column DESC
) WHERE ROWNUM = 1;
16
ответ дан rtaft 18 August 2018 в 08:49
поделиться
  • 1
    будет ли это работать? Я думал, что rownum применяется до и order by, что означает, что он игнорирует сортировку, которую вы там делаете. [Д0] oracle.com/technetwork/issue-archive/2006/06-sep/… – Alex Moore-Niemi 16 September 2015 в 19:25
  • 2
    @ AlexMoore-Niemi Сначала происходит сортировка в parens, поэтому rownum работает в этом примере. Вы увидите это ниже в статье, которую вы связали. Попробуйте протестировать его, и вы увидите, что он работает. – user2227422 19 October 2015 в 22:46
  • 3
    Я попробовал это и получил неверный идентификатор. У меня есть таблица, которую я построил из другой, используя insert into /*+ append */ с ORDER BY DESC в столбце идентификатора первичного ключа. Когда я построил таблицу изначально, она поставила строки в правильном порядке с 1-75. Когда я запускаю этот запрос или выполняю select * from ( select a.*, max(pk) over () as max_pk from my_table a ) where pk = max_pk, я получаю 9. Если я делаю SELECT ID FROM MyTable WHERE ROWID IN (SELECT MAX(ROWID) FROM MyTable), я получаю правильный ID 75. – vapcguy 12 August 2016 в 14:44
  • 4
    @vapcguy у вас нет ROWNUM в запросах, которые вы разместили. Возможно, вы прокомментировали неправильный пример. – rtaft 12 August 2016 в 17:47
  • 5
    @rtaft. Я имел в виду, если бы я выполнил ваш запрос или ответ от ответа Бена выше вашего, ответы BOTH дали мне 9. Вот что я имел в виду, когда сказал: Когда я запустил этот запрос или сделаю ... выше. Этот ссылался на выполнение вашего запроса, rtaft. Извините, если это неясно. – vapcguy 12 August 2016 в 20:37
Другие вопросы по тегам:

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