表定義:
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;
也
編輯請參見:我重寫了全部答案,因爲它是不正確的。
這是針對特定的數據庫,還是您要求它是便攜式的? – 2012-03-26 06:04:47
更新後的問題,僅適用於SQL Server 2008. – Icerman 2012-03-26 06:30:03