使用游标计算必要表中的所有行

时间:2017-03-09 09:35:36

标签: sql-server sql-server-2008

我的数据库中有几个表,我想根据AppoitmentID计算所有这些表的总行数,我使用标量游标和表变量来存储基于AppoitmentID的那些表的一些数据。在游标结束后,我计算了表变量的行,其中我在游标中使用动态查询插入了数据。

但它给了我以下错误

  

必须声明表变量" @ ProcCount"。

是否有其他方法可以从必要的表中获取所有行的计数。 以下是我的代码:

 Create FUNCTION [dbo].[ufn_GetProcedureCount] 
(   

)
RETURNS INT
AS
BEGIN
    -- Declare the return variable here
    DECLARE @MenuID bigINT, @TableName VARCHAR(150);    
    DECLARE @Result int
    DECLARE @ProcCount TABLE (AppID INT, WoundId bigINT,TableName varchar(150));

    DECLARE @sql nvarchar(2000)
    DECLARE @Count int


     DECLARE Cur_PendSign Cursor For 
        select Distinct MenuID,TableName from AppointmentTypeRequiredDocumnet  A inner join Menu M on  M.ID =A.MenuID where m.MenuGroupID = 8

    OPEN Cur_PendSign 

    FETCH Cur_PendSign INTO @MenuID, @TableName
    WHILE @@FETCH_STATUS=0
    BEGIN

SET @sql='DECLARE @ProcCount TABLE (AppID INT, WoundId bigINT,TableName varchar(150))'
SET @sql=@sql+'INSERT INTO @ProcCount (AppID,WoundId)
            SELECT TOP 1 V.AppointmentID, 1
            FROM ['+@TableName+'] V WITH(NOLOCK)'
set @sql=@sql+ 'select count(*) from @ProcCount;'


--set @sql=@sql+ 'DECLARE @Count int'
 EXECUTE sp_executesql @sql 

FETCH Cur_PendSign INTO @MenuID, @TableName
    END
CLOSE  Cur_PendSign
DEALLOCATE  Cur_PendSign


  --set  @Result = select count(*) from @ProcCount

    RETURN @Result

END

3 个答案:

答案 0 :(得分:0)

脚本存在两个问题。

第一:缺少where子句

从Appointment A.AppointmentID = 8

中选择Distinct MenuID,TableName

第二:由于范围的限制,你需要创建持久表而不是变量表,因为你不能在EXEC之外声明变量表并使用它。

答案 1 :(得分:0)

此查询应该适合您。您需要使用sp_executesql来执行动态查询。

CREATE FUNCTION [dbo].[ufn_GetProcedureCount]
(

)
RETURNS INT
AS
BEGIN
    -- Declare the return variable here
    DECLARE @Result INT

    DECLARE @ProcCount TABLE (
        AppID INT,
        WoundId BIGINT,
        TableName VARCHAR(150)
    )
    DECLARE @MenuID BIGINT,
            @TableName VARCHAR(150)

    --Get all table which I need to count rows
    DECLARE Cur_PendSign CURSOR FOR
    SELECT DISTINCT MenuID, TableName FROM Appointment WHERE AppointmentID = 8
    OPEN Cur_PendSign

    FETCH Cur_PendSign INTO @MenuID, @TableName
    WHILE @@fetch_status = 0
    BEGIN

        -- Insert require data into @ProcCount using dynamic query
        DECLARE @query VARCHAR(255) = 'INSERT INTO @ProcCount (AppID,WoundId,TableName) 
                                       SELECT TOP 1 AppointmentID, WoundId, TableName
                                       FROM [' + @TableName + ']  WITH(NOLOCK) '

        EXECUTE sys.sp_executesql @query

        FETCH Cur_PendSign INTO @MenuID, @TableName
    END
    CLOSE Cur_PendSign
    DEALLOCATE Cur_PendSign

    --Get Count of all rows from tables
    SELECT @Result = COUNT(*) FROM @ProcCount

    RETURN @Result

END

答案 2 :(得分:0)

如果没有[1] "C:/Users/Owner/Documents/R/win-library/3.3" [2] "C:/Program Files/R/R-3.3.2/library" cursor,您可以使用动态编码来完成..

架构:

(可能与您的实际架构不同)

Loops

现在做如下

CREATE TABLE #Appointment (MENUID INT IDENTITY,AppointmentID INT, TableName VARCHAR(20))
INSERT INTO #Appointment
SELECT 1,'TABLE1'
UNION ALL
SELECT 2, 'TABLE2'
UNION ALL
SELECT 8,'TABLE3'
UNION ALL
SELECT 8,'TABLE4'
UNION ALL
SELECT 8,'TABLE5'

如果你想查看@QRY包含的内容

DECLARE @QRY VARCHAR(MAX)='';

SELECT @QRY = @QRY+ 'SELECT COUNT(1) AS COUNT_TABLES FROM '+ TableName + ' (NOLOCK)  
UNION ALL
' FROM (
SELECT DISTINCT  TableName FROM #Appointment A WHERE  A.AppointmentID = 8
)A

SELECT @QRY = SUBSTRING(@QRY,1,LEN(@QRY)-11)

SELECT @QRY = '
SELECT SUM(COUNT_TABLES) FROM (

' + @QRY+'
)A'

--PRINT @QRY

EXEC (@QRY)