Using dynamic sql in a procedure to create schemas and tables

好久不见. 提交于 2019-12-13 03:19:26

问题


I've been tasked with creating a sample database that stores data from my college's 15 campuses. The data from each campus must be separate from the rest (with the use of schemas) and each schema must have the same tables and columns. This is where dynamic sql has to be used (as stated in the assignment).

The following code snippet demonstrates my efforts (bare in mind that I'm still new to this):

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'

The query gets executed successfully but the problem is that the schemas and tables are not actually being created:

No tables were created

No schemas were created

My question is, why are the tables and schemas not being created? I deduced that it is because of the dynamic sql as it may be wrong, but I don't understand why the query executes successfully if that is the case.


回答1:


ok, fixed all the misspellings, incorrect syntax and non-unique names. all better. added a bit of error handling. hope it gets you going again.

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'




回答2:


Move the DECLARE @DynamicSQL varchar(MAX) variable in side the begin end block of the stored procedure:

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'


来源:https://stackoverflow.com/questions/55169997/using-dynamic-sql-in-a-procedure-to-create-schemas-and-tables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!