需求:写动态SQL 实现 最后的and 限制 查找所有字段含01HX970,实现效果如下
SELECT * FROM [dbo].[AIO_Consumption_report] WHERE VALID = 'Y' AND LOCATION_NAME LIKE '%VN%' AND (CAST([DATA_FROM_KEY] AS VARCHAR(50)) = '01HX970' OR CAST([iwoow] AS VARCHAR(50)) = '01HX970' OR ......OR CAST([iwoow_RMK] AS VARCHAR(50)) = '01HX970')
实现代码:
sql
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'SELECT * FROM [dbo].[AIO_Consumption_report] WHERE VALID = ''Y'' AND LOCATION_NAME LIKE ''%VN%'' ';
-- 初始化一个临时变量来存储条件
DECLARE @conditions NVARCHAR(MAX);
SET @conditions = N'';
-- 获取所有非日期/时间字段名并构建动态条件
SELECT @conditions = @conditions +
CASE
WHEN DATA_TYPE IN ('int', 'bigint', 'smallint', 'tinyint', 'decimal', 'numeric', 'float', 'real') THEN
'CAST(' + QUOTENAME(COLUMN_NAME) + ' AS VARCHAR(50)) = ''01HX970'' OR '
ELSE
-- 排除日期/时间类型,只保留字符型数据或不确定类型(如sql_variant)
CASE WHEN DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar', 'text', 'ntext', 'sql_variant') THEN
'CAST(' + QUOTENAME(COLUMN_NAME) + ' AS VARCHAR(50)) = ''01HX970'' OR '
ELSE
'' -- 对于其他类型,不添加条件
END
END
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'AIO_Consumption_report' AND TABLE_SCHEMA = 'dbo';
-- 如果有生成条件,则移除最后的 ' OR ' 并拼接到主SQL语句中
IF LEN(@conditions) > 0
BEGIN
-- 去掉最后的 ' OR ' 并加上括号
SET @conditions = LEFT(@conditions, LEN(@conditions) - 3); -- 去除最后的 ' OR '
SET @sql = @sql + ' AND (' + @conditions + ')'; -- 拼接到主SQL语句中
END
ELSE
BEGIN
-- 如果没有条件,则保持当前的 SQL 不变
SET @sql = @sql + ';';
END
-- 打印 SQL 语句以进行调试
SELECT @sql;
-- 执行动态 SQL
EXEC sp_executesql @sql;
注意:
SQL Server Management Studio(SSMS)限制 :有时,SSMS 的 PRINT
命令只会输出部分内容。它最多可以打印 4000 个字符(如果是 NVARCHAR(MAX)
),因此如果你使用 PRINT
来调试长 SQL 语句,它可能被截断。你可以尝试将结果输出到临时表或文件,而不是直接 PRINT
。
替代方法 :可以通过 SELECT
而不是 PRINT
来输出 SQL 语句。