Sql-Server

Delete Works 在一個儲存過程中但不是另一個

  • February 23, 2016

我已經建構了一個應用程序,它使用儲存過程來插入、更新和刪除數據庫表中的行。所有域使用者都被賦予了對這些程序的執行權限,所有程序對它們具有相同的權限。

其中兩個過程包含相同的刪除語句:

DELETE RFT
FROM Database.schema.tbl_Review_Response_FreeText RFT
WHERE RFT.Instance_ID = @InstanceID

每個InstanceID. 在一個過程中,該語句會刪除相應的行,而在另一個過程中則不會。

關於不起作用的語句,我不認為@InstanceID它失去了它的價值,因為更新語句之前使用它沒有任何問題。

這似乎不是權限問題,因為刪除在其中一個過程中起作用,在另一個過程中不起作用(對於使用者),但它似乎確實是權限問題,因為當執行這些過程時,兩者都按預期工作。所以這讓我覺得這是另外一回事,但Google一直沒有幫助。

關於這裡可能發生什麼的任何想法?


澄清:

該行在刪除語句之前存在(並且在刪除之後仍然存在),並且更新正在更新另一個表。

這是未刪除的過程的完整定義:

USE [database]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [schema].[spr_App_EngRvwAddProxyRow]
   @ProxyNm varchar(100),@InstanceID bigint
AS
BEGIN
   SET NOCOUNT ON;

   DECLARE @UserOprID varchar(8)
   DECLARE @ProxyID varchar(8)

   SET @UserOprID=RIGHT(SUSER_SNAME(), LEN(SUSER_SNAME()) - CHARINDEX('\', SUSER_SNAME()))

   SET @ProxyID=   (
                   SELECT TOP 1 ep.Opr_ID ProxyToID
                   FROM database.schema.tbl_Reviews r
                       INNER JOIN database.schema.tbl_Review_Setup rs ON rs.Rvw_ID=r.Rvw_ID
                       INNER JOIN database.schema.tbl_Engagement_Proxies ep ON ep.Eng_ID=r.Eng_ID AND ep.Qtr_ID=rs.Qtr_ID
                       LEFT OUTER JOIN Import_Stage_Db.schema.vw_ALLWb_Assoc_Identifiers AS aaProx1 ON aaProx1.OPER_ID = ep.Opr_ID 
                   WHERE 
                   --(REPLACE(@ProxyNm,'.',',')=REPLACE(aaProx1.PREFERRED_NAME,)
                   @ProxyNm=REPLACE(aaProx1.PREFERRED_NAME,',','.')
                       AND 
                       r.Instance_ID=@InstanceID
                       AND 
                       r.Rvwer_OprID=@UserOprID
                       AND 
                       r.ADD_DTTM= (
                                       SELECT MAX(r2.ADD_DTTM)
                                       FROM database.schema.tbl_Reviews r2
                                       WHERE r2.Instance_ID=r.Instance_ID
                                       )
                   )
   --Insert a new row into the reviews table for the proxy
   INSERT INTO database.schema.tbl_Reviews(Instance_ID,Rvw_ID,Eng_ID,Rvwee_OprID,Rvwer_OprID)
   SELECT r.Instance_ID,r.Rvw_ID,Eng_ID,r.Rvwee_OprID,@ProxyID
   FROM database.schema.tbl_Reviews r
   WHERE r.Instance_ID=@InstanceID
       AND r.Rvwer_OprID=@UserOprID
       AND r.ADD_DTTM= (
                       SELECT MAX(r2.ADD_DTTM)
                       FROM database.schema.tbl_Reviews r2
                       WHERE r2.Instance_ID=r.Instance_ID
                       )

   --Wipe any responses for that reviewee from the repsonses table
   UPDATE database.schema.tbl_Review_Response
   SET Response_ID = NULL, LAST_UPD_BY = NULL, LAST_UPD_DTTM = NULL
   WHERE Instance_ID = @InstanceID

   --Wipe the free text reponses for the instance ID
   DELETE RFT
   FROM database.schema.tbl_Review_Response_FreeText RFT
   WHERE RFT.Instance_ID = @InstanceID

   --Always return a row for the front end
   SELECT 0 AS Return_Value
END

這是該過程的第一部分(直到刪除):

USE [database]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [schema].[spr_App_EngRvwResponse_Upd]
   @QID int,@RtgTxt varchar(max),@IID int
AS
BEGIN
   SET NOCOUNT ON;
   SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

   DECLARE @ScaleDtlID tinyint,@IsFreeTxt bit,@UserOprID varchar(8)


   SET @UserOprID=RIGHT(SUSER_SNAME(), LEN(SUSER_SNAME()) - CHARINDEX('\', SUSER_SNAME()))


   SELECT TOP 1 
       @ScaleDtlID=sd.Scale_Dtl_ID
       ,@IsFreeTxt=CASE WHEN q.Scale_ID=1
                       THEN 1
                       ELSE 0
                       END 
   FROM database.schema.tbl_Questions q
       LEFT OUTER JOIN database.schema.tbl_Rvw_Scale_Detail sd 
           ON sd.Scale_ID=q.Scale_ID
               AND sd.Label_Text=@RtgTxt
   WHERE q.Q_ID=@QID


   IF @IsFreeTxt=1
       BEGIN
           IF ltrim(rtrim(@RtgTxt))='' OR @RtgTxt IS NULL
               BEGIN
                   DELETE rft
                   FROM database.schema.tbl_Review_Response_FreeText rft
                   WHERE rft.Instance_ID=@IID
                       AND rft.Q_ID=@QID
               END
           ELSE
  --rest of code

我認為值得注意的是,ISOLATION LEVEL在一位同事建議我在刪除不起作用的過程中將其刪除之前,兩者都是相同的…

能夠弄清楚問題所在。

我回顧了應用程序並再次詢問使用者他是如何開始這個過程的。問題是使用者在啟動程序之前沒有保存值,因此正在執行一個單獨的程序來保存未保存的值,並在語句執行後將值插入到表中。delete

在保存應用程序中未保存的值之前,我修改了我的應用程序中的程式碼以刪除該值(從應用程序)。

感謝@spaghettidba 將我推向正確的方向!

引用自:https://dba.stackexchange.com/questions/130205