|
|
su.dbms.sql- SU.DBMS.SQL ------------------------------------------------------------------ From : Akzhan Abdulin 2:5030/217 17 Feb 2001 15:42:47 To : All Subject : деревья --------------------------------------------------------------------------------
В пpинципе, я пользуюсь подходом Ильи Звягина и Анатолия Тенцеpа -
дополнительная таблица.
Я лишь поделюсь фактическими скpиптами:
Это основа:
=== Cut ===
-- здесь часть FOREIGN KEY CONSTRAINT's на самом деле используют DRI
-- это таблица "Произвольный счёт"
CREATE TABLE [ACustomAccount] (
[Id] [AnAccountId] IDENTITY (1, 1) NOT NULL ,
[IsRoot] [AnUnorderedBoolean] NOT NULL CONSTRAINT [Set_to_false3] DEFAULT (0),
[IsSub] [AnUnorderedBoolean] NOT NULL CONSTRAINT [Set_to_false4] DEFAULT (0),
[IsFolder] [AnUnorderedBoolean] NOT NULL CONSTRAINT [Set_to_false5] DEFAULT
(0),
[IsLeaf] [AnUnorderedBoolean] NOT NULL CONSTRAINT [Set_to_false6] DEFAULT (0),
CONSTRAINT [XPKACustomAccount] PRIMARY KEY CLUSTERED
(
[Id]
) ON [PRIMARY]
) ON [PRIMARY]
GO
-- некоторые счета являются счетами-папками
CREATE TABLE [AFolderAccount] (
[Id] [int] NOT NULL ,
CONSTRAINT [XPKAFolderAccount] PRIMARY KEY CLUSTERED
(
[Id]
) ON [PRIMARY] ,
CONSTRAINT [aca_is_afa] FOREIGN KEY
(
[Id]
) REFERENCES [ACustomAccount] (
[Id]
)
) ON [PRIMARY]
GO
-- а в папках содержатся подсчета
CREATE TABLE [ASubAccount] (
[Id] [int] NOT NULL ,
[FolderAccountId] [int] NOT NULL ,
[Code] [AnAccountCode] NOT NULL ,
CONSTRAINT [XPKASubAccount] PRIMARY KEY NONCLUSTERED
(
[Id]
) ON [PRIMARY] ,
CONSTRAINT [XAKSubAccountCode] UNIQUE NONCLUSTERED
(
[FolderAccountId],
[Code]
) ON [PRIMARY] ,
CONSTRAINT [aca_is_asa] FOREIGN KEY
(
[Id]
) REFERENCES [ACustomAccount] (
[Id]
),
CONSTRAINT [contain_subaccounts] FOREIGN KEY
(
[FolderAccountId]
) REFERENCES [AFolderAccount] (
[Id]
),
CONSTRAINT [IsValidAccountCode34] CHECK (not([Code] like '%\%'))
) ON [PRIMARY]
GO
-- существует также понятие счетов, являющихся корнями деревьев счетов
CREATE TABLE [ARootAccount] (
[Id] [int] NOT NULL ,
[Code] [AnAccountCode] NOT NULL ,
CONSTRAINT [XPKARootAccount] PRIMARY KEY CLUSTERED
(
[Id]
) ON [PRIMARY] ,
CONSTRAINT [XAKRootAccountCode] UNIQUE NONCLUSTERED
(
[Code]
) ON [PRIMARY] ,
CONSTRAINT [aca_is_ara] FOREIGN KEY
(
[Id]
) REFERENCES [ACustomAccount] (
[Id]
),
CONSTRAINT [IsValidAccountCode33] CHECK (not([Code] like '%\%'))
) ON [PRIMARY]
GO
-- а это вспомогательная таблица
CREATE TABLE [AnAccountAndItsAncestors] (
[AncestorId] [int] NOT NULL ,
[AccountId] [int] NOT NULL ,
CONSTRAINT [XPKAnAccountAndItsAncestors] PRIMARY KEY CLUSTERED
(
[AncestorId],
[AccountId]
) ON [PRIMARY] ,
CONSTRAINT [account_under_ancestors] FOREIGN KEY
(
[AccountId]
) REFERENCES [ACustomAccount] (
[Id]
),
CONSTRAINT [is_ancestor_of] FOREIGN KEY
(
[AncestorId]
) REFERENCES [ACustomAccount] (
[Id]
)
) ON [PRIMARY]
GO
-- эта процедура создаёт произвольный счёт
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE akCreateACustomAccount @Id AnAccountId OUTPUT, @CheckRights
BIT = 1
AS
BEGIN
/* initialize execution state */
DECLARE @Result INT
SET NOCOUNT ON
SET @Result = 0
SET @Id = -1
BEGIN TRANSACTION
IF (@CheckRights = 1) AND (dbo.akHasConstraint('Accounting:Plan:Change') = 0)
BEGIN
SET @Result = -100
GOTO fin
END
INSERT
INTO ACustomAccount
DEFAULT VALUES
SET @Result = @@ERROR
IF @Result = 0
BEGIN
SET @Id = @@IDENTITY
INSERT
INTO AnAccountAndItsAncestors(AccountId, AncestorId)
VALUES(@Id, @Id)
SET @Result = @@ERROR
END
/* finalize transaction */
fin:
IF @@TRANCOUNT > 0
BEGIN
IF @Result <> 0 ROLLBACK TRANSACTION ELSE COMMIT TRANSACTION
END
RETURN @Result
END
-- эта процедура обновляет вспомогательную таблицу для одного подсчёта при его
создании
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE akUpdateSingleSubAccountAncestors @AccountId AnAccountId
AS
BEGIN
/* initialize execution state */
DECLARE @Result INT
SET NOCOUNT ON
SET @Result = 0
BEGIN TRANSACTION
IF NOT EXISTS(SELECT TOP 1 * FROM AnAccountAndItsAncestors WHERE (AncestorId
= @AccountId) AND (AccountId = @AccountId))
BEGIN
INSERT
INTO AnAccountAndItsAncestors(AccountId, AncestorId)
VALUES(@AccountId, @AccountId)
SET @Result = @@ERROR
IF @Result <> 0 GOTO fin
END
INSERT
INTO AnAccountAndItsAncestors(AccountId, AncestorId)
SELECT @AccountId, AAIA.AncestorId FROM AnAccountAndItsAncestors AAIA INNER
JOIN ASubAccount SA ON (AAIA.AccountId = SA.FolderAccountId) WHERE SA."Id" =
@AccountId
SET @Result = @@ERROR
/* finalize transaction */
fin:
IF @@TRANCOUNT > 0
BEGIN
IF @Result <> 0 ROLLBACK TRANSACTION ELSE COMMIT TRANSACTION
END
RETURN @Result
END
GO
=== Cut ===
Akzhan
--- FMail/Win32 1.42/g
* Origin: MT Computers, mailto:akzhan@mtgroup.ru (2:5030/217)
Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /su.dbms.sql/22713a8e914e.html, оценка из 5, голосов 10
|