在过程中使用动态sql创建模式和表

时间:2019-03-14 18:49:24

标签: sql-server tsql dynamic-sql

我的任务是创建一个示例数据库,该数据库存储我学院的15个校区的数据。每个园区的数据必须与其余园区分开(使用模式),并且每个模式必须具有相同的表和列。这是必须使用动态sql的地方(如作业中所述)。

以下代码段演示了我的努力(请记住,我还是新手):

USE master
GO
CREATE DATABASE CTUDB
GO
USE CTUDB
GO

CREATE PROCEDURE AddCampus_proc(@campus varchar(50))
AS
DECLARE @DynamicSQL varchar(MAX)
BEGIN
SET @DynamicSQL = 'CREATE schema ['+@campus+']'
EXEC (@DynamicSQL)

SET @DynamicSQL = 'CREATE table ['+@campus+'].Student_tbl(
StudentID number(4,0) not null,
Name varchar(50) not null,
Surname varchar(50) not null,
ID_Number number(13,0) not null,
Address varchar(100) not null,
PRIMARY KEY (StudentID),
CONSTRAINT CheckStudentID check (length(StudentID) = 4),
CONSTRAINT CheckIDNumber check (length(ID_Number) = 13)
);'
EXEC (@DynamicSQL)

SET @DynamicSQL = 'CREATE table ['+@campus+'].Course_tbl(
CourseID integer not null,
CourseName varchar(50) not null,
Description varchar(100) not null,
StudentID number(4,0) not null,
PRIMARY KEY (CourseID),
FOREIGN KEY (StudentID) REFERENCES Student_tbl(StudentID),
CONSTRAINT CheckStudentID check (length(StudentID) = 4)
);'
EXEC (@DynamicSQL)

SET @DynamicSQL = 'CREATE table ['+@campus+'].ClassMarks_tbl(
ClassMarksID integer not null,
StudentID number(4,0) not null,
CourseID integer not null,
Semester1_Mark1 integer not null check (Semester1_Mark1 between 0 and 100),
Semester1_Mark2 integer not null check (Semester1_Mark2 between 0 and 100),
Semester1_Mark3 integer not null check (Semester1_Mark3 between 0 and 100),
Semester1_Average integer not null check (Semester1_Average between 0 and 100),
Semester1_Test_Mark integer not null check (Semester1_Test_Mark between 0 and 100),
Semester2_Mark1 integer not null check (Semester2_Mark1 between 0 and 100),
Semester2_Mark2 integer not null check (Semester2_Mark2 between 0 and 100),
Semester2_Mark3 integer not null check (Semester2_Mark3 between 0 and 100),
Semester2_Average integer not null check (Semester2_Average between 0 and 100),
Semester2_Test_Mark integer not null check (Semester2_Test_Mark between 0 and 100),
PRIMARY KEY (ClassMarksID),
FOREIGN KEY StudentID REFERENCES Student_tbl(StudentID),
FOREIGN KEY CourseID REFERENCES Course_tbl(CourseID),
CONSTRAINT CheckStudentID check (length(StudentID) = 4)
);'
EXEC (@DynamicSQL)

SET @DynamicSQL = 'CREATE table ['+@campus+'].Facilitator_tbl(
FacilitatorID integer not null,
Name varchar(50) not null,
Surname varchar(50) not null,
Address varchar(100) not null,
Paycheck deciaml(19,4) not null,
CourseID integer not null,
PRIMARY KEY (FacilitatorID),
FOREIGN KEY CourseID REFERENCES Course_tbl(CourseID)
);'
EXEC (@DynamicSQL)

SET @DynamicSQL = 'CREATE table ['+@campus+'].Parents_tbl(
ParentID integer not null,
Name varchar(50) not null,
Surname varchar(50) not null,
ID_Number number(13,0) not null,
StudentID number(4,0) not null,
PRIMARY KEY (ParentID),
FOREIGN KEY StudentID REFERENCES Student_tbl(StudentID),
CONSTRAINT StudentID check (length(StudentID) = 4)
);'
EXEC (@DynamicSQL)
END

EXEC AddCampus_proc 'Nelspruit'
EXEC AddCampus_proc 'Roodepoort'
EXEC AddCampus_proc 'Sandton'
EXEC AddCampus_proc 'Boksburg'
EXEC AddCampus_proc 'Pretoria'
EXEC AddCampus_proc 'Cape_Town'
EXEC AddCampus_proc 'Vereniging'
EXEC AddCampus_proc 'Bloemfontein'
EXEC AddCampus_proc 'Polokwane'
EXEC AddCampus_proc 'Durban'
EXEC AddCampus_proc 'Stellenbosch'
EXEC AddCampus_proc 'Port_Elizabeth'
EXEC AddCampus_proc 'Pochefstroom'
EXEC AddCampus_proc 'Auckland_Park'

查询已成功执行,但问题是实际上并未创建模式和表:

未创建表

No tables were created

未创建任何模式

No schemas were created

我的问题是,为什么不创建表和模式?我推断是由于动态sql造成的,因为它可能是错误的,但是我不明白为什么在这种情况下查询才能成功执行。

2 个答案:

答案 0 :(得分:0)

DECLARE @DynamicSQL varchar(MAX)变量移到存储过程的begin end块旁边:

CREATE PROCEDURE AddCampus_proc(@campus varchar(50))
AS
BEGIN
    DECLARE @DynamicSQL varchar(MAX)
    SET @DynamicSQL = 'CREATE schema ['+@campus+']'

    PRINT (@DynamicSQL)

    -- more T-SQL code

    EXEC (@DynamicSQL)
END

EXEC AddCampus_proc 'Nelspruit'

答案 1 :(得分:0)

好的,修复了所有拼写错误,语法错误和名称不唯一的问题。都更好。 添加了一些错误处理。希望它能使您再次走下去。

USE master
GO
if not exists (select 1 from master.sys.databases where name = 'CTUDB')
CREATE DATABASE CTUDB
GO
USE CTUDB
GO
if object_id('AddCampus_proc','P') is not null
    begin
        drop proc AddCampus_proc;
    end;
GO
CREATE PROCEDURE AddCampus_proc(@campus varchar(50)
)
AS
BEGIN
DECLARE @DynamicSQL varchar(MAX)
SET @DynamicSQL = 'CREATE schema '+quotename(@campus)+''
begin try
    EXEC (@DynamicSQL);
end try
begin catch
    if error_number() <> 2759 --this just means the schema already exists.
        begin
            print(error_number())
            print(error_message())
        end
end catch

SET @DynamicSQL = 'CREATE table '+quotename(@campus)+'.Student_tbl(
StudentID numeric(4,0) not null PRIMARY KEY,
Name varchar(50) not null,
Surname varchar(50) not null,
ID_numeric numeric(13,0) not null,
Address varchar(100) not null,
CONSTRAINT '+@campus+'_Student_tbl_CheckStudentID check (len(StudentID) = 4),
CONSTRAINT '+@campus+'_Student_tbl_CheckIDnumeric check (len(ID_numeric) = 13)
);'
--print (@DynamicSQL);
EXEC (@DynamicSQL);

SET @DynamicSQL = 'CREATE table '+quotename(@campus)+'.Course_tbl(
CourseID integer not null PRIMARY KEY,
CourseName varchar(50) not null,
Description varchar(100) not null,
StudentID numeric(4,0) not null,
FOREIGN KEY (StudentID) REFERENCES ' + quotename(@campus) + '.Student_tbl(StudentID),
CONSTRAINT '+@campus+'_Course_tbl_CheckStudentID check (len(StudentID) = 4)
);'
--print (@DynamicSQL);
EXEC (@DynamicSQL);

SET @DynamicSQL = 'CREATE table '+quotename(@campus)+'.ClassMarks_tbl(
ClassMarksID integer not null PRIMARY KEY,
StudentID numeric(4,0) not null,
CourseID integer not null,
Semester1_Mark1 integer not null check (Semester1_Mark1 between 0 and 100),
Semester1_Mark2 integer not null check (Semester1_Mark2 between 0 and 100),
Semester1_Mark3 integer not null check (Semester1_Mark3 between 0 and 100),
Semester1_Average integer not null check (Semester1_Average between 0 and 100),
Semester1_Test_Mark integer not null check (Semester1_Test_Mark between 0 and 100),
Semester2_Mark1 integer not null check (Semester2_Mark1 between 0 and 100),
Semester2_Mark2 integer not null check (Semester2_Mark2 between 0 and 100),
Semester2_Mark3 integer not null check (Semester2_Mark3 between 0 and 100),
Semester2_Average integer not null check (Semester2_Average between 0 and 100),
Semester2_Test_Mark integer not null check (Semester2_Test_Mark between 0 and 100),
FOREIGN KEY (StudentID) REFERENCES ' + quotename(@campus) + '.Student_tbl(StudentID),
FOREIGN KEY (CourseID) REFERENCES ' + quotename(@campus) + '.Course_tbl(CourseID),
CONSTRAINT '+@campus+'_ClassMarks_tbl_CheckStudentID check (len(StudentID) = 4)
);'
--print (@DynamicSQL);
EXEC (@DynamicSQL);

SET @DynamicSQL = 'CREATE table '+quotename(@campus)+'.Facilitator_tbl(
FacilitatorID integer not null PRIMARY KEY,
Name varchar(50) not null,
Surname varchar(50) not null,
Address varchar(100) not null,
Paycheck decimal(19,4) not null,
CourseID integer not null,
FOREIGN KEY (CourseID) REFERENCES ' + quotename(@campus) + '.Course_tbl(CourseID)
);'
--print (@DynamicSQL);
EXEC (@DynamicSQL);

SET @DynamicSQL = 'CREATE table '+quotename(@campus)+'.Parents_tbl(
ParentID integer not null PRIMARY KEY,
Name varchar(50) not null,
Surname varchar(50) not null,
ID_numeric numeric(13,0) not null,
StudentID numeric(4,0) not null,
FOREIGN KEY (StudentID) REFERENCES ' + quotename(@campus) + '.Student_tbl(StudentID),
CONSTRAINT '+@campus+'_Parents_tbl_StudentID check (len(StudentID) = 4)
);'
--print (@DynamicSQL);
EXEC (@DynamicSQL);
END
GO
EXEC AddCampus_proc 'Nelspruit'
EXEC AddCampus_proc 'Roodepoort'
EXEC AddCampus_proc 'Sandton'
EXEC AddCampus_proc 'Boksburg'
EXEC AddCampus_proc 'Pretoria'
EXEC AddCampus_proc 'Cape_Town'
EXEC AddCampus_proc 'Vereniging'
EXEC AddCampus_proc 'Bloemfontein'
EXEC AddCampus_proc 'Polokwane'
EXEC AddCampus_proc 'Durban'
EXEC AddCampus_proc 'Stellenbosch'
EXEC AddCampus_proc 'Port_Elizabeth'
EXEC AddCampus_proc 'Pochefstroom'
EXEC AddCampus_proc 'Auckland_Park'