2010-08-13 85 views
10

我正尝试在的SQL Server 2005如何在SQL Server中的VIEW“声明标量变量”(2005)

的SQL代码工作作为这样创建VIEW(我在VS2008中使用它),但在SQL Server中,我无法保存它,因为弹出错误消息“声明标量变量@StartDate”和“声明标量变量@EndDate”。

下面是代码:

WITH Calendar AS (SELECT  CAST(@StartDate AS datetime) AS Date 
    UNION ALL 
    SELECT  DATEADD(d, 1, Date) AS Expr1 
    FROM   Calendar AS Calendar_1 
    WHERE  (DATEADD(d, 1, Date) < @EndDate)) 
    SELECT  C.Date, C2.Country, COALESCE (SUM(R.[Amount of people per day needed]), 0) AS [Allocated testers] 
    FROM   Calendar AS C CROSS JOIN 
          dbo.Country AS C2 LEFT OUTER JOIN 
          dbo.Requests AS R ON C.Date BETWEEN R.[Start date] AND R.[End date] AND R.CountryID = C2.CountryID 
    GROUP BY C.Date, C2.Country 

而且我的问题当然是 - 究竟应该怎么申报呢?

我试图把下面的第一个代码:

DECLARE @StartDate smalldatetime 
DECLARE @EndDate smalldatetime 

但是didn't做的伎俩,就如我所料 - 它只是给了我另一个弹出消息:

“声明游标SQL构造或语句不受支持。”

回答

12

正如Alex K所提到的,你应该把它写成一个内联表值函数。这里是描述它的article

总之,语法会像

CREATE FUNCTION dbo.GetForPeriod 
    (@StartDate datetime, @EndDate datetime) 
RETURNS TABLE 
RETURN 
    SELECT [[ your column list ]] 
    FROM [[ table list] 
    WHERE [[some column] BETWEEN @StartDate AND @EndDate 

你可以有一个选择查询(但复杂,可以使用CTE)。然后,你将用它作为

SELECT * FROM dbo.GetForPeriod('1-Jan-2010', '31-Jan-2010') 
+0

不错,要测试一下 - 我认为它是一个可以接受的答案:-) – 2010-08-13 12:34:54

+0

功能的缺点是,如果你想加入或过滤它们,它们的性能很差 – 2012-07-27 15:24:30

+1

@IanBoyd,对于多语句TVF和标量函数,你说的通常是正确的,然而,这里的解决方案使用了内联表值函数AFAIK,SQL Server将在查询中扩展UDF(就像在视图中所做的那样),因此,与你已经说过,他们会在join/filter中工作得更好(假设参与表有适当的索引),或者至少不会有任何惩罚涉及使用内联TVF的情况(除了额外的解析),参见http: //blogs.msdn.com/b/psssql/archive/2010/10/ 28/query-performance-and-multi-statement-table-valued values.aspx – VinayC 2012-08-01 06:38:18

2

如果VIEW你的意思是一个SQL Server本机视图(CREATE VIEW ...),那么你不能在所有使用局部变量(你可以使用一个表值UDF代替)。

如果你的意思是别的,那么加入DECLARE @StartDate DATETIME, @EndDate DATETIME使得这个语句解析得很好,它是整个SQL吗?

+0

我的意思是我在上的SQL Server Management Studio中右键点击“视图”文件夹并选择“新视图...”“ - 我以这种方式创建了其他视图,然后在Visual Studio 2008(C#)中使用它们来创建”TableAdapter“时使用它们。那么,什么是表值UDF?在哪里以及如何创建它,你知道吗? – 2010-08-13 10:12:38

-1

尝试AX和AY更换所有@X,@Y,添加到您的代码: FROM(SELECT X = 'literalX',Y = 'literalY')一个 然后你已经把所有的文字放在一个地方,只有一个副本。

0

这是一个示例查询,它使用CTE很好地模拟内部变量构造。您可以在您的SQL Server版本中测试运行它。

CREATE VIEW vwImportant_Users AS 
WITH params AS (
    SELECT 
    varType='%Admin%', 
    varMinStatus=1) 
SELECT status, name 
    FROM sys.sysusers, params 
    WHERE status > varMinStatus OR name LIKE varType 

SELECT * FROM vwImportant_Users 

产生输出:

status name 
12  dbo 
0  db_accessadmin 
0  db_securityadmin 
0  db_ddladmin 

还通过JOIN

WITH params AS (SELECT varType='%Admin%', varMinStatus=1) 
SELECT status, name 
    FROM sys.sysusers INNER JOIN params ON 1=1 
    WHERE status > varMinStatus OR name LIKE varType 

还通过CROSS APPLY

WITH params AS (SELECT varType='%Admin%', varMinStatus=1) 
SELECT status, name 
    FROM sys.sysusers CROSS APPLY params 
    WHERE status > varMinStatus OR name LIKE varType