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

Bob*_*tor 35 t-sql

这看起来像一个小白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    
Run Code Online (Sandbox Code Playgroud)

但我一直在收到错误,是否只是一个systax错误,或者我正在吃午饭?

G M*_*ros 57

你需要使用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
Run Code Online (Sandbox Code Playgroud)


Jai*_*der 18

你可以这样做:

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

EXEC(@SQL)
Run Code Online (Sandbox Code Playgroud)

2016年9月18日更新

注意:这是一种简单快捷的解决方案,但请记住,这是在生产环境中实施的长期解决方案.我同意@Jon Galloway:"我觉得CASE这不合适."

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

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
Run Code Online (Sandbox Code Playgroud)


Kev*_*ley 11

虽然G Mastros的答案没有任何问题,但它可能会导致执行计划问题,因为每次运行程序时执行路径都会改变.另一种方法是在INSERT中使用SELECT ... 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
Run Code Online (Sandbox Code Playgroud)

这样所有代码都会被执行,但只有@Type匹配的代码才会"触发"

  • 我更喜欢这个解决方案,因为它看起来更干净,而且执行计划保持不变。 (2认同)

Jon*_*way 7

该CASE语句只能是某些条款,而不是控制流.您可以在SET或UPDATE语句中使用它,但是当您更新不同的表时,这些都不会有帮助.在不改变数据库的情况下(例如创建视图或其他内容),我认为CASE不适合这里.

  • 在T-SQL中,我认为CASE是一个操作符/表达式而不是语句. (4认同)