表定義:
CREATE TABLE Programs (
ID INT NOT NULL PRIMARY KEY IDENTITY(1,1),
Name varchar(50)
);
CREATE TABLE Modules (
ID INT NOT NULL PRIMARY KEY IDENTITY(1,1),
ProgramID INT,
Name varchar(50)
);
CREATE TABLE Classes (
ID INT NOT NULL PRIMARY KEY IDENTITY(1,1),
ModuleID INT,
Name varchar(50)
);
CREATE TABLE Functions (
ID INT NOT NULL PRIMARY KEY IDENTITY(1,1),
ClassID INT,
Name varchar(50)
);
タイプ定義:
CREATE TYPE ProgramTableType AS TABLE
(
Program varchar(50),
Module varchar(50),
Class varchar(50),
Func varchar(50)
);
プロシージャ定義:
CREATE PROCEDURE dbo.sp_insert_definitions
@NewRows ProgramTableType READONLY
AS
SET NOCOUNT ON;
DECLARE cur_new CURSOR FOR
SELECT Program, Module, Class, Func
FROM @NewRows
ORDER BY Program, Module, Class, Func;
DECLARE
-- Cache variables
@ProgramID int,
@ProgramName varchar(50) = NULL,
@ModuleID int,
@ModuleName varchar(50) = NULL,
@ClassID int,
@ClassName varchar(50) = NULL,
-- Iteration variables
@Program varchar(50),
@Module varchar(50),
@Class varchar(50),
@Func varchar(50);
OPEN cur_new;
FETCH NEXT FROM cur_new
INTO @Program, @Module, @Class, @Func;
-- Loop trough the cursor
WHILE @@FETCH_STATUS = 0
BEGIN
-- Get or create program
IF @ProgramName IS NULL OR @Program <> @ProgramName
BEGIN
IF NOT EXISTS (SELECT NULL FROM Programs WHERE Name = @Program)
INSERT INTO Programs (Name)
VALUES (@Program);
SELECT
@ProgramID = ID,
@ProgramName = Name,
@ModuleID = NULL,
@ModuleName = NULL,
@ClassID = NULL,
@ClassName = NULL
FROM Programs
WHERE Name = @Program;
END
-- Get or create module
IF @ModuleName IS NULL OR @Module <> @ModuleName
BEGIN
IF NOT EXISTS (SELECT NULL FROM Modules WHERE Name = @Module AND ProgramID = @ProgramID)
INSERT INTO Modules (ProgramID, Name)
VALUES (@ProgramID, @Module);
SELECT
@ModuleID = ID,
@ModuleName = Name,
@ClassID = NULL,
@ClassName = NULL
FROM Modules
WHERE Name = @Module
AND ProgramID = @ProgramID;
END;
-- Get or create class
IF @ClassName IS NULL OR @Class <> @ClassName
BEGIN
IF NOT EXISTS (SELECT NULL FROM Classes WHERE Name = @Class AND ModuleID = @ModuleID)
INSERT INTO Classes (ModuleID, Name)
VALUES (@ModuleID, @Class);
SELECT
@ClassID = ID,
@ClassName = Name
FROM Classes
WHERE Name = @Class
AND ModuleID = @ModuleID;
END;
-- Create function if it doesn't exists
IF NOT EXISTS (SELECT NULL FROM Functions WHERE Name = @Func AND ClassID = @ClassID)
INSERT INTO Functions (ClassID, Name)
VALUES (@ClassID, @Func);
FETCH NEXT FROM cur_new
INTO @Program, @Module, @Class, @Func;
END
CLOSE cur_new;
DEALLOCATE cur_new;
GO
例:
BEGIN TRAN;
DECLARE @NewData AS ProgramTableType;
INSERT INTO @NewData (Program, Module, Class, Func)
VALUES ('Program1', 'M1', 'C1', 'Func1'),
('Program1', 'M1', 'C1', 'Func2'),
('Program1', 'M1', 'C2', 'Func3'),
('Program1', 'M2', 'C3', 'Func4'),
('Program1', 'M2', 'C4', 'Func5'),
('Program2', 'M3', 'C5', 'Func6'),
('Program2', 'M3', 'C5', 'Func7'),
('Program2', 'M3', 'C6', 'Func8'),
('Program2', 'M4', 'C7', 'Func9'),
('Program2', 'M4', 'C7', 'Func10'),
('Program2', 'M4', 'C8', 'Func11');
EXEC sp_insert_definitions @NewData;
COMMIT TRAN;
は、元の入力を取得します:
SELECT p.Name AS Program, m.Name AS Module, c.Name AS Class, f.Name AS [Function]
FROM Functions f
INNER JOIN Classes c ON c.ID = f.ClassID
INNER JOIN Modules m ON m.ID = c.ModuleID
INNER JOIN Programs p ON p.ID = m.ProgramID;
も参照してください
編集:それは間違っていたので、私は、全体の答えを書き直しました。
これは特定のデータベース用ですか、ポータブルである必要がありますか? –
SQL Server 2008だけの質問が更新されました。 – Icerman