Multiple Select Statements using SQL Server 2005 “

2019-01-12 03:01发布

问题:

I am trying to use the "WITH" statement in SQL Server 2005. It seems to work fine if I do something like:

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

But it fails if I try to use multiple select statements like:

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

and the error message is "Invalid object name 'MyBigProducts'".

Is there something I can do to increase the scope of the "MyBigProducts" table to include both of the select statements?

My example is a simplification of my actual code causing the problem, so I'm not discounting the possibility that the above trivial example should work and that there is another bug in my SQL.

I have tried wrapping a BEGIN and END around the two SELECT statements, but the parser could not compile it.

回答1:

As Kane said, the CTE is only available in the SQL statement where it is written. Another possible solution, depending on the specifics of your situation, would be to include the COUNT(*) in the single query:

;WITH MyBigProducts AS
(
     SELECT
          Name,
          COUNT(*) OVER () AS total_count
     FROM
          Products
     WHERE
          Size = 'Big'
)
SELECT
     Name,
     total_count
FROM
     MyBigProducts


回答2:

I believe that Common Table Expressions are only valid for immediate use which is why you are getting an error for the "SELECT Count(*) FROM MyBigProducts". In order to reuse a CTE you should use a temporary table instead

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

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


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

Please correct me if I am wrong.



回答3:

CTE have statement local scope and visibility. If you want greater scope and visibility for a table expression, you would need to make the CTE into a View or table-valued function.

Alternatively, you can materialize the expressions results into a table variable, which is local to the current batch or a temporary table whose lifetime is also local to the current batch, but whose visibility extends to the whole session.



回答4:

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`


回答5:

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