2011-08-23 73 views
1

我有一個存儲過程,如下所示。發生什麼事是我跑步時失敗了。當我嘗試更新(例如)更新代理中的AGENT STATE語法時,我縮小了範圍。 WHEN PropertyDefinitionID = @passStatePropertyDefID THEN @passState - 座席狀態澄清 - 使用更新TSQL

ALTER procedure [dbo].[usp_UpdateProfile] 
    @passCompanyName varchar(100), 
    @passFName varchar(50), 
    @passLName varchar(50), 
    @passEmail varchar(50), 
    @passStreet varchar(50), 
    @passCity varchar(50), 
    @passState int, 
    @passZip varchar(10), 
    @passPhone varchar(15), 
    @passUserID int 
As 
Begin 
    Declare @passCompanyNamePropertyDefID int 
    Declare @passFNamePropertyDefID int 
    Declare @passLNamePropertyDefID int 
    Declare @passEmailPropertyDefID int 
    Declare @passStreetPropertyDefID int 
    Declare @passCityPropertyDefID int 
    Declare @passStatePropertyDefID int 
    Declare @passPostalPropertyDefID int 
    Declare @passPhonePropertyDefID int 
    Declare @passACURefID int 

    Set @passCompanyNamePropertyDefID = 62 -- Local PropertyDefinitionID from server : Agent Company Name 
    Set @passFNamePropertyDefID = 61 -- Local PropertyDefinitionID from server : Agent First Name 
    Set @passLNamePropertyDefID = 63 -- Local PropertyDefinitionID from server : Agent Last Name 
    Set @passEmailPropertyDefID = 64 -- Local PropertyDefinitionID from server : Agent Email  
    Set @passStreetPropertyDefID = 65 -- Local PropertyDefinitionID from server : Agent Street 
    Set @passCityPropertyDefID = 66 -- Local PropertyDefinitionID from server : Agent City 
    Set @passStatePropertyDefID = 72 -- Local PropertyDefinitionID from server : Agent State 
    Set @passPostalPropertyDefID = 67 -- Local PropertyDefinitionID from server : Agent State 
    Set @passPhonePropertyDefID = 68 -- Local PropertyDefinitionID from server: Agent Telephone 

    If(Exists(Select UserID From AgentCompanyUser Where UserID = @passUserID)) 
    Begin 
     -- Modify First Name and Last Name in AgentCompanyUser table -- 
     Update AgentCompanyUser Set Agent_FirstName = @passFName, Agent_LastName = @passLName Where UserID = @passUserID   
    End 

    -- Modify Email Address in dnn_Users table -- 
    Update dnn_Users Set Email = @passEmail Where UserID = @passUserID 

    -- Retreive ACU_RefID from AgentCompanyUser table -- 
    Set @passACURefID = (Select ACU_RefID from AgentCompanyUser Where UserID = @passUserID) 

    -- UPDATE COMPANY WITH AGENT - AGENT PROFILE SECTION 
    Update dnn_UserProfile 
    Set PropertyValue = CASE WHEN PropertyDefinitionID = @passFNamePropertyDefID THEN @passFName -- Agent First Name 
          WHEN PropertyDefinitionID = @passLNamePropertyDefID THEN @passLName -- Agent Last Name 
          WHEN PropertyDefinitionID = @passEmailPropertyDefID THEN @passEmail -- Agent Email 
          WHEN PropertyDefinitionID = @passStreetPropertyDefID THEN @passStreet -- Agent Street 
          WHEN PropertyDefinitionID = @passCityPropertyDefID THEN @passCity -- Agent City 
          WHEN PropertyDefinitionID = @passStatePropertyDefID THEN @passState -- Agent State 
          WHEN PropertyDefinitionID = @passPostalPropertyDefID THEN @passZip -- Agent Postal 
          WHEN PropertyDefinitionID = @passPhonePropertyDefID THEN @passPhone -- Agent Phone 
         END 
    WHERE PropertyDefinitionID IN (@passFNamePropertyDefID, @passLNamePropertyDefID, @passEmailPropertyDefID, @passStreetPropertyDefID, @passCityPropertyDefID, @passStatePropertyDefID, @passPostalPropertyDefID, @passPhonePropertyDefID) 
     AND UserID IN (
     SELECT B.UserID 
     FROM CompanyAuthorizeAgent AS B 
      INNER JOIN AgentCompanyUser AS A ON A.ACU_RefID = B.FK_acu_RefID 
     WHERE A.ACU_RefID = @passACURefID) 
End 

但是,如果修改代碼分離,這是造成我的問題的代碼。有用。下面的代碼修改,你會看到我創建了另一個更新:

ALTER procedure [dbo].[usp_UpdateProfile] 
    @passCompanyName varchar(100), 
    @passFName varchar(50), 
    @passLName varchar(50), 
    @passEmail varchar(50), 
    @passStreet varchar(50), 
    @passCity varchar(50), 
    @passState int, 
    @passZip varchar(10), 
    @passPhone varchar(15), 
    @passUserID int 
As 
Begin 
    Declare @passCompanyNamePropertyDefID int 
    Declare @passFNamePropertyDefID int 
    Declare @passLNamePropertyDefID int 
    Declare @passEmailPropertyDefID int 
    Declare @passStreetPropertyDefID int 
    Declare @passCityPropertyDefID int 
    Declare @passStatePropertyDefID int 
    Declare @passPostalPropertyDefID int 
    Declare @passPhonePropertyDefID int 
    Declare @passACURefID int 

    Set @passCompanyNamePropertyDefID = 62 -- Local PropertyDefinitionID from server : Agent Company Name 
    Set @passFNamePropertyDefID = 61 -- Local PropertyDefinitionID from server : Agent First Name 
    Set @passLNamePropertyDefID = 63 -- Local PropertyDefinitionID from server : Agent Last Name 
    Set @passEmailPropertyDefID = 64 -- Local PropertyDefinitionID from server : Agent Email  
    Set @passStreetPropertyDefID = 65 -- Local PropertyDefinitionID from server : Agent Street 
    Set @passCityPropertyDefID = 66 -- Local PropertyDefinitionID from server : Agent City 
    Set @passStatePropertyDefID = 72 -- Local PropertyDefinitionID from server : Agent State 
    Set @passPostalPropertyDefID = 67 -- Local PropertyDefinitionID from server : Agent State 
    Set @passPhonePropertyDefID = 68 -- Local PropertyDefinitionID from server: Agent Telephone 

    If(Exists(Select UserID From AgentCompanyUser Where UserID = @passUserID)) 
    Begin 
     -- Modify First Name and Last Name in AgentCompanyUser table -- 
     Update AgentCompanyUser Set Agent_FirstName = @passFName, Agent_LastName = @passLName Where UserID = @passUserID   
    End 

    -- Modify Email Address in dnn_Users table -- 
    Update dnn_Users Set Email = @passEmail Where UserID = @passUserID 

    -- Retreive ACU_RefID from AgentCompanyUser table -- 
    Set @passACURefID = (Select ACU_RefID from AgentCompanyUser Where UserID = @passUserID) 

    -- UPDATE COMPANY WITH AGENT - AGENT PROFILE SECTION 
    Update dnn_UserProfile 
    Set PropertyValue = CASE WHEN PropertyDefinitionID = @passFNamePropertyDefID THEN @passFName -- Agent First Name 
          WHEN PropertyDefinitionID = @passLNamePropertyDefID THEN @passLName -- Agent Last Name 
          WHEN PropertyDefinitionID = @passEmailPropertyDefID THEN @passEmail -- Agent Email 
          WHEN PropertyDefinitionID = @passStreetPropertyDefID THEN @passStreet -- Agent Street 
          WHEN PropertyDefinitionID = @passCityPropertyDefID THEN @passCity -- Agent City 
          WHEN PropertyDefinitionID = @passPostalPropertyDefID THEN @passZip -- Agent Postal 
          WHEN PropertyDefinitionID = @passPhonePropertyDefID THEN @passPhone -- Agent Phone 
         END 
    WHERE PropertyDefinitionID IN (@passFNamePropertyDefID, @passLNamePropertyDefID, @passEmailPropertyDefID, @passStreetPropertyDefID, @passCityPropertyDefID, @passPostalPropertyDefID, @passPhonePropertyDefID) 
     AND UserID IN (
     SELECT B.UserID 
     FROM CompanyAuthorizeAgent AS B 
      INNER JOIN AgentCompanyUser AS A ON A.ACU_RefID = B.FK_acu_RefID 
     WHERE A.ACU_RefID = @passACURefID) 

    -- UPDATE COMPANY WITH AGENT - AGENT PROFILE SECTION (Add 2nd Update) 
    Update dnn_UserProfile 
    Set PropertyValue = CASE WHEN PropertyDefinitionID = @passStatePropertyDefID THEN @passState-- Agent State 
         END 
    WHERE PropertyDefinitionID IN (@passStatePropertyDefID) 
     AND UserID IN (
     SELECT B.UserID 
     FROM CompanyAuthorizeAgent AS B 
      INNER JOIN AgentCompanyUser AS A ON A.ACU_RefID = B.FK_acu_RefID 
     WHERE A.ACU_RefID = @passACURefID) 

End 

我的問題是,爲什麼我要創建另一個更新,而不是用我的原代碼,使這項工作?

在此先感謝。

+0

「它對我失敗」 - 失敗如何? –

+0

在最初的UPDATE語法中,所有傳遞的參數都不會分別更新。但由於某些原因,如果我創建兩個更新,所有記錄都會更新。傳遞給update的參數的差異是VARCHAR,但是在Update中似乎會導致衝突的參數的差異是INT –

+0

你確定你的varchar參數中沒有尾隨空格嗎?添加ltrim(rtrim())到您的case語句中的所有參數檢查(以及可能的表字段),並查看它是否可行... –

回答

5

這是SQL Server中數據類型優先級的經典案例。

Int總是比varchar具有更高的優先級。

你的第一座

在第一個塊的更新語句,當CASE語句的結果表達式甚至一個有一個int數據類型(在這種情況下@passState)和結果的其餘部分CASE語句的表達式評估爲varchar數據類型,則所有的結果表達式都應爲Int,因爲Int優先於varchar。

但隨着案件的結果表達式的其餘部分的計算結果爲VARCHAR,你會得到一個語法錯誤在第一種情況下的結果表達@passFName,因爲它是希望所有的int:

語法錯誤將varchar值* *轉換爲int類型的數據列 。

你的第二塊

在第二塊,第一個更新語句,所有result_expressions評價爲varchar的情況。因此它期望varchar並且沒有轉換問題。

在第二個更新語句中,只有一個結果表達式計算爲int(@passState)。因此它將int隱式轉換爲varchar。

課程的溶液是轉換@passState在CASE語句爲varchar在第一塊或者使用CASE或CONVERT如下所示。

// ...................... 
CASE WHEN (PropertyDefinitionID = @passFNamePropertyDefID) THEN @passFName -- Agent First Name 
    WHEN PropertyDefinitionID = @passLNamePropertyDefID THEN @passLName -- Agent Last Name 
    WHEN PropertyDefinitionID = @passEmailPropertyDefID THEN @passEmail -- Agent Email 
    WHEN PropertyDefinitionID = @passStreetPropertyDefID THEN @passStreet -- Agent Street 
    WHEN PropertyDefinitionID = @passCityPropertyDefID THEN @passCity -- Agent City 
    WHEN PropertyDefinitionID = @passStatePropertyDefID THEN CONVERT(varchar(50), @passState) -- Agent State 
    --WHEN PropertyDefinitionID = @passStatePropertyDefID THEN CAST(@passState as varchar(50)) -- Agent State 
    WHEN PropertyDefinitionID = @passPostalPropertyDefID THEN @passZip -- Agent Postal 
    WHEN PropertyDefinitionID = @passPhonePropertyDefID THEN @passPhone -- Agent Phone 
END 
// ........................ 

參考文獻:

Data Type Precedence

報價從CAST statement: *返回從result_expressions類型的集合和可選else_result_expression最高優先級的類型。有關詳細信息,請參閱數據類型優先級(Transact-SQL)。*

+0

Kashinath,非常感謝您的詳細解釋和解決方案。這幫了很多。 –