您可以将函数调用分配给SQL Server中的本地变量子句

时间:2013-12-08 03:40:53

标签: sql sql-server function where

SQL Server 2012 (或2014)中,是否可以转换选择语句,如

... where S.getAge(Handle) >= @ageMin and S.getAge(Handle) <= @ageMax

成像(伪代码)

... where {set @a = S.getAge(Handle)} and @a >= @ageMin and @a <= @ageMax

1 个答案:

答案 0 :(得分:0)

SQL专家Itzik Ben-Gan在他的书“Microsoft SQL Server 2008内部:T-SQL查询”中描述了逻辑查询处理阶段。

正确的顺序如下:

1. FROM
2. ON
3. OUTER
4. WHERE
5. GROUP BY
6. CUBE | ROLLUP
7. HAVING
8. SELECT
9. DISTINCT
10. ORDER BY
11. TOP

变量的赋值总是在FROM子句之前的语句的SELECT部分​​中完成。

但是,SQL Server允许您执行不应该尝试的内容。

让我们做一个测试用例。一个简单的表,在tempdb中从1到10计数,一个简单的标量函数,它取数字并乘以10得到年龄。

这与您的示例有一些相似之处。

-- Use temp db
USE TEMPDB;
GO

-- Create simple table
CREATE TABLE T1
( MYID INT IDENTITY (1,1) );
GO

-- Add 10 records
INSERT INTO T1 DEFAULT VALUES;
GO 10

-- Create a scalar valued function
CREATE FUNCTION GETAGE (@INDEX INT)
RETURNS INT 
AS 
BEGIN
    RETURN (@INDEX * 10);
END
GO

-- Returns 10
DECLARE @A INT;
SELECT @A = DBO.GETAGE(1);
PRINT @A

以下是您在下面尝试执行的操作的示例。

where子句是逻辑评估中的第4步。它可以过滤最终结果中的记录。我们在WHERE子句的表达式中有一个赋值。但是,表达式应该为TRUE,FALSE或UNKNOWN(NULL)。

作业返回的内容是什么?

我只能猜测不是因为表达式之间的AND显示没有记录。表达式之间的OR表示记录。

-- OR displays 4 to 8, AND = empty result set
DECLARE @A INT = 0;
SELECT MYID FROM TBL1
WHERE 
(@A = DBO.GETAGE(MYID)) OR 
(DBO.GETAGE(MYID) > 30 AND DBO.GETAGE(MYID) < 90);
PRINT @A;

最后但并非最不重要的,你想做什么?

此代码仅返回最后一个分配。

-- Only displays last assignment
DECLARE @A INT = 0;
SELECT @A = DBO.GETAGE(MYID) FROM TBL1
WHERE (DBO.GETAGE(MYID) > 30) AND (DBO.GETAGE(MYID) < 90);
PRINT @A;

此代码返回逗号分隔列表。

-- Comma delimited list
DECLARE @A VARCHAR(MAX) = '';
SELECT @A += STR(DBO.GETAGE(MYID), 2, 0) + ', ' FROM TBL1
WHERE (DBO.GETAGE(MYID) > 30 AND DBO.GETAGE(MYID) < 90);
IF LEN(@A) > 0 SET @A = SUBSTRING(@A, 1, LEN(@A) - 1);
PRINT @A;