测试获取光标时,不返回正确的值

时间:2014-07-18 20:20:12

标签: sql sql-server

最近,我在测试获取代码时遇到了一个问题。我将变量声明为@Positive_percentage作为数值,它假设返回百分比列表,但是当我打印动态代码时,@ Product_percentage为所有列返回NULL值(这在触发SELECT @ POSITIVE_PERCENTAGE时发生,@ COL_NAME)。但是,当我打印整个SQL并在其他地方运行时,它会返回正确的百分比和匹配的列名。请有人提供一些建议。感谢

DECLARE @COL_NAME VARCHAR(100),@POSITIVE_PERCENTAGE NUMERIC(19,2),@SQL VARCHAR(MAX)
DECLARE FINANCIAL_COL_CURSOR CURSOR FOR
SELECT DISTINCT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS  
WHERE TABLE_NAME = 'STND_ENCOUNTER'
AND DATA_TYPE IN ('DECIMAL')

--AND COLUMN_NAME IN        
   ('TOTAL_PAYMENTS','BAD_DEBT_WRITEOFF','PATIENT_AMOUNT_PAID','PAYOR_AMOUNT_PAID','TOTAL_BALANCE_DUE')

 OPEN FINANCIAL_COL_CURSOR;

 FETCH NEXT FROM FINANCIAL_COL_CURSOR INTO @COL_NAME;

WHILE @@FETCH_STATUS = 0
BEGIN

SET @SQL  = 
'SELECT @POSITIVE_PERCENTAGE = CASE WHEN COUNT('+@COL_NAME+') > 0 THEN CAST(CAST(SUM(CASE      WHEN CAST('+@COL_NAME+' AS FLOAT)>0 
                                                                  THEN 1 
                                                                  ELSE 0 END)AS      FLOAT)/CAST(COUNT('+@COL_NAME+') AS FLOAT)* 100 AS NUMERIC(19,2))
ELSE 100.00 END FROM STND_ENCOUNTER'

PRINT @SQL      

SELECT @POSITIVE_PERCENTAGE,@COL_NAME     --<-- this is where NULL value return



--IF @POSITIVE_PERCENTAGE <30.00
--  BEGIN
--      --UPDATE #temp
--      SET '+@COL_NAME+'  =  @COL_NAME * -1
--  END
PRINT @COL_NAME
FETCH NEXT FROM  FINANCIAL_COL_CURSOR INTO @COL_NAME;
END
CLOSE FINANCIAL_COL_CURSOR;
DEALLOCATE FINANCIAL_COL_CURSOR;

2 个答案:

答案 0 :(得分:0)

您没有为@POSITIVE_PERCENTAGE分配任何值,因为您的动态/非动态SQL组合错误地混合在一起。

这是这一部分:

SET @SQL  = 
'SELECT @POSITIVE_PERCENTAGE = CASE WHEN COUNT('+@COL_NAME+') > 0 THEN CAST(CAST(SUM(CASE      WHEN CAST('+@COL_NAME+' AS FLOAT)>0 
                                                                  THEN 1 
                                                                  ELSE 0 END)AS      FLOAT)/CAST(COUNT('+@COL_NAME+') AS FLOAT)* 100 AS NUMERIC(19,2))
ELSE 100.00 END FROM STND_ENCOUNTER'

PRINT @SQL      

SELECT @POSITIVE_PERCENTAGE,@COL_NAME

您可以在字符串@SQL中为@POSITIVE_PERCENTAGE分配值,但不是执行字符串。如果你这样做,你会得到语法错误,因为在那个上下文中没有声明@POSITIVE_PERCENTAGE。 (这是一个不同的背景)

您需要将动态SQL更好地包装到您想要实现的(并执行它),或者更好的方法是不使用游标执行此操作。 (游标通常不是SQL中的首选工具)

答案 1 :(得分:0)

这是我的情况解决方案

DECLARE @COL_NAME VARCHAR(100),@SQL NVARCHAR(MAX),@POSITIVE_PERCENTAGE DECIMAL(19,2),
@INIT INT = (SELECT COUNT(*)
          FROM INFORMATION_SCHEMA.COLUMNS  
         WHERE TABLE_NAME = 'STND_ENCOUNTER'
         AND COLUMN_NAME IN           ('TOTAL_PAYMENTS','BAD_DEBT_WRITEOFF','PATIENT_AMOUNT_PAID','PAYOR_AMOUNT_PAID','TOTAL_BALANCE_DUE'))

WHILE (@INIT <> 0 )
BEGIN
            Select @COL_NAME = (    SELECT COLUMN_NAME FROM (
                                    SELECT COLUMN_NAME, RANK() OVER (ORDER BY COLUMN_NAME DESC) AS RankByCOL
                                    FROM INFORMATION_SCHEMA.COLUMNS  
                                    WHERE TABLE_NAME = 'STND_ENCOUNTER'
                                    AND COLUMN_NAME IN ('TOTAL_PAYMENTS','BAD_DEBT_WRITEOFF','PATIENT_AMOUNT_PAID','PAYOR_AMOUNT_PAID','TOTAL_BALANCE_DUE') 
                                    ) S
                                    where RankByCOL = @INIT)

SET @SQL = N'SELECT @POSITIVE_PERCENTAGE = CASE WHEN COUNT('+@COL_NAME+') > 0 THEN CAST(CAST(SUM(CASE WHEN CAST('+@COL_NAME+' AS FLOAT)>0 
                                                                  THEN 1 
                                                                  ELSE 0 END)AS FLOAT)/CAST(COUNT('+@COL_NAME+') AS FLOAT)* 100 AS NUMERIC(19,2))
             ELSE 100.00 END FROM STND_ENCOUNTER'
EXECUTE sp_executesql @SQL, N'@POSITIVE_PERCENTAGE DECIMAL(19,2) output', @POSITIVE_PERCENTAGE output           

            IF @POSITIVE_PERCENTAGE < 30.00
            BEGIN                   
                EXEC ('UPDATE DBO.STND_ENCOUNTER SET '+@COL_NAME+'= '+@COL_NAME+' * -1')
            END
 SET @INIT = @INIT - 1
END