如何优化SQL Server函数:避免重复使用d1至d31列判断
优化方案
要实现你的需求,核心思路是将列转换为行来避免重复书写d1至d31的列名,同时用IF逻辑判断结果。以下是具体实现:
优化后的函数代码
CREATE FUNCTION CheckColumnsForXY (@id INT) RETURNS BIT AS BEGIN DECLARE @delete BIT = 0; -- 通过UNPIVOT将31列转为行数据,统一检查值是否为x或y IF EXISTS ( SELECT 1 FROM tblname UNPIVOT ( ColumnValue FOR ColumnName IN (d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31) ) AS unpvt WHERE id = @id AND ColumnValue IN ('x', 'y') ) BEGIN SET @delete = 0; -- 存在x/y,返回0 END ELSE BEGIN SET @delete = 1; -- 不存在x/y,返回1 END RETURN @delete; END
关键说明
- UNPIVOT的作用:把d1至d31这31个列转换成31行数据,每行对应一个列的名称和值,这样只需要一次
ColumnValue IN ('x','y')就能完成所有列的检查,彻底避免重复书写列名的冗余代码。 - 简化列名输入:如果不想手动敲31个列名,可以执行以下SQL生成列名列表,直接复制到UNPIVOT的IN子句中:
SELECT STRING_AGG(QUOTENAME('d' + CAST(n AS VARCHAR)), ', ') FROM (SELECT TOP 31 ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n FROM sys.all_columns) AS nums
执行后会输出[d1], [d2], ..., [d31]的字符串,直接替换到函数代码里即可。
3. IF逻辑实现:用IF EXISTS判断转换后的行中是否存在x或y,直接控制返回值,替代了原有的长串OR IN逻辑。
内容的提问来源于stack exchange,提问作者Yash
相关产品推荐
相关产品推荐

