2011-07-15 96 views
1

我需要幫助我的存儲過程,目前我有存儲過程接受值並將這些值發佈到我的數據庫。這是一個給學生一個測驗的程序,它將他們的答案和分數記錄到數據庫中。我想跟蹤學生在每次測驗中所做的嘗試次數。我需要一種方式來爲每個學生和每個測驗設置一個計數器。這是我當前的存儲過程,當我運行它時我的數據庫給了我這個錯誤錯誤170:第17行:在'LIMIT'附近的語法不正確。 我也嘗試做一個LAST()函數,但數據庫表示LAST()函數無法識別。SQL Counter幫助

CREATE PROCEDURE [dbo].spRecordStudentScore 
    @StudentNum   BIGINT, 
    @TestID    BIGINT, 
    @DateCompleted  DATETIME, 
    @Score  FLOAT 
AS 
BEGIN 
    SET NOCOUNT ON; 
    DECLARE @Attempt int; 

    SET @Attempt = 1; 

    BEGIN 
    IF NOT EXISTS (SELECT * FROM dbo.tbStudentScores WHERE fdStudent# = @StudentNum AND fdTestID = @TestID AND fdAttempt = @Attempt) 
     SET @Attempt = 1; 
    ELSE 
     SELECT @Attempt = fdAttempt FROM dbo.tbStudentScores WHERE fdStudent# = @StudentNum AND fdTestID = @TestID ORDER BY fdAttempt DESC LIMIT 1 

    END 

    BEGIN TRANSACTION 
        BEGIN 
      IF NOT EXISTS (SELECT * FROM dbo.tbStudentScores WHERE fdStudent# = @StudentNum AND fdTestID = @TestID AND fdDateCompleted = @DateCompleted AND fdScore = @Score) 

        INSERT INTO dbo.tbStudentScores 
           (fdStudent#, 
      fdTestID, 
      fdAttempt, 
      fdDateCompleted, 
      fdScore) 
         VALUES (@StudentNum, 
      @TestID, 
      @Attempt, 
      @DateCompleted, 
      @Score) 
     END 
        -- END INSERT INTO dbo.tbStudentScores 

    IF @@error <> 0 
     BEGIN 
      ROLLBACK TRANSACTION 
      RETURN 1 
     END 

    ELSE 
     BEGIN 
      COMMIT TRANSACTION 
      RETURN 0 
     END 
END 
-- END PROCEDURE [dbo].spRecordStudentScore 
GO 
+0

什麼RDBMS你正在用嗎?它看起來像SQL Server,但是您使用的是非SQL Server語法,如「LIMIT」。 –

回答

1

如果你只是想找到下一個嘗試次數,你並不需要什麼特別的東西 - 這裏是它最基本的SQL:

DECLARE @Attempt INT;

SELECT 
    @Attempt = isnull(max(fdAttempt),0) 
FROM 
    dbo.tbStudentScores 
WHERE 
    fdStudent# = @StudentNum 
    AND fdTestID = @TestID 

您可以將+1添加到它你做你的下一個插入之前 - 或者:

SET @Attempt = @Attempt + 1 

或SELECT,只需+1它有

SELECT 
     @Attempt = isnull(max(fdAttempt),0) + 1 
... 
+0

順便說一句 - isnull部分只是照顧學生尚未做出嘗試的情況。 – Chains

+0

謝謝你的幫助,我看到我忘了增加我的櫃檯 – Nate

0

替換該行

SELECT @Attempt = fdAttempt FROM dbo.tbStudentScores WHERE fdStudent# = @StudentNum AND fdTestID = @TestID ORDER BY fdAttempt DESC LIMIT 1 

與此

SELECT TOP 1 @Attempt = fdAttempt FROM dbo.tbStudentScores WHERE fdStudent# = @StudentNum AND fdTestID = @TestID ORDER BY fdAttempt DESC 
+0

謝謝你的幫助 – Nate

0

試試這個

SET @Attempt = SELECT TOP 1 fdAttempt FROM dbo.tbStudentScores WHERE fdStudent# = @StudentNum AND fdTestID = @TestID ORDER BY fdAttempt DESC)

+0

謝謝你的幫助 – Nate

0

請在下面看到我的評論:

CREATE PROCEDURE [dbo].spRecordStudentScore 
    @StudentNum   BIGINT, 
    @TestID    BIGINT, 
    @DateCompleted  DATETIME, 
    @Score  FLOAT 

我看到@Score被定義爲FLOAT ......這將是一個近似值。你確定你不想使用DECIMAL類型嗎?

此外,BIGINT似乎是相當大的TestIDStudentNum(除非StudentNum真的應該是一個VARCHAR)...你確定INT是不夠的?

AS 
BEGIN 
    SET NOCOUNT ON; 
    DECLARE @Attempt int; 

    SET @Attempt = 1; 

    BEGIN 
    IF NOT EXISTS (SELECT * FROM dbo.tbStudentScores WHERE fdStudent# = @StudentNum AND fdTestID = @TestID AND fdAttempt = @Attempt) 
     SET @Attempt = 1; 
    ELSE 
     SELECT @Attempt = fdAttempt FROM dbo.tbStudentScores WHERE fdStudent# = @StudentNum AND fdTestID = @TestID ORDER BY fdAttempt DESC LIMIT 1 

    END 

相反的LIMIT 1,你可以做SELECT TOP 1 @Attempt = fdAttempt ...

BEGIN TRANSACTION 
        BEGIN 
      IF NOT EXISTS (SELECT * FROM dbo.tbStudentScores WHERE fdStudent# = @StudentNum AND fdTestID = @TestID AND fdDateCompleted = @DateCompleted AND fdScore = @Score) 

的記錄居然可以檢查之間潛入這裏,如果它存在並將其插入之前......如果你需要爲了防止這種情況發生,你需要使用一個可序列化的讀取...可能在讀取時使用排他鎖來防止死鎖。或者,更好的辦法是確保你在表格上有合適的唯一約束。

     INSERT INTO dbo.tbStudentScores 
           (fdStudent#, 
      fdTestID, 
      fdAttempt, 
      fdDateCompleted, 
      fdScore) 
         VALUES (@StudentNum, 
      @TestID, 
      @Attempt, 
      @DateCompleted, 
      @Score) 
     END 
        -- END INSERT INTO dbo.tbStudentScores 

您正在使用哪個版本的MS SQL Server?如果是2005年或更新版本,則應檢出TRY CATCH塊以進行錯誤處理。

IF @@error <> 0 
     BEGIN 
      ROLLBACK TRANSACTION 
      RETURN 1 
     END 

    ELSE 
     BEGIN 
      COMMIT TRANSACTION 
      RETURN 0 
     END 
END 
-- END PROCEDURE [dbo].spRecordStudentScore 
GO