这里的存储过程定义有什么问题?

时间:2016-01-18 05:26:03

标签: sql sql-server tsql stored-procedures database-design

我有20个错误,但我列出了3个,也许你可以帮助我理解我在尝试根据文档https://msdn.microsoft.com/en-us/library/ms345415.aspx编写存储过程时总体上做错了什么。

完整代码:

CREATE DATABASE JsPracticeDb; 
/* Create tables corresponding to the problems, solutions to 
   problems, and ratings of problems or solutions */
GO

USE[JsPracticeDb]
Go

/* Table representing JavaScript problems. The promp_code 
   is the HTML that formats the JS code for the view. */
CREATE TABLE Problems 
( 
    id INT PRIMARY KEY IDENTITY(1,1) NOT NULL, 
    prompt_code VARCHAR(5000) NOT NULL,
    created DATETIME DEFAULT CURRENT_TIMESTAMP
);

/* Create sprocs for adding and deleting problems */
GO
CREATE PROC AddProblem  
    @prompt_code VARCHAR(5000) 
AS 
    INSERT INTO Problems (@prompt_code)
GO

CREATE PROC DeleteProblem
    @id INT
AS
    DELETE FROM Problems WHERE id=@id
GO  

/* Table representing JavaScript solutions (in formatted HTML),
   associated solvers and code that tests validity of solutions */
CREATE TABLE Solutions 
(
   id INT PRIMARY KEY IDENTITY(1,1) NOT NULL, 
   problem_id INT NOT NULL,
   solver VARCHAR(50),
   solution_code VARCHAR(5000),
   test_code VARCHAR(8000),
   FOREIGN KEY (problem_id) REFERENCES Problems(id) ON DELETE CASCADE,
   created DATETIME DEFAULT CURRENT_TIMESTAMP
);

/* Create PROCEDURE for adding and deleting solutions */
GO
CREATE PROC AddSolution
    @problem_id INT,
    @solver VARCHAR(50),
    @solution_code VARCHAR(5000),
    @test_code VARCHAR(8000)
AS  
    INSERT INTO Solutions (@problem_id, @solver, @solution_code, @test_code)
GO

CREATE PROC DeleteSolution 
    @id INT 
AS
    DELETE FROM Solutions WHERE id=@id

/* Table representing 0-5 star rating of associated solutions */
CREATE TABLE Ratings 
(
    id INT PRIMARY KEY IDENTITY(1,1) NOT NULL,
    solution_id INT NOT NULL,
    stars TINYINT NOT NULL,
    FOREIGN KEY (solution_id) REFERENCES Solutions(id) ON DELETE CASCADE
);
/* Create sproc for adding ratings */
GO

CREATE PROCEDURE AddRating
    @solution_id INT,
    @stars TINYINT 
AS
    INSERT Into Ratings (@solution_id, @stars)
GO

/* Table representing comments on solutions or comments on coments, and
   the associated commenter. The association of comments on comments is 
   mapped in the next table, CommentPaths   */
CREATE TABLE Comments 
(
    id INT PRIMARY KEY IDENTITY(1,1) NOT NULL,
    solution_id INT NOT NULL,
    commenter VARCHAR(50),
    cmnt VARCHAR(2000) NOT NULL,
    created DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (solution_id) REFERENCES Solutions(id) ON DELETE CASCADE
);

/* Create sprocs for adding and deleting comments 
CREATE PROCEDURE AddComment
    @solution_id INT NOT NULL,
    @commenter VARCHAR(50),
    @cmnt VARCHAR(2000) NOT NULL,
    @parent_id \
AS 
    INSERT INTO Comments (@solution_id, @commenter, @cmnt)
   Still implementing   
*/

CREATE PROCEDURE DeleteComment 
    @id
AS 
    DELETE FROM Comments WHERE id=@id
GO

/* Closure Table for comment tree, e.g.

                         Comments
    ==================================================
    id | solution_id | commenter | comment | created
    --------------------------------------------------
    1  |    1        | ......... | .....   | ......
    2  |    1        | ......... | .....   | ......
    3  |    1        | ......... | .....   | ......
    4  |    1        | ......... | .....   | ......    
    5  |    2        | ......... | .....   | ......    
    6  |    2        | ......... | .....   | ...... 


                      CommentPaths 
                ========================
                 ancestor | descendant
                ------------------------
                    1     |     2
                    1     |     3 
                    1     |     4
                    2     |     4
                    5     |     6

corresponds to the Comments ids being related
to each other like

                1       5
               / \      |
              2   3     6
             /
            4

 */
CREATE TABLE CommentPaths 
(
    ancestor_id INT NOT NULL,
    descendant_id INT NOT NULL,
    PRIMARY KEY (ancestor_id, descendant_id),
    FOREIGN KEY (ancestor_id) REFERENCES Comments(id) ON CASCADE DELETE,
    FOREIGN KEY (descendant_id) REFERENCES Comments(id)
);

/* sproc called on delete of a comment to delete descendant comments
   The references to the descendant comments in CommentPaths */
GO
CREATE PROC DeleteCommentDescendens  
    @AncestorId INT 
AS 
    /* http://stackoverflow.com/questions/506602/best-way-to-work-with-transactions-in-ms-sql-server-management-studio */
    BEGIN TRY
        SELECT descendant_id FROM CommentPaths WHERE ancestor_id=@AncestorId AS descs
        DELETE FROM Comments WHERE id IN descs
        DELETE FROM CommentPaths WHERE ancestor_id IN descs OR descendant_id IN descs
    END TRY
    BEGIN CATCH
        SELECT 
            ERROR_NUMBER() AS ErrorNumber
            ,ERROR_SEVERITY() AS ErrorSeverity
            ,ERROR_STATE() AS ErrorState
            ,ERROR_PROCEDURE() AS ErrorProcedure
            ,ERROR_LINE() AS ErrorLine
            ,ERROR_MESSAGE() AS ErrorMessage;
        IF @@TRANCOUNT > 0
            ROLLBACK TRANSACTION;
    END CATCH;

    IF @@TRANCOUNT > 0
        COMMIT TRANSACTION;

前三个错误是

  

Msg 102,Level 15,State 1,Procedure AddProblem,Line 20
  “#”;'附近的语法不正确。

     

Msg 102,Level 15,State 1,Procedure AddSolution,Line 46
  “#”;'附近的语法不正确。

     

Msg 102,Level 15,State 1,Procedure AddRating,Line 66
  ')'附近的语法不正确。

指的是

INSERT INTO Problems (@prompt_code)

INSERT INTO Solutions (@problem_id, @solver, @solution_code, @test_code)

INSERT Into Ratings (@solution_id, @stars)

分别。

2 个答案:

答案 0 :(得分:4)

您有许多语法错误:

AddProblem

INSERT INTO Problems (@prompt_code)

应该是:

INSERT INTO Problems (prompt_code) VALUES(@prompt_code)

AddSolution

INSERT INTO Solutions (@problem_id, @solver, @solution_code, @test_code)

应该是:

INSERT INTO Soulutions (problem_id, solver, solution_code, test_code) VALUES (@problem_id, @solver, @solution_code, @test_code)

AddRating

INSERT INTO Ratings (@solution_id, @stars)

应该是

INSERT INTO Ratings (solution_id, stars) VALUES (@solution_id, @stars)

DeleteComment

CREATE PROCEDURE DeleteComment
    @id

应该是

CREATE PROCEDURE DeleteComment
    @id INT

CommentPaths表创建中:

FOREIGN KEY (ancestor_id) REFERENCES Comments(id) ON CASCADE DELETE

应该是

FOREIGN KEY (ancestor_id) REFERENCES Comments(id) ON DELETE CASCADE

DeleteCommentDescendens

SELECT descendant_id FROM CommentPaths WHERE ancestor_id=@AncestorId AS descs
DELETE FROM Comments WHERE id IN descs
DELETE FROM CommentPaths WHERE ancestor_id IN descs OR descendant_id IN descs

应该是:

DECLARE @descs AS TABLE(descendant_id INT)

INSERT INTO @descs(descendant_id)
    SELECT descendant_id FROM CommentPaths WHERE ancestor_id=@AncestorId

DELETE FROM Comments WHERE id IN (SELECT descendant_id FROM @descs)
DELETE FROM CommentPaths WHERE ancestor_id IN (SELECT descendant_id FROM @descs) OR descendant_id IN (SELECT descendant_id FROM @descs)

答案 1 :(得分:0)

你是T-Sql编程新手吗? 如果是这种情况,我建议您阅读文档或学习材料以了解语法。

在您的情况下,您需要提及列的列表或匹配应插入值的列。 如果你向表中添加一个新列,那么你会遇到一个问题然后你会做什么? 它可能适合你,但如果其他人需要维护和增强代码,它将不会对他/她产生任何意义。

因此,我建议您明确提及禁止标识列和默认值的列名 e.g:

    CREATE PROC AddProblem  
       @prompt_code VARCHAR(5000) 
    AS 
       INSERT INTO Problems(prompt_code) values(@prompt_code)
    GO