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