2011-08-23 74 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,非常感谢您的详细解释和解决方案。这帮了很多。 –