Пояснение - Использование обновления TSQL - PullRequest
1 голос
/ 23 августа 2011

У меня есть хранимая процедура, которая выглядит следующим образом ниже.Что происходит, так это то, что мне не удается, когда я бегу.Я сузил его, где при попытке обновить синтаксис AGENT STATE, например, WHEN PropertyDefinitionID = @passStatePropertyDefID THEN @passState - состояние агента

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 

Мой вопрос: почему я должен создать другое обновление вместо использования моего исходного кода, чтобы это работало?

Заранее спасибо.

1 Ответ

5 голосов
/ 23 августа 2011

Это классический случай приоритета типов данных в SQL Server.

Int всегда имеет более высокий приоритет, чем varchar.

Ваш первый блок

В операторе обновления первого блока, когда даже одно из результирующих выражений оператора CASE имеет тип данных int (в данном случае @passState), а остальные результирующие выражения оператора CASE оцениваются как тип данных varchar, тогдаОжидается, что результирующее выражение all будет Int, потому что Int имеет более высокий приоритет над varchar.

Но так как остальные выражения результата CASE оцениваются как varchar, вы получите синтаксическую ошибку в первом выражении результата CASE @passFName, так как он ожидает int для всех:

Синтаксическая ошибка при преобразовании значения varchar ** в столбец типа данных int.

Ваш второй блок

Inвторой блок, первый оператор обновления имеет CASE, где все result_expressions оцениваются как varchar.Следовательно, он ожидает varchar и проблем с преобразованием нет.

Во втором операторе обновления есть только одно выражение результата, которое оценивается как int (@passState).Следовательно, он неявно преобразует int в varchar.

Решение

Конечно, решение состоит в том, чтобы преобразовать @passState в varchar в операторе CASE в первом блоке либо с использованием 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
// ........................

Ссылки:

Тип данных Приоритет

Цитата из CAST оператор: * Возвращает тип наивысшего приоритета из набора типов в result_expressions и необязательного выражения else_result_expression.Для получения дополнительной информации см. Приоритет типа данных (Transact-SQL). *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...