例如,在SQL Server(10.0.5520.SQL Server 2008 SP3)中,我们有一个包含3列DateTime
列的表。
我们的目标是只获取具有3列中的一列的数据> SpecificedDate
但我们不希望逐个列出指定的列。
请查看以下示例:
TABLE A (ID INT,
Name VARCHAR,
CreateDate DATETIME,
ModifyDate DATETIME,
VoidDate DATETIME)
通常会是:
SELECT *
FROM A
WHERE CreateDate > 'X' OR ModifyDate > 'X' OR VoidDate > 'X'
应该转向
SELECT *
FROM A
WHERE (IF Column Is DateTime AND Column.Data > 'X')
我们可以这样查询吗?如果是,我们该怎么做?
答案 0 :(得分:3)
您可以使用sys.columns
获取datetime
的给定表格的列。
select C.name
from sys.columns as C
where C.object_id = object_id('A') and
C.system_type_id = type_id('datetime')
然后,您可以使用sp_executesql
来构建和执行查询。
declare @SQL nvarchar(max)
set @SQL = '
select *
from dbo.A
where '+stuff((
select 'or '+quotename(C.name) + ' > @Value '
from sys.columns as C
where C.object_id = object_id('A') and
C.system_type_id = type_id('datetime')
for xml path(''), type
).value('text()[1]', 'nvarchar(max)'), 1, 3, '')
--print @SQL
exec sp_executesql @SQL, N'@Value datetime', '2015-07-01'
select *
from dbo.A
where [CreateDate] > @Value or [ModifyDate] > @Value or [VoidDate] > @Value
答案 1 :(得分:1)
表A
ID Name CreateDate ModifyDate VoidDate
--- ----------- ----------------------- ----------------------- -----------------------
1 Name1 2015-01-01 00:00:00.000 2015-02-02 00:00:00.000 2015-03-03 00:00:00.000
2 Name2 2015-01-01 00:00:00.000 NULL NULL
3 Name3 NULL NULL 2015-03-03 00:00:00.000
4 Name4 NULL NULL NULL
T-SQL代码
DECLARE @ColNames AS TABLE (RowNumber INT, ColumnName VARCHAR(MAX))
INSERT INTO @ColNames
SELECT
RANK() OVER (ORDER BY c.COLUMN_NAME) AS RowNumber,
c.COLUMN_NAME
FROM
INFORMATION_SCHEMA.COLUMNS c
WHERE
TABLE_NAME = 'A' AND DATA_TYPE = 'datetime'
ORDER BY RowNumber
DECLARE @SpecifiedDate DATETIME
SET @SpecifiedDate = '2015-01-01'
DECLARE @i INT = 1
DECLARE @sqlString NVARCHAR(MAX) = N'SELECT * FROM A WHERE '
DECLARE @count INT = (SELECT COUNT(*) FROM @ColNames)
WHILE @i <= @count
BEGIN
DECLARE @colName VARCHAR(MAX) =
(SELECT ColumnName FROM @ColNames WHERE RowNumber = @i)
SET @sqlString = @sqlString + @colName + ' > '''
+ CONVERT(VARCHAR, @SpecifiedDate,104) + ''''
SET @sqlString = @sqlString +
CASE WHEN @i < @count
THEN ' OR '
ELSE ''
END
SET @i = @i + 1;
END
EXEC sp_executesql @sqlString, N'@SpecifiedDate datetime', '2015-01-01'
输出
ID Name CreateDate ModifyDate VoidDate
--- ------ ----------------------- ----------------------- -----------------------
1 Name1 2015-01-01 00:00:00.000 2015-02-02 00:00:00.000 2015-03-03 00:00:00.000
3 Name3 NULL NULL 2015-03-03 00:00:00.000
答案 2 :(得分:0)
在Sql Server 2012+
中,您可以使用TRY_CAST
功能:
WHERE TRY_CAST(column1 AS DATETIME) > 'X' OR
TRY_CAST(column2 AS DATETIME) > 'X' OR
TRY_CAST(column3 AS DATETIME) > 'X'
在Sql Server 2008
中,您可以使用ISDATE
功能:
WHERE (ISDATE(column1) = 1 AND CAST(column1 AS DATETIME) > 'X') OR
(ISDATE(column2) = 1 AND CAST(column2 AS DATETIME) > 'X') OR
(ISDATE(column3) = 1 AND CAST(column3 AS DATETIME) > 'X')