Tsql 在T-SQL中使用类开关逻辑

Tsql 在T-SQL中使用类开关逻辑,tsql,Tsql,这看起来像是一个noob T-SQL问题,但我想在存储过程中使用类似于开关的逻辑,我认为使用CASE将是使用类似 SELECT CASE @Type WHEN 1 THEN INSERT INTO dbo.Credit ( CompanyName, PhoneNumber, City, State ) V

这看起来像是一个noob T-SQL问题,但我想在存储过程中使用类似于开关的逻辑,我认为使用CASE将是使用类似

 SELECT CASE @Type
        WHEN 1 THEN
            INSERT INTO dbo.Credit (
                CompanyName,
                PhoneNumber,
                City,
                State
            ) VALUES ( 
                @CompanyName,
                @PhoneNumber,
                @City,
                @State) 
        WHEN 2 THEN  
            INSERT INTO dbo.Debit (
                CompanyName,
                PhoneNumber,
                City,
                State
            ) VALUES ( 
                @CompanyName,
                @PhoneNumber,
                @City,
                @State) 
        WHEN 3 THEN  
            --ETC
     END    

但我总是出错,这只是systax错误还是我出去吃午饭的原因?

您需要使用If/Else If结构,如下所示:

If @Type = 1
    Begin
        INSERT INTO dbo.Credit (
                CompanyName,
                PhoneNumber,
                City,
                State
        ) VALUES ( 
                @CompanyName,
                @PhoneNumber,
                @City,
                @State) 
    End
Else If @Type = 2
    Begin
        INSERT INTO dbo.Debit (
                CompanyName,
                PhoneNumber,
                City,
                State
        ) VALUES ( 
                @CompanyName,
                @PhoneNumber,
                @City,
                @State) 
    End
Else If @Type = 3
    Begin
        --ETC
    END
If @Type = 1
    EXEC InsertCredit @CompanyName, @PhoneNumber, @City, @State
Else If @Type = 2
    EXEC InsertDebit @CompanyName, @PhoneNumber, @City, @State
Else If @Type = 3
    EXEC OtherInsert @CompanyName, @PhoneNumber, @City, @State

而不是控制流量。您可以在SET或UPDATE语句中使用它,但当您更新不同的表时,这两种方法都没有帮助。如果不更改您的数据库(例如创建视图或其他内容),我认为案例不适合这里。

虽然g Mastros的答案没有错,但它可能会导致执行计划问题,因为每次运行过程时执行路径都会改变。另一种方法是使用选择。。。插入中的WHERE条款:

INSERT INTO dbo.Credit (
                CompanyName,
                PhoneNumber,
                City,
                State   ) 
SELECT 
                @CompanyName,
                @PhoneNumber,
                @City,
                @State
WHERE 
                @Type = 1

INSERT INTO dbo.Debit (
                CompanyName,
                PhoneNumber,
                City,
                State   ) 
SELECT 
                @CompanyName,
                @PhoneNumber,
                @City,
                @State
WHERE 
                @Type = 2

这样,所有代码都将始终执行,但只有@Type匹配的代码才会“激发”

您可以执行以下操作:

SET @SQL = CASE @Type
            WHEN 1 THEN
                    @SQL1
            WHEN 2 THEN  
                    @SQL2
            ELSE 
                    @SQL3
     END

EXEC(@SQL)
更新日期:2016年9月18日

注意:这是一个简单快速的解决方案,但请记住,这不是一个在生产环境中实施的长期解决方案。 我同意@Jon Galloway的观点:“我认为
CASE
不适合这里。”

另一个更专业的实现是创建3个不同的存储过程来完成各自的工作(单一责任原则),如下所示:

If @Type = 1
    Begin
        INSERT INTO dbo.Credit (
                CompanyName,
                PhoneNumber,
                City,
                State
        ) VALUES ( 
                @CompanyName,
                @PhoneNumber,
                @City,
                @State) 
    End
Else If @Type = 2
    Begin
        INSERT INTO dbo.Debit (
                CompanyName,
                PhoneNumber,
                City,
                State
        ) VALUES ( 
                @CompanyName,
                @PhoneNumber,
                @City,
                @State) 
    End
Else If @Type = 3
    Begin
        --ETC
    END
If @Type = 1
    EXEC InsertCredit @CompanyName, @PhoneNumber, @City, @State
Else If @Type = 2
    EXEC InsertDebit @CompanyName, @PhoneNumber, @City, @State
Else If @Type = 3
    EXEC OtherInsert @CompanyName, @PhoneNumber, @City, @State

在T-SQL中,我认为CASE是一个操作符/expresion,而不是一个语句。我更喜欢这个解决方案,因为它看起来更干净,同时保持执行计划不变。这是一个更好的解决方案。使用SET FMTONLY时,IF语句可能会产生意外的结果。