SQL Server存储过程 - 通过CASE执行不同的查询

时间:2014-09-04 04:53:21

标签: sql-server

我的存储过程有两个参数。根据{{​​1}}的值,必须搜索正确的列。在伪代码格式中,它应该是这样的

Searching_Condition

以下是我正在处理的代码以及陷入困境的代码。它应该很简单但是man ...由于不熟悉SQL Server,我很挣扎,SQL Server中的//CASE @Search_Condition // WHEN 'UserID' THEN SELECT * FROM user_table WHERE UserID LIKE '@Keywords' // WHEN 'UserName' THEN SELECT * FROM user_table WHERE UserName LIKE '@Keywords' // WHEN 'UserAddress' THEN SELECT * FROM user_table WHERE UserAddress LIKE '@Keywords' 不能像我想象的那样工作。

谢谢!

CASE

2 个答案:

答案 0 :(得分:1)

帮助您做到这一点的关键概念是表达式语句之间的区别。

声明是程序性的,并指导控制流程。您可以想到一个从语句到语句的指令指针,并且每个语句都与其他语句隔离(尽管它们可以选择执行它们之后的语句)。它们可以被认为是动词

表达式可以减少为某个值 - 标量值,字符串甚至行集 - 但表达式不会命令执行任何操作。他们可以被认为是名词。这些名词本身不能存在,它们必须在陈述的背景下。

SQL Server中的CASE语句是表达式。它不是像Select Case那样的程序语句,例如Visual Basic。诀窍是,当语言需要表达式时,不能替换语句 - 此外,除了在某些特殊用法中,您不能将过程语句放在表达式的中间(除了行集)可以作为表达式进行评估,例如单列和单行SELECTEXISTS)。表达式可以包含包含表达式的表达式。它们就像一棵树,一直倒塌。

考虑EXECUTE dbo.MyStoredProcedure (8 + @@SPID) / 2中的部分:这是一个单个语句,带有一个参数表达式,由三个子表达式组成,按特定顺序计算,解析为单个值,用作存储过程的参数。您无法单独执行(8 + @@SPID) / 2,因为它不是声明。 (不要紧,表达式很愚蠢,仅举例来说。)

我确实说过,在某些情况下,行集可以是值,但几乎所有表达式的预期类型都是单个值 - 而不是行集。这就是这里发生的问题 - 您的外SELECT语句期望单行中第一列定义的值(因为您没有FROM子句),但是当您的搜索条件为'user_name'时,您正尝试提供整个行集。

您可以完全放弃CASE并使用IF来解决此问题 - 因为IF是一个程序性陈述。

CREATE PROCEDURE [dbo].[USP_SP_NAME]
    @Searching_Condition NVARCHAR(100),
    @Keywords NVARCHAR(100)
AS
SET NOCOUNT ON;
SET LOCK_TIMEOUT 3000;
SET XACT_ABORT ON;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

BEGIN TRY
   IF @Searching_Condition = 'user_id' BEGIN
      select count(*) from user_table;
   END
   ELSE IF @Searching_Condition = 'user_name' BEGIN
      select * from user_table;
   END;
END TRY;

我主张避免不使用IFBEGIN的{​​{1}}版本并接受单个声明 - 这种形式会导致混淆和错误。我每次都使用ENDBEGIN,这看起来很痛苦,直到你发现这样做有多少时间和精力可以帮助你节省时间......

答案 1 :(得分:0)

你可以试试这个,不需要提供案例,条件会根据@Searching_Condition的值而改变:

CREATE PROCEDURE [dbo].[USP_SP_NAME]
    @Searching_Condition NVARCHAR(100),
    @Keywords NVARCHAR(100)
AS
SET NOCOUNT ON
SET LOCK_TIMEOUT 3000
SET XACT_ABORT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

BEGIN TRY
   exec('Select * from user_table WHERE'+ @Searching_Condition+' LIKE '+ @Keywords);
END TRY