-- Write SQL scripts that: -- a. modify the type of a column; -- b. add / remove a column; -- c. add / remove a DEFAULT constraint; -- d. add / remove a primary key; -- e. add / remove a candidate key; -- f. add / remove a foreign key; -- g. create / drop a table. -- For each of the scripts above, write another one that reverts the operation. Place each script in a stored procedure. Use a simple, intuitive naming convention. -- a. modify the type of a column; CREATE PROCEDURE setNameToVarChar100 AS BEGIN ALTER TABLE Decks ALTER COLUMN name VARCHAR(100) END GO CREATE PROCEDURE setNameToVarChar255 AS BEGIN ALTER TABLE Decks ALTER COLUMN name VARCHAR(255) END GO -- b. add / remove a column; CREATE PROCEDURE addColumnDescription AS BEGIN ALTER TABLE Decks ADD description VARCHAR(255) END GO CREATE PROCEDURE removeColumnDescription AS BEGIN ALTER TABLE Decks DROP COLUMN description END GO -- c. add / remove a DEFAULT constraint; CREATE PROCEDURE addDefaultToDescription AS BEGIN ALTER TABLE Decks ADD CONSTRAINT DF_Decks_description DEFAULT 'No description' FOR description END GO CREATE PROCEDURE removeDefaultFromDescription AS BEGIN ALTER TABLE Decks DROP CONSTRAINT DF_Decks_description END GO -- d. add / remove a primary key; CREATE PROCEDURE removePrimaryKeyFromJournalProgress AS BEGIN ALTER TABLE JourneyProgress DROP CONSTRAINT PK__JourneyP__2FA1EA2E0A91C8BD END GO CREATE PROCEDURE addPrimaryKeyToJournalProgress AS BEGIN ALTER TABLE JourneyProgress ADD CONSTRAINT PK__JourneyP__2FA1EA2E0A91C8BD PRIMARY KEY(hJourney, hPlayer) END GO -- e. add / remove a candidate key; CREATE PROCEDURE addCandidateKeyToDecks AS BEGIN ALTER TABLE Decks ADD CONSTRAINT CK_Decks_name UNIQUE(name) END GO CREATE PROCEDURE removeCandidateKeyFromDecks AS BEGIN ALTER TABLE Decks DROP CONSTRAINT CK_Decks_name END GO -- f. add / remove a foreign key; CREATE PROCEDURE removeForeignKeyFromJourneyProgress AS BEGIN ALTER TABLE JourneyProgress DROP CONSTRAINT FK__JourneyPr__hPlay__031C6FA4 END GO CREATE PROCEDURE addForeignKeyToJourneyProgress AS BEGIN ALTER TABLE JourneyProgress ADD CONSTRAINT FK__JourneyPr__hPlay__031C6FA4 FOREIGN KEY(hPlayer) REFERENCES Players(hmy) END GO -- g. create / drop a table. CREATE PROCEDURE createTableSkillTree AS BEGIN CREATE TABLE SkillTree( hmy INT NOT NULL IDENTITY(1,1) PRIMARY KEY, name VARCHAR(255) NOT NULL, description VARCHAR(8000) NOT NULL, hFaction INT NOT NULL references Factions(hmy), hPlayer INT NOT NULL references Players(hmy), ) END GO CREATE PROCEDURE dropTableSkillTree AS BEGIN DROP TABLE SkillTree END GO CREATE TABLE versionTable( version INT NOT NULL ) CREATE TABLE proceduresTable( fromVersion INT NOT NULL, toVersion INT NOT NULL, procedureName VARCHAR(255) NOT NULL PRIMARY KEY(fromVersion, toVersion) ) INSERT INTO versionTable(version) VALUES(1) INSERT INTO proceduresTable(fromVersion, toVersion, procedureName) VALUES (1, 2, 'setNameToVarChar100'), (2, 1, 'setNameToVarChar255'), (2, 3, 'addColumnDescription'), (3, 2, 'removeColumnDescription'), (3, 4, 'addDefaultToDescription'), (4, 3, 'removeDefaultFromDescription'), (4, 5, 'removePrimaryKeyFromJournalProgress'), (5, 4, 'addPrimaryKeyToJournalProgress'), (5, 6, 'addCandidateKeyToDecks'), (6, 5, 'removeCandidateKeyFromDecks'), (6, 7, 'removeForeignKeyFromJourneyProgress'), (7, 6, 'addForeignKeyToJourneyProgress'), (7, 8, 'createTableSkillTree'), (8, 7, 'dropTableSkillTree') GO CREATE PROCEDURE VersionSelector(@newVersion int) AS BEGIN TRANSACTION versionControl BEGIN TRY DECLARE @currentVersion int DECLARE @procedureName VARCHAR(255) SET @currentVersion = (SELECT version FROM versionTable) IF @newVersion > (SELECT MAX(toVersion) FROM proceduresTable) RAISERROR('Invalid version', 16, 1) IF @newVersion < (SELECT MIN(toVersion) FROM proceduresTable) RAISERROR('Invalid version', 16, 1) WHILE @currentVersion > @newVersion BEGIN SET @procedureName = (SELECT procedureName FROM proceduresTable WHERE fromVersion = @currentVersion AND toVersion = @currentVersion - 1) EXEC @procedureName SET @currentVersion = @currentVersion - 1 END WHILE @currentVersion < @newVersion BEGIN SET @procedureName = (SELECT procedureName FROM proceduresTable WHERE fromVersion = @currentVersion AND toVersion = @currentVersion + 1) EXEC @procedureName SET @currentVersion = @currentVersion + 1 END UPDATE versionTable SET version = @newVersion COMMIT TRANSACTION versionControl END TRY BEGIN CATCH ROLLBACK TRANSACTION versionControl PRINT ERROR_PROCEDURE() PRINT ERROR_MESSAGE() END CATCH EXECUTE VersionSelector 1