在创建模式和表的过程中使用动态 sql
Using dynamic sql in a procedure to create schemas and tables
我的任务是创建一个示例数据库,用于存储我学院 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'
查询成功执行,但问题是模式和表实际上并未创建:
没有创建表
没有创建架构
我的问题是,为什么没有创建表和模式?我推断这是因为动态 sql 因为它可能是错误的,但我不明白为什么在这种情况下查询会成功执行。
将 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'
好的,修复了所有的拼写错误、不正确的语法和不唯一的名称。一切都好
添加了一些错误处理。希望它能让你再次出发。
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'
我的任务是创建一个示例数据库,用于存储我学院 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'
查询成功执行,但问题是模式和表实际上并未创建:
没有创建表
没有创建架构
我的问题是,为什么没有创建表和模式?我推断这是因为动态 sql 因为它可能是错误的,但我不明白为什么在这种情况下查询会成功执行。
将 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'
好的,修复了所有的拼写错误、不正确的语法和不唯一的名称。一切都好 添加了一些错误处理。希望它能让你再次出发。
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'