最近,我在测试获取代码时遇到了一个问题。我将变量声明为@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;
答案 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