�������: ������ (���� | �����������) ��RU opennet.me  
The OpenNET Project / Index page

[ ������� /+++ | ����� | ���� | ]

������� ������������ / ������ "���� ������, SQL" (����� | ��� ������)

������������� ��������� ������ � ����������� ��

�����: ������ ���������
��������: RSDN Magazine #0
������������: 28.01.2002
����������: 15.01.2004
������ ������: 1.2
��������
�������� ������
��������� �������� �������� �� ��� �������� ��������
��������� ���������������� ��������
��������� ���� ��������
��������� ������ ����������� ��������
��������� ������� ���� �� �������� �� ����� ��������
�������� �������, ��������, ����������� �������� � ��� ��������
����������

��������

����������� ����������� ��� ������ ������������� �� �������� ������ ������ �� ���������� � ��������� �������������� ������� � ������ ����� ����. ������ �� ������� ������� �������� ���������� �� ����� ����������. ����������� �������� ���������� � ����������� ���� �� ����� ����������� ��������� (�.�. ��� ���������� "�������" ������) �� �������� ������� �����������. ������, ������ � "��������" �������, ��� ���������� ���� ������� �������������� ������, ���������� ������� � �� � ���������� � "���������" ���� � ����� ���������, �.� ������������� ������. ����������� �������� ����� ���������� � ����������� �� ������, �� �� ������ �������� ��� ���, ��� ������� ������������ � �������� �������. � ������ ������ � ��������� ���������� ����������� ������.

�������, ���������� �����, ���� ������� � �������������� � ������� Interbase 6.

�������� ������

����� �������� �������� �������� �������� � ����������� ��, �� ������� ���������� ������ � ���, ����� �� �������� ������ ����� ����������� �� ��������. � �������� ����� �������� �����, ��� �������, ��������� �����������. �������� ��� �����������, ����� ��������� ����� ����������� ��������� ��������� ������������� ������.

���, � ����� ������, ������ ����� ����� ����� ���������� ������� ��������. �� � ������� ������� ����� ������� �����, � ����� �����������, ��������. ����� ���� ���������� ���������� ���������������� �������� ������ �������� ��������.

���������� ��������� �������� ������������� ������������� �������� � ����������� ��.

��������� �������� �������� �� ��� �������� ��������

�������� ����� ������� �������� ������ � �������������� ������� ����������� � �������������� ����������� ��������. ��� �������� ������ ���� �������� ���������� �������� � �������� �������� �������������� ���� - ������ �� ��������� ���� ������. ����� ������ ����������� �������� �������� ����� ���������������� � �������������. ������ ��� ������� ��������� ����������:

������������� ����������� �������� ��� ��������� ������� ���� �� ������������� �������� �� ����� ������.

��������� ���������� ������ ����������� ������������� ��������.

��������� ��������� ���� (� ��� ����� � �� ������) �������� ������� ����.

���������� ������������ �� ����� ����� �� ������� ���������� ������������� ��������� - ������������� �������� ����������. ������ ������� ����������� ��� �������������, ���������� � ������ ���� �� �� ����������. ����� �������, ��� ������ ������� �������� ����������� ����������� ������������ ���������� ������. ��� ����������� ������������ ������� ��� ������� �������� �������� ���������� ������ ��������� ����. ��� ��������� ������������� ������ ������ �������������� ����-������ �� ������ ������� �������� ��������. ���� ��������� �������� ���������� ��������� �� ����� SQL:

CREATE TABLE "CATALOG" (
  "ID" INTEGER NOT NULL PRIMARY KEY,
  "NAME" VARCHAR(200) CHARACTER SET WIN1251 NOT NULL,
  "PARENT_ID" INTEGER
);

������ ��������� �������� ���������� ����������� � ����������� ��� ����������� � �������� ��������. ������� �� ���������� �� ������� �� ������. � ������ ��������� ������������ ��� ������� ���� ���������� - ���������� �������� ������������ ������ �� ��������. ����� �� �������� ���� PARENT_ID �������� �����������? ����� �������� - ���� �������� �������� ���������� ����� (���� ID) + ���� ��������, ������������ ��� ����������� ���������� ������������� ��������. ������ �������� ���������� ��� ����� � �������� �������� ��������� ��������. ���� ����� � �������� ��������, ������������� ���������� ��������, ������������ NULL, ���� ��� ������� ���������� ����������� ��� ������������� ������ ��������. ���, ��������, ���� �� �������, ��� �������� ���������� ����� ����� ������ 0, � �������� �������� ��������� �������� ����� ������������ �������� (-1) ��� ������ ������������� �������� � ���� PARENT_ID. � �� ���� ���������� � � �������� �������� PARENT_ID ��� �������� ��������� ��������� NULL. ����� ��� �������� ������������ PARENT_ID ����� ������������ ��������� �����������:

"PARENT_ID" INTEGER
  CHECK(
      ("PARENT_ID" IS NULL) 
    OR 
       ( "PARENT_ID" = ANY(SELECT "ID" FROM "CATALOG") )
  )
(� ��������, ����� ����������� ������� ����� � ����������� 
��������� ��� ������� �����. ������������ ��������� ��� ���� 
�������� ������� �������� ������, �.�. ������������ ������ 
��� ��� �� ����������. ������ ����� ����������� �����, �������� 
������� ���� ����� ������� �������� ������. - ����.���.)

�������� � ���������� ���� ����������� ������ ��������� (��������� ������������ ������� ���� � ���������� ������ ��������). ��� ���������� �������� �� ���� �������� �����, ��� � ������ ��������� ���������� � ������ ���� � ������ ����� �� ��������. ������ �������� �������� ��������� ������ ����������� ����� ��������� � ��������� ������� ��������������� ���� Level. �������� ������� ����� ����� ��������� ���:

CREATE TABLE "CATALOG" (
  "ID" INTEGER NOT NULL PRIMARY KEY,
  "NAME" VARCHAR(200) CHARACTER SET WIN1251 NOT NULL,
  "PARENT_ID" INTEGER
  CHECK(
     "PARENT_ID" = ANY(SELECT "ID" FROM "CATALOG") or "PARENT_ID" is NULL
  ),
  "LEVEL" INTEGER  DEFAULT 1 NOT NULL
);

��������� ��� �������� �������� � �������������� ������ ������� ����������� � �������� ������.

��������� �� ������� ��������������� �������� �������� � �������������� ������ ������� ����������� � �������� ������ �������� �������� ��������. ����������� ���������� �������� ��������� ������� ������ � ��������� ����.

������ �� ������ �������� � ���� ������ �� ������, �������� ���������� � ���������� ������ �������� � �������� (����� �������) � ��������� ��������.

� ����� ������� �� ��������� ���������� ������� ������ 5, ����� SQL-�������� ������� ����� ��������� ��������� �������:

CREATE TABLE "CATALOG2" (
  "LEVEL" INTEGER NOT NULL,
  "OFFSET" SMALLINT NOT NULL CHECK("OFFSET" > 0 and "OFFSET" < 6),
  "NAME_1" VARCHAR(200) CHARACTER SET WIN1251,
  "NAME_2" VARCHAR(200) CHARACTER SET WIN1251,
  "NAME_3" VARCHAR(200) CHARACTER SET WIN1251,
  "NAME_4" VARCHAR(200) CHARACTER SET WIN1251,
  "NAME_5" VARCHAR(200) CHARACTER SET WIN1251,
  "PARENT_LEVEL" INTEGER,
  "PARENT_OFFSET" SMALLINT CHECK(("PARENT_OFFSET" > 0 and "PARENT_OFFSET" < 6) or ("PARENT_OFFSET" is NULL)),
  CONSTRAINT "PK_CATALOG2" PRIMARY KEY("LEVEL","OFFSET")
);

������� ����������� ������������� ����� ��������� � �� ����, ���������� �� ������ - ��� ��������� ������������� ���������� �������� ������ ���� �������� ��������� ��� ���� ������� �������, ��� ������ ��������. �� ���� ������� �������� ������������� ��� ��������� �� �� ������, � �������� � ���������� ������ - �������� � �������� ������ ������� ����������� � ����������� ������ �������� ����.

����� �� ��������� �������� ����� �������� �������� ����������� �������� � ��������� ��������. ��������, ������� CATALOG_LEVEL_1 ������ ��� �������� ������� ������ �����������, ������� CATALOG_LEVEL_2 - �������, � �.�. ���� ��������� �������� ����� ��������� ��� ������ ������������� ��������.

CREATE TABLE "CATALOG3_LEVEL1" (
  "ID" INTEGER NOT NULL PRIMARY KEY,
  "NAME" VARCHAR(200) CHARACTER SET WIN1251 NOT NULL
);
CREATE TABLE "CATALOG3_LEVEL2" (
  "ID" INTEGER NOT NULL UNIQUE,
  "NAME" VARCHAR(200) CHARACTER SET WIN1251 NOT NULL,
  "PARENT_ID" INTEGER NOT NULL REFERENCES "CATALOG3_LEVEL1"("ID"),
  PRIMARY KEY("ID","PARENT_ID")
);
CREATE TABLE "CATALOG3_LEVEL3" (
  "ID" INTEGER NOT NULL UNIQUE,
  "NAME" VARCHAR(200) CHARACTER SET WIN1251 NOT NULL,
  "PARENT_ID" INTEGER NOT NULL REFERENCES "CATALOG3_LEVEL1"("ID"),
  "PARENT_ID2" INTEGER NOT NULL REFERENCES "CATALOG3_LEVEL2"("ID"),
  PRIMARY KEY ("ID", "PARENT_ID", "PARENT_ID2")
);

��� ������� ���������� ������� ���������� ���������� �������������� ������� ��� ������� ������, �� ��������� ����������� ������� CATALOG3_LEVEL2. � ������ ��������� ��������� ������ �������� �� ������������ ������� ���������, �.� ���������� ������������ ��������, � ������� �� ��������. ������ ���� �� ������ �������� �� ����� ����� ������������ ��������� ��������� ������ �������. ���� ��� ��������� ������� ���������� � ����������� ��������� �������

��������� �� ����� �������� - �������� � ������������ ������������ � ������������ ������ ��������. ������ �� �������� �����, ������������� ���, � ��� ��� ���� ������� ����� ���� ������ � ����� ���� ��������. ���, ��������, ���� ������ � ��������� ����������, ���� � ������� ���� � �������� ��������� � �������������� ������ �������� ���� � ������������, ����� ���� ������� � ���������������� ���� ��������. ������ ����� ���������� ���������� ��������� �� ����� ������ ��������� 9 (��� ������ ���������� ������� ������) � 5 �������� �����������. �����? �����, ��� � ������ ���� �������� ��� ������������ ����������� ���������� ����� ����� ����������� ��������� ������ � ���������. ��� �������� ������� ���� �������� ����� ������������ ����� ��������� ��������� �������� � �������������� ������������ � ����������� �������� � �������� � ������������ ����������� ������� � �������������� ������ ��������. ������ ���� ��� ����������� �������� ����������� ��� ������� ���� ��������.

������ ��� �������� ����:

CREATE TABLE "CATALOG4" (
  "ID" DECIMAL(5) NOT NULL PRIMARY KEY,
  "NAME" VARCHAR(200) CHARACTER SET WIN1251 NOT NULL
);

���� ����� � �������� ������������ ���������� ����� ID. ������� ���������� ���������� ����������� ������� ����� - ��� ������� ��������, � ����� � ���� ������� - ����� �������� �� ������ ������. ��������, ������ ������� ������� ������ ����� ����� ID = 00001, ������ - 00002. �� ������ ������ ������ �������, ������� ������� ������ ������� ������� ������, ����� ����� ID = 00031, � �.�. ������ ��������� ������ ��� ����������� ������������� ��������� �� �������. �� �� ������� ���������� � ����������� ������. � ����������� �� ����, ������ ��� ����� ��������� ������, ���������� ������ �������, ����� �������� ��������� � ����������� ������ ������ � ��������� � ����������� ����� ������. � ����� ������ � ������ ������ ����. ���� �� ������������ ����� ��������� �������, �� �������� ��� ��������� ������ ������, � ���� �� �������������� ����� ���� ������� ��� ������ �����, ����� ��������������� ��������� ����������:

CREATE TABLE "CATALOG5" (
  "ID" INTEGER NOT NULL PRIMARY KEY,
  "NAME" VARCHAR(200) CHARACTER SET WIN1251 NOT NULL,
  "PARENT_ID" INTEGER
    CHECK(
     "PARENT_ID" = ANY(SELECT "ID" FROM "CATALOG") or "PARENT_ID" is NULL
  ),
  "LOW" INTEGER NOT NULL,
  "HIGH" INTEGER NOT NULL
);

������ ��������� �������� ������������ ��������� ��� �������� �������� � �������������� ������� ����������� � ����������� ��������. � ��������� ��������� ���� LOW � HIGH ��� �������� ������ � ����� ��������� ��������� ������ ���� �������� ������� ��������. ����� �������� ����� ���� ������������ ������� �������� (��. �������). ��� ��������� ������ � ����� ������� ���� �������� ������� ��������. ������ ��������� ������� ���������� � ��������� ������ �����.


����, �� ����������� ��������� ��������� ����� �������� ��� �������� ��������. ����� �� ���������� ������� �����, ��������� � �������������� ���� ��������:

��������� ���������������� ��������

��������� �������� �������� �������� �������� ������� ��� ���������� � ����������� ������. ����� �� ���������� ��������� �������� ���:

�������� �� ������� �� ������

� ����� ���� �������� ��������� � ����������� � ���������� ���������� �� ������ ��������, � ����� ��������� � ��������� ������ �����. ��������, ��� � ����� ��������� ��������� �������� ����� ��� ��������, ����������� �� ������ (PARENT_ID �������� ����� ID ��������). ������ �� ������� �������� (����� ������� � ����� ����� �� ����������� ���� ��������) �������� ���:

SELECT "ID" FROM CATALOG WHERE "PARENT_ID" = <�������� id ��������>

�������� � ����������� ��������� �������

� ������ ��������� ��� ����������� �������� ���������� ����� ������� ����������� ������. ���� ������� �����������, ����� ���������� ��� �������, � ������� �������� ���������� � ��������. ������ �� ������� ��������:

SELECT "ID" FROM <��� ������� � ���������> where <������� ������ �� ������> = <������� ��������� ���� ������>

��������, ��� ����������� �������� ���� ������� ������ � ID = 10 � PARENT_ID = 5 ������ �����:

SELECT "ID" FROM CATALOG3_LEVEL3 WHERE "PARENT_ID"=5 AND "PARENT_ID2" = 10

�������� � ����������� ������

��� ��������� � ����������� ������ ������ ���������������� ������� ����� ��������� ����� c ��������� ��������� �������� � ����� ��, ��� ��������� ���� ������ ������ � ������� ��������. � ����� ������������� ���� ������ ������� ������� ��������� �������� (ID = 1) ����� ����� ID 11,21,31,41, .91. ������ �� �������:

SELECT "ID" FROM "CATALOG4" WHERE "ID" IN (11,21,31,41,51,61,71,81,91)

��������� � ����� ������ ��� ������� ��������� �������� (ID = 10000) ������� 11000, 12000,13000.19000.

��������� ���� ��������

�������� ����� ��������� ������ ��������� ����, � ��� ����� � �� ������ �������� ������� ��������. ���������� ������� ���� ������ ��� ����������� ��������.

��������� �� ������� �� ������ � �� ����������� � ���������� ���������� �� ������ ��������

�������� �������, � ���������, ���. ���������� �������������� �������� ��������.

��������� � ����������� ��������� �������

������� ������� �������� ���������� � "�����������" �������� � ����� ��� ����� ��������� ������ �� ������ � ����� �� ����� �������� ID ������. ����� ������ �������� ����� �������� ������������ (UNION) ��������.

select "ID",'1' as "LEVEL" from CATALOG3_LEVEL2 where PARENT_ID = 1
union
select "ID",'2' as "LEVEL" from CATALOG3_LEVEL3 where PARENT_ID = 1

���� ��������������� ���� LEVEL � ������ ���������� ���, ��� ������� �������� � ������ �������� ����� ����� ���������� ID � ��� ����������� �������� ������ ���������� ����� � ���������� ����� �������� ����. ��� ���� ��������, ���������� � ������������� ����� ��������������� ���� � ������, �.�. ���� �����, �� ����� ������� ������ ������ ID.

��������� � ����������� ������

� ������ ��������� ���������� ���������� � ������ ���� � ��������. ��� ��������� ������� ���� ��������.

����� ����

��� ������� ��������� �������� �������� ID �������� ����� 10001. 19999, ��� ������� 20001.29999 � �.�.

������ ����

��, ����� ���� ��� ������. ������ ������� �������� ID = 1, �� ������ ������ ��� ������ ������ 11 � �.�. ����� �������, ������� ����� ����� � ����� ID �����, ����������� � ID ������.

��������� � ��������� ������ �����

�������� ��������� LOW � HIGH ������ ������� ��������� ��������� ������ ���� ��������.

��������� ������ ����������� ��������

����� ������� ����������� �������� �������� �������� � ������-���� ������������������ �������� ���������� �������. ������ ��������� ������ ����������� ������ ����������� ������������� ��������.

��������� �� ������� �� ������, ��������� � ��������� ������ �����

���������� ������� ���� � ����� ������ � ����������� ����� �������. �������� ��������, �� ������� ������� ���.

��������� �� ������� �� ������ � ��������� ������ �����������

������� �� ����� ���� ��� �������� ������ �����������. ���-�� � �������� ������ ��� ����������.

��������� � ����������� ��������� �������

������� ����������� ������������ ��������, � ������� �������� ������ �� ��������.

��������� � ����������� ������

������� ����������� ������������ ���������� ���������� ���������� ������� � �����.

��������� ������� ���� �� �������� �� ����� ��������

��������� �� ������� �� ������ � �� ����������� � ���������� ���������� �� ������ ��������, ��������� � ��������� ������ �����

����� ��, ��� ���������� ������� ���� ����� �������� ������� � ������� ���������������� ��������. ����� ������� �������� ����� �� ��������. ���� �������� ����� �������� ��������� ��������� ������� ���� �� ������������� ��������:

CREATE PROCEDURE GET_PARENTS (ID INTEGER)
RETURNS (E_ID INTEGER, NAME CHAR(200))
AS
declare variable P_ID integer;
BEGIN
  select PARENT_ID from CATALOG where ID = :ID into :ID;
  WHILE (ID > 0) DO
    BEGIN
      SELECT C.ID, C.PARENT_ID, C.NAME
      FROM CATALOG C
      WHERE ID = :ID
      INTO :E_ID, :P_ID,:NAME;
      ID=P_ID;
      SUSPEND;
    END
END ^

��������� � ����������� ��������� �������, ��������� � ����������� ������

������ ���� ���������� � ��������� ����� ��������.

�������� �������, ��������, ����������� �������� � ��� ��������

��������� �� ������� �� ������

���������� ������ ��������:

insert into "CATALOG"("name","parent_id") values( _win1251 '����� �������', <�������� ���������� ����� ������>);

�������� ��������: ����� ��������������� ������ �������� ���������� ������� � ��� ��������. �������� �������� ��������� ��������:

CREATE TRIGGER "CATALOG_AFTER_DEL" FOR "CATALOG"
ACTIVE AFTER DELETE POSITION 0
AS
BEGIN
  delete from  "CATALOG" where "PARENT_ID" = OLD."ID";
END ^

����������� ��������: ���� ������ �������� ������ �� ��������.

UPDATE "CATALOG" SET "PARENT_ID" = <�������� ���������� ����� ������ ��������> WHERE "ID" = <�������� ���������� ����� ��������>

��������� �� ������� �� ������ � ���������� �������

����� ������������ �������, ����������� ������ � ������� ����������. ��� �������� ������������ ���� Level ����� ������ �������������� ��������:

CREATE EXCEPTION "WRONG_LEVEL" '�������� ������� ����������� ��������';
/*
  ������� ����� �������� ������ � ������� - ��������� ������������ ���� Level � ���������� ID ������
*/
CREATE TRIGGER "CATALOG_BEFORE_INS" FOR "CATALOG"
ACTIVE BEFORE INSERT POSITION 0
AS
  declare variable parent_level integer;
BEGIN
   if (NEW."ID" is null) then NEW."ID" =GEN_ID(CATALOG_GEN,1);
   /*�������� �������� ����� ������� 1*/
   if ((NEW."PARENT_ID" is NULL) and (NEW."LEVEL" <> 1)) then
     exception WRONG_LEVEL;
   /*�������� ���� Level ��� ���������� ��������� ������ ���� �� 1 ������, ��� � �� ��������*/
   if (NEW."PARENT_ID" is NOT NULL) THEN
   begin
     select "LEVEL" from "CATALOG" WHERE "ID" = NEW."PARENT_ID" into :parent_level;
     if (NEW."LEVEL" <> :parent_level+1) then
       exception WRONG_LEVEL;
   end
END ^
/*
  ������� ����� ����������� - ������������ ������������ ���� Level
*/
CREATE TRIGGER "CATALOG_BEFORE_UPD" FOR "CATALOG"
ACTIVE BEFORE UPDATE POSITION 0
AS
  declare variable parent_level integer;
  declare variable child_id integer;
BEGIN
   if ((NEW."PARENT_ID" is NULL) and (NEW."LEVEL" <> 1)) then
     exception WRONG_LEVEL;
  select "LEVEL" from "CATALOG" WHERE "ID" = NEW."PARENT_ID" into :parent_level;
  if (NEW."LEVEL" <> :parent_level+1) then
    exception WRONG_LEVEL;
    
END ^
/*
  ������� ����� ���������� - ������������ ������������ ���� Level
*/
CREATE TRIGGER "CATALOG_AFTER_UPD" FOR "CATALOG"
ACTIVE AFTER UPDATE POSITION 0
AS
BEGIN
  update "CATALOG" set "LEVEL" = NEW."LEVEL"+1 where "PARENT_ID" = NEW."ID";
END ^

��������� � ����������� ��������� �������

������� �� ������� � ����������� ����������, � ������ �� ����������. ��� �������� �������� ����� ������ �������������� ������� ��� �������� ��������, ���������� �������� ��� ��������� �� ������� �� ������.

��������� � ��������� ������ �����

������� � �������� ���������� ������ ��������� �� ������� �� ������. ����������� �������� � ����� ������ ���������� ��� ������������� ��������� ������ ���������, ������� ����������� �����.

����������

�� ���, �������, � ���. �������, ��� ������ ������ ����� ��� �������. ���� � ��� ��������� ���������, ����������� ��� �� ���������� �����-���� ������, ������ ��� mgoblin@mail.ru


��� ������ ������������ � ������� RSDN Magazine



������:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
�������:

�������� �� �����
���������� �� ���������
Created 1996-2026 by Maxim Chirkov
��������, ����������, ����������