Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 测试获取游标时,未返回正确的值_Sql_Sql Server - Fatal编程技术网

Sql 测试获取游标时,未返回正确的值

Sql 测试获取游标时,未返回正确的值,sql,sql-server,Sql,Sql Server,最近,我在测试获取代码时遇到了一个问题。我将一个变量声明为@Positive_percentage作为数值,它应该返回一个百分比列表,但是当我打印动态代码时,@Positive_percentage为所有列返回空值。这是在触发选择@Positive_percentage,@COL_NAME时发生的。但是,当我打印整个SQL并在其他地方运行时,它会返回正确的百分比和匹配的列名。请有人提供一些建议。谢谢 DECLARE @COL_NAME VARCHAR(100),@POSITIVE_PERCENT

最近,我在测试获取代码时遇到了一个问题。我将一个变量声明为@Positive_percentage作为数值,它应该返回一个百分比列表,但是当我打印动态代码时,@Positive_percentage为所有列返回空值。这是在触发选择@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;

您没有为@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中的go-to工具

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

我们可以完全删除光标,并帮助您找到一种基于集合的方法,而不是修复光标。此外,您正在创建动态sql,但您的变量@POSITIVE_PERCENTAGE超出了范围。即使它在范围内,您也不会执行动态sql。因此,您的变量从未被赋值,因此它将始终为空。感谢Sean的建议。我明白你的意思。我将研究这些问题。同时,如果可能的话,你能指导我如何解决这个问题吗。非常感谢。正如我说的,在这里最好不要使用光标。即使您需要坚持使用动态sql,也可以不使用游标来实现。这就是挑战所在。我不能在这里提供太多帮助,因为没有足够的细节。请发布ddl创建表脚本和示例数据插入语句。sqlfiddle.com可以提供帮助。一旦我有事情要做,并且解释了你想要什么,我可以帮你。谢谢肖恩的建议。最后,我没有在这个案例中使用游标。相反,我只是在while循环中包装动态,它工作得很好。我已经在下面发布了我的解决方案。再次感谢。感谢艾伦的宝贵建议。我接受任何这样做的建议。我使用游标的原因是,我只想简单地循环遍历列名并计算百分比,然后与30进行比较。如果您不认为这是一种方法,请提供一些更好的方法,或者您认为什么是使其工作的最佳修改方法。感谢您为STND_遭遇提供ddl?