在 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
答案 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;