下面提到的是讨论中的示例代码:
DECLARE @FROMDATE AS DATETIME
DECLARE @TODATE AS DATETIME
DECLARE @DAYS AS VARCHAR(100)
SET @FROMDATE = CONVERT(DATETIME, '2017-09-03')
SET @TODATE = CONVERT(DATETIME, '2017-09-06')
SET @DAYS = '''SUNDAY'',''MONDAY'',''TUESDAY'',''WEDNESDAY'',''FRIDAY'',''SATURDAY'''
PRINT @DAYS
--(O/P - 'SUNDAY','MONDAY','TUESDAY','WEDNESDAY','FRIDAY','SATURDAY')
SELECT
UPPER(DATENAME(dw, CONVERT(DATETIME, CONVERT(VARCHAR(10), APPDATE, 112)))),
*
FROM
SQLTABLE
WHERE
UPPER(DATENAME(dw, CONVERT(DATETIME, CONVERT(VARCHAR(10), APPDATE, 112)))) IN (@DAYS)
如果我手动传递值如下,我将获得输出:
UPPER(DATENAME(dw, CONVERT(DATETIME, CONVERT(VARCHAR(10), APPDATE, 112))))
IN ('SUNDAY','MONDAY','TUESDAY','WEDNESDAY','FRIDAY','SATURDAY')
如果我使用具有与PRINT @DAYS
O/P相同的变量传递值,则结果为空白:
UPPER(DATENAME(dw, CONVERT(DATETIME, CONVERT(VARCHAR(10), APPDATE, 112))))
IN (@DAYS)
假设在实际情况下,我正在动态地生成@DAYS
变量下的值,或者将代码传递到以下查询/存储过程中:
在SQL中不允许它还是我错误地这样做?
您需要将其执行为Dynamic SQL:
Set @sql='SELECT ... from ... WHERE ... NOT IN ('+@days+')'
exec sp_executesql @sql
如果不是,则整个param值将被视为一个值。
in
运算符期望由逗号分隔的值列表,但是您提供的是一个单个值,其中包含一个逗号分隔列表。
您可以使用Dynamic SQL来解决它,如Sagi在答案中所建议的,或使用字符串拆分函数(在SQL Server 2016中它内置)将单个逗号分隔变量转换为表 -
SET @DAYS = 'SUNDAY,MONDAY,TUESDAY,WEDNESDAY,FRIDAY,SATURDAY'
SELECT UPPER(DATENAME(dw, CONVERT(DATETIME, CONVERT(VARCHAR(10), APPDATE, 112)))), *
FROM SQLTABLE
WHERE UPPER(DATENAME(dw, CONVERT(DATETIME, CONVERT(VARCHAR(10), APPDATE, 112)))) IN (STRING_SPLIT(@DAYS, ','))
如果您使用的版本比2016年的版本较低,则需要自己创建字符串拆分用户定义的函数 - 或以正确的方式从Aaron Bertrand的拆分字符串中选择一个 - 或下一个最佳方式
但是,如果您的客户端支持它,我建议将一个有价值的参数发送到数据库,而不是完全处理逗号界限字符串。
如果您不喜欢动态查询,这是萨吉答案的另一种方法。您可以创建一个桌子并填充想要的日子:
CREATE TABLE #Days (NAME VARCHAR(20))
INSERT INTO #Days
VALUES ('SUNDAY'),('MONDAY'),('TUESDAY'),('WEDNESDAY'),('FRIDAY'),('SATURDAY')
,然后将其与您的桌子一起加入:
SELECT UPPER(DATENAME(dw, CONVERT(DATETIME, CONVERT(VARCHAR(10), APPDATE, 112)))),*
FROM SQLTABLE s
INNER JOIN #Days d ON d.NAME
= UPPER(DATENAME(dw, CONVERT(DATETIME, CONVERT(VARCHAR(10), s.APPDATE, 112))))
如果您使用的是SQL Server 2016 ,则有一个String_split函数,该函数返回具有value
列的表。
SET @DAYS = 'SUNDAY,MONDAY,TUESDAY,WEDNESDAY,FRIDAY,SATURDAY'
SELECT UPPER(DATENAME(dw, CONVERT(DATETIME, CONVERT(VARCHAR(10), APPDATE, 112)))), *
FROM SQLTABLE s
INNER JOIN STRING_SPLIT(@DAYS, ',') d ON d.value
= UPPER(DATENAME(dw, CONVERT(DATETIME, CONVERT(VARCHAR(10), s.APPDATE, 112))))
(PS:Zohar peled的实现STRING_SPLIT
如果您使用的是SQL Server 2016 )