Несколько операторов выбора с помощью оператора «WITH» SQL Server 2005 - PullRequest
15 голосов
/ 05 июня 2009

Я пытаюсь использовать оператор «WITH» в SQL Server 2005. Кажется, он работает нормально, если я делаю что-то вроде:

WITH MyBigProducts AS (SELECT * FROM Products WHERE Size='Big')
SELECT Name FROM MyBigProducts

Но произойдет сбой, если я попытаюсь использовать несколько операторов выбора, таких как:

WITH MyBigProducts AS (SELECT * FROM Products WHERE Size='Big')
SELECT Name FROM MyBigProducts
SELECT Count(*) FROM MyBigProducts

и сообщение об ошибке: «Неверное имя объекта« MyBigProducts »».

Что я могу сделать, чтобы расширить область действия таблицы «MyBigProducts» для включения обоих операторов выбора?

Мой пример - упрощение моего фактического кода, вызывающего проблему, поэтому я не исключаю, что приведенный выше тривиальный пример должен работать и что в моем SQL есть еще одна ошибка.

Я попытался обернуть BEGIN и END вокруг двух операторов SELECT, но парсер не смог его скомпилировать.

Ответы [ 5 ]

14 голосов
/ 05 июня 2009

Как сказал Кейн, CTE доступен только в операторе SQL, в котором он написан. Другое возможное решение, в зависимости от конкретной ситуации, состоит в том, чтобы включить COUNT (*) в один запрос:

;WITH MyBigProducts AS
(
     SELECT
          Name,
          COUNT(*) OVER () AS total_count
     FROM
          Products
     WHERE
          Size = 'Big'
)
SELECT
     Name,
     total_count
FROM
     MyBigProducts
14 голосов
/ 05 июня 2009

Я считаю, что выражения Common Table Express действительны только для немедленного использования, поэтому вы получаете сообщение об ошибке «SELECT Count (*) FROM MyBigProducts». Для повторного использования CTE вы должны использовать временную таблицу вместо

DECALRE @BigProducts TABLE (...[declaration omitted]...)

INSERT INTO @BigProducts
SELECT * 
FROM Products 
WHERE Size='Big'


SELECT Name FROM @BigProducts
SELECT Count(*) FROM @BigProducts

Пожалуйста, поправьте меня, если я ошибаюсь.

2 голосов
/ 05 июня 2009

CTE имеют локальную область видимости и видимость оператора. Если вам нужна большая область видимости для табличного выражения, вам нужно превратить CTE в функцию View или табличную функцию.

Кроме того, вы можете материализовать результаты выражений в табличную переменную, которая является локальной для текущего пакета или временной таблицей, время жизни которой также локально для текущего пакета, но видимость которой распространяется на весь сеанс.

0 голосов
/ 11 сентября 2015
CREATE TABLE tblEmployees
(
    EmployeeID    SMALLINT IDENTITY(1001,1) NOT NULL,
    EmployeeName  NVARCHAR(100) NOT NULL,
    Department    NVARCHAR(50) NOT NULL,
    Designation   NVARCHAR(50) NOT NULL,
    JoiningDate   DATETIME NOT NULL,
    Salary        DECIMAL(10,2) NOT NULL,
    [Description] NVARCHAR(1000) NULL 
)

SELECT * FROM tblEmployees

INSERT INTO tblEmployees(EmployeeName, Department, Designation, JoiningDate, Salary, [Description]) 
VALUES  ('John Smith', 'IT Research', 'Research Analyst', '02/08/2005', 23000.00, 'John Smith is involved in the Research and Development since 2005')

INSERT INTO tblEmployees(EmployeeName, Department, Designation, JoiningDate, Salary, [Description]) 
VALUES  ('John Micheal', 'IT Operations', 'Manager', '07/15/2007', 15000.00, NULL)

INSERT INTO tblEmployees(EmployeeName, Department, Designation, JoiningDate, Salary, [Description]) 
VALUES  ('Will Smith', 'IT Support', 'Manager', '05/20/2006', 13000.00, 'Joined this year as IT Support Manager')

INSERT INTO tblEmployees(EmployeeName, Department, Designation, JoiningDate, Salary, [Description]) 
VALUES  ('Anna John', 'IT Support', 'Developer', '02/10/2008', 23000.00, 'Joined this year as IT Support Developer')


DECLARE @EmpID AS SMALLINT
DECLARE @SQLQuery AS NVARCHAR(500)
SET @EmpID = 1001
SET @SQLQuery = 'SELECT * FROM tblEmployees WHERE EmployeeID = ' + CAST(@EmpID AS NVARCHAR(10))
Print @SQLQuery 
EXECUTE(@SQLQuery)


DECLARE @EmpID AS SMALLINT
DECLARE @SQLQuery AS NVARCHAR(500)
DECLARE @ParameterDefinition AS NVARCHAR(100)
SET @EmpID = 1002
SET @SQLQuery = 'SELECT * FROM tblEmployees WHERE EmployeeID = @EmpID' 
SET @ParameterDefinition =  '@EmpID SMALLINT'
EXECUTE sp_executesql @SQLQuery, @ParameterDefinition, @EmpID



Create Procedure sp_EmployeeSelect
    @EmployeeName NVarchar(100),
    @Department NVarchar(50),
    @Designation NVarchar(50),
    @StartDate DateTime,
    @EndDate DateTime,
    @Salary Decimal(10,2)       
AS
    Set NoCount ON  
    Declare @SQLQuery AS NVarchar(4000)
    Declare @ParamDefinition AS NVarchar(2000) 
    Set @SQLQuery = 'Select * From tblEmployees where (1=1) ' 

    If @EmployeeName Is Not Null 
         Set @SQLQuery = @SQLQuery + ' And (EmployeeName = @EmployeeName)'
    If @Department Is Not Null
         Set @SQLQuery = @SQLQuery + ' And (Department = @Department)' 
    If @Designation Is Not Null
         Set @SQLQuery = @SQLQuery + ' And (Designation = @Designation)'
    If (@StartDate Is Not Null) AND (@EndDate Is Not Null)
         Set @SQLQuery = @SQLQuery + ' And (JoiningDate BETWEEN @StartDate AND @EndDate)'
    If @Salary Is Not Null
         Set @SQLQuery = @SQLQuery + ' And (Salary >= @Salary)'
    Set @ParamDefinition = '@EmployeeName NVarchar(100),
                @Department NVarchar(50),
                @Designation NVarchar(50),
                @StartDate DateTime,
                @EndDate DateTime,
                @Salary Decimal(10,2)'

    Exec sp_Executesql  @SQLQuery, @ParamDefinition, @EmployeeName, @Department, @Designation, 
                        @StartDate, @EndDate, @Salary

    If @@ERROR <> 0 GoTo ErrorHandler
    Set NoCount OFF
    Return(0)

ErrorHandler:
    Return(@@ERROR)
GO


EXEC sp_EmployeeSelect 'John Smith', NULL, NULL, NULL, NULL, NULL

EXEC sp_EmployeeSelect NULL, 'IT Operations', 'Manager', NULL, NULL, NULL




DECLARE @EmpName AS NVARCHAR(50)
DECLARE @SQLQuery AS NVARCHAR(500)
SET @EmpName = 'John' 
SET @SQLQuery = 'SELECT * FROM tblEmployees WHERE EmployeeName LIKE '''+ '%' + @EmpName + '%' + '''' 
PRINT @SQLQuery
EXECUTE sp_executesql @SQLQuery



DECLARE @EmpID AS NVARCHAR(50)
DECLARE @SQLQuery AS NVARCHAR(500)
SET @EmpID = '1001,1003,1004,1002' 
SET @SQLQuery = 'SELECT * FROM tblEmployees WHERE EmployeeID IN(' + @EmpID + ')'
EXECUTE sp_executesql @SQLQuery


DECLARE @OrderBy AS NVARCHAR(50)
DECLARE @SQLQuery AS NVARCHAR(500)
SET @OrderBy = 'Department' 
SET @SQLQuery = 'SELECT * FROM tblEmployees Order By ' + @OrderBy
EXECUTE sp_executesql @SQLQuery


WITH RESULTS AS(
SELECT * FROM [dbo].[User]
)`enter code here`
0 голосов
/ 24 апреля 2013
WITH n(id, name) AS 
   (SELECT id, name 
    FROM ABC
    WHERE parent = 44
        UNION ALL
    SELECT m.id, m.name 
    FROM ABC as m, n
    WHERE n.id = m.parent)
SELECT * FROM n
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...