Использование динамического sql в процедуре для создания схем и таблиц - PullRequest
0 голосов
/ 14 марта 2019

Мне было поручено создать образец базы данных, в которой будут храниться данные из 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 голосов
/ 15 марта 2019

ОК, исправлены все ошибки, неправильный синтаксис и неуникальные имена.все лучше.добавил немного обработки ошибок.Надеюсь, что это поможет вам снова.

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'

0 голосов
/ 14 марта 2019

Переместите переменную 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'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...