cравнить два рекорда в PL/SQL без перечисления полей?

11g newbi
Дата: 19.11.2009 13:45:02
вроде такого нет даже в 11g?

declare
  lR1 mys.sart%rowtype;
  lR2 mys.sart%rowtype;
begin
  if lR1 = lR2 then
    ....
  else
    ......
  end if;
end;     

а жаль! :-(
Elic
Дата: 19.11.2009 14:02:19
Намёк, почему нет (и не будет): (lR1.x is null and lR2.x is null) - записи при этом равны? - Следуя традициям Oracle-а, это UNKNOWN(NULL). Поэтому и малополезно :)
RedFast
Дата: 19.11.2009 18:37:42
union
Elic
Дата: 19.11.2009 18:46:58
RedFast
union
Перед тем, как писать бред, тебе стоит больше думать
semirax
Дата: 21.11.2009 16:08:08
Elic,

CREATE TABLE t(x int, y int);

CREATE OR REPLACE PACKAGE comp_pkg AS 
  TYPE t_type IS TABLE OF t%ROWTYPE; 
  FUNCTION f_pipe RETURN t_type PIPELINED;
  FUNCTION is_records_equal(x t%ROWTYPE, y t%ROWTYPE) RETURN BOOLEAN;
end comp_pkg;
/


CREATE OR REPLACE PACKAGE BODY comp_pkg AS
  gT t_type;
  FUNCTION f_pipe RETURN t_type PIPELINED IS
  BEGIN
    PIPE ROW(gT(1)); PIPE ROW(gT(2));
  END f_pipe;

  FUNCTION is_records_equal(x t%ROWTYPE, y t%ROWTYPE) RETURN BOOLEAN IS
    lCNT NUMBER;
  BEGIN
    gT := t_type(x, y);
    SELECT COUNT(*) 
    INTO lCNT
    FROM (SELECT DISTINCT * FROM TABLE(comp_pkg.f_pipe));
    RETURN (lCNT = 1);
  END is_records_equal;
END comp_pkg;
/

SET SERVEROUTPUT ON SIZE 100000;

DECLARE
  r1 t%ROWTYPE;
  r2 t%ROWTYPE;
BEGIN
  r1.x:=1; r1.y:=1;
  r2.x:=1; r2.y:=1;
  dbms_output.put_line(CASE WHEN comp_pkg.is_records_equal(r1, r2) THEN '=' ELSE '<>' END);

  r1.x:=1; r1.y:=1;
  r2.x:=1; r2.y:=2;
  dbms_output.put_line(CASE WHEN comp_pkg.is_records_equal(r1, r2) THEN '=' ELSE '<>' END);

  r1.x:=1; r1.y:=1;
  r2.x:=1; r2.y:=NULL;
  dbms_output.put_line(CASE WHEN comp_pkg.is_records_equal(r1, r2) THEN '=' ELSE '<>' END);

  r1.x:=1; r1.y:=NULL;
  r2.x:=1; r2.y:=NULL;
  dbms_output.put_line(CASE WHEN comp_pkg.is_records_equal(r1, r2) THEN '=' ELSE '<>' END);  
END;
/

Получаем:

=
<>
<>
=
semirax
Дата: 21.11.2009 16:10:33
Пример выше показывает, что без создания типов уровня схемы и без явного перечисления полей записей сравнение все-таки возможно.
Nikolay Kalmarskiy
Дата: 21.11.2009 16:25:52
semirax
Пример выше показывает, что без создания типов уровня схемы и без явного перечисления полей записей сравнение все-таки возможно.


Не совсем так. Типы уровня схемы в вашем примере всё же создаются.

SQL> select count(*) from user_types;

  COUNT(*)
----------
         0

SQL> @c:\work\test\pt2811

Table created.


Package created.


Package body created.

=
<>
<>
=

PL/SQL procedure successfully completed.

SQL> select count(*) from user_types;

  COUNT(*)
----------
         4

SQL>
andreymx
Дата: 21.11.2009 22:22:56
semirax
Пример выше показывает, что без создания типов уровня схемы и без явного перечисления полей записей сравнение все-таки возможно.
вы уровняли NULLы, что не есть хорошо, как и написал уже Elic
RA\/EN
Дата: 21.11.2009 22:33:38
Не буквоедствуйте С точки зрения оператора = nullы различаются, с точчки зрения distinct/union - нет. И вообще, в составе СТРУКТУР нуллы ведут себя не так, как отдельно: составной UNIQUE KEY допускает несколько (NULL,NULL), но не допускает несколько (1,NULL). Т.к. сравниваются именно структуры, то логика NULL применима разве что к полностью пустым структурам.
Dixi.
suPPLer
Дата: 21.11.2009 22:52:17
andreymx
semirax
Пример выше показывает, что без создания типов уровня схемы и без явного перечисления полей записей сравнение все-таки возможно.
вы уровняли NULLы, что не есть хорошо, как и написал уже Elic


Сравнение NULL ещё терпимо, а вот это уже незнание доброты Oracle, создающего для PIPELINED-функций соответствующие SQL-типы автоматом, начиная с, ЕМНИП, 10g.