我正在尝试搜索可能驻留在数据库中的所有日期列。问题是有许多日期列属于数据类型nvarchar
,列名称也没有暗示它是日期列。
这些列中存储的日期也可以是任何日期格式。我尝试使用isdate()
,但isdate
无法识别dd-mm-yyyy
或dd/mm/yyyy
或mmm-dd-yyyy
(2014年6月6日)。
有没有办法识别这些列?
答案 0 :(得分:0)
我可能花了太多时间在这上面,但我想我有一个答案。以下代码基于您提到的三种数据格式(并使用CONVERT()
函数可用的一些简单格式),将列出数据库中可使用这些格式转换的所有字段。
这里有几个重要的注释:
1)查询当前仅检查具有VARCHAR,NVARCHAR,CHAR,NCHAR,DATE和DATETIME数据类型的列。
2)查询仅检查特定格式 - 您提到的三种格式,SQL可以隐式处理的任何格式,以及可以传递给CONVERT()
函数的各种格式代码。通过复制以BEGIN TRY
开头并以END CATCH
开头的最后一个块,必须手动添加任何其他特殊的。如果你知道一种格式,谷歌可以找到你使用它的SQL代码,只需添加它。
CREATE TABLE #ListOfColumnsToCheck
(
ListID INT IDENTITY(1,1),
TableName VARCHAR(100),
ColumnName VARCHAR(100)
)
INSERT INTO #ListOfColumnsToCheck (TableName, ColumnName)
SELECT
TABLE_NAME,
COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE IN -- expand this list as necessary
(
'VARCHAR',
'NVARCHAR',
'CHAR',
'NCHAR',
'DATETIME',
'DATE'
)
CREATE TABLE #DateCheck (DateValue DATE)
CREATE TABLE #Results
(
TableName VARCHAR(100),
ColumnName VARCHAR(100),
ConvertsToDate BIT
)
DECLARE @LoopCounter INT
DECLARE @LoopFinishNumber INT
DECLARE @CurrentTableName VARCHAR(100)
DECLARE @CurrentColumnName VARCHAR(100)
SET @LoopCounter = 1
SET @LoopFinishNumber = (SELECT MAX(ListID) FROM #ListOfColumnsToCheck)
WHILE @LoopCounter <= @LoopFinishNumber
BEGIN
SELECT @CurrentColumnName = ColumnName, @CurrentTableName = TableName
FROM #ListOfColumnsToCheck
WHERE ListID = @LoopCounter
BEGIN TRY -- add additional date formats to these lists as you come across them
EXEC('
INSERT INTO #DateCheck (DateValue)
SELECT TOP 1 ' + @CurrentColumnName + '
FROM ' + @CurrentTableName + '
WHERE ' + @CurrentColumnName + ' IS NOT NULL')
INSERT INTO #Results (TableName, ColumnName, ConvertsToDate)
VALUES (@CurrentTableName, @CurrentColumnName, 1)
END TRY
BEGIN CATCH
PRINT @CurrentTableName + '.' + @CurrentColumnName + ' is not a valid date'
END CATCH
BEGIN TRY
EXEC('
INSERT INTO #DateCheck (DateValue)
SELECT TOP 1 CONVERT(DATETIME, '+@CurrentColumnName+',101)
FROM ' + @CurrentTableName + '
WHERE ' + @CurrentColumnName + ' IS NOT NULL')
INSERT INTO #Results (TableName, ColumnName, ConvertsToDate)
VALUES (@CurrentTableName, @CurrentColumnName, 1)
END TRY
BEGIN CATCH
PRINT @CurrentTableName + '.' + @CurrentColumnName + ' is not a valid date'
PRINT ERROR_MESSAGE()
END CATCH
BEGIN TRY
EXEC('
INSERT INTO #DateCheck (DateValue)
SELECT TOP 1 CONVERT(DATETIME, '+@CurrentColumnName+',102)
FROM ' + @CurrentTableName + '
WHERE ' + @CurrentColumnName + ' IS NOT NULL')
INSERT INTO #Results (TableName, ColumnName, ConvertsToDate)
VALUES (@CurrentTableName, @CurrentColumnName, 1)
END TRY
BEGIN CATCH
PRINT @CurrentTableName + '.' + @CurrentColumnName + ' is not a valid date'
PRINT ERROR_MESSAGE()
END CATCH
BEGIN TRY
EXEC('
INSERT INTO #DateCheck (DateValue)
SELECT TOP 1 CONVERT(DATETIME, '+@CurrentColumnName+',103)
FROM ' + @CurrentTableName + '
WHERE ' + @CurrentColumnName + ' IS NOT NULL')
INSERT INTO #Results (TableName, ColumnName, ConvertsToDate)
VALUES (@CurrentTableName, @CurrentColumnName, 1)
END TRY
BEGIN CATCH
PRINT @CurrentTableName + '.' + @CurrentColumnName + ' is not a valid date'
PRINT ERROR_MESSAGE()
END CATCH
BEGIN TRY
EXEC('
INSERT INTO #DateCheck (DateValue)
SELECT TOP 1 CONVERT(DATETIME, '+@CurrentColumnName+',104)
FROM ' + @CurrentTableName + '
WHERE ' + @CurrentColumnName + ' IS NOT NULL')
INSERT INTO #Results (TableName, ColumnName, ConvertsToDate)
VALUES (@CurrentTableName, @CurrentColumnName, 1)
END TRY
BEGIN CATCH
PRINT @CurrentTableName + '.' + @CurrentColumnName + ' is not a valid date'
PRINT ERROR_MESSAGE()
END CATCH
BEGIN TRY
EXEC('
INSERT INTO #DateCheck (DateValue)
SELECT TOP 1 CONVERT(DATETIME, '+@CurrentColumnName+',105)
FROM ' + @CurrentTableName + '
WHERE ' + @CurrentColumnName + ' IS NOT NULL')
INSERT INTO #Results (TableName, ColumnName, ConvertsToDate)
VALUES (@CurrentTableName, @CurrentColumnName, 1)
END TRY
BEGIN CATCH
PRINT @CurrentTableName + '.' + @CurrentColumnName + ' is not a valid date'
PRINT ERROR_MESSAGE()
END CATCH
BEGIN TRY
EXEC('
INSERT INTO #DateCheck (DateValue)
SELECT TOP 1 CONVERT(DATETIME, '+@CurrentColumnName+',106)
FROM ' + @CurrentTableName + '
WHERE ' + @CurrentColumnName + ' IS NOT NULL')
INSERT INTO #Results (TableName, ColumnName, ConvertsToDate)
VALUES (@CurrentTableName, @CurrentColumnName, 1)
END TRY
BEGIN CATCH
PRINT @CurrentTableName + '.' + @CurrentColumnName + ' is not a valid date'
PRINT ERROR_MESSAGE()
END CATCH
BEGIN TRY
EXEC('
INSERT INTO #DateCheck (DateValue)
SELECT TOP 1 CONVERT(DATETIME, '+@CurrentColumnName+',107)
FROM ' + @CurrentTableName + '
WHERE ' + @CurrentColumnName + ' IS NOT NULL')
INSERT INTO #Results (TableName, ColumnName, ConvertsToDate)
VALUES (@CurrentTableName, @CurrentColumnName, 1)
END TRY
BEGIN CATCH
PRINT @CurrentTableName + '.' + @CurrentColumnName + ' is not a valid date'
PRINT ERROR_MESSAGE()
END CATCH
BEGIN TRY
EXEC('
INSERT INTO #DateCheck (DateValue)
SELECT TOP 1 CONVERT(DATETIME, '+@CurrentColumnName+',108)
FROM ' + @CurrentTableName + '
WHERE ' + @CurrentColumnName + ' IS NOT NULL')
INSERT INTO #Results (TableName, ColumnName, ConvertsToDate)
VALUES (@CurrentTableName, @CurrentColumnName, 1)
END TRY
BEGIN CATCH
PRINT @CurrentTableName + '.' + @CurrentColumnName + ' is not a valid date'
PRINT ERROR_MESSAGE()
END CATCH
BEGIN TRY
EXEC('
INSERT INTO #DateCheck (DateValue)
SELECT TOP 1 CONVERT(DATETIME, '+@CurrentColumnName+',109)
FROM ' + @CurrentTableName + '
WHERE ' + @CurrentColumnName + ' IS NOT NULL')
INSERT INTO #Results (TableName, ColumnName, ConvertsToDate)
VALUES (@CurrentTableName, @CurrentColumnName, 1)
END TRY
BEGIN CATCH
PRINT @CurrentTableName + '.' + @CurrentColumnName + ' is not a valid date'
PRINT ERROR_MESSAGE()
END CATCH
BEGIN TRY
EXEC('
INSERT INTO #DateCheck (DateValue)
SELECT TOP 1 CONVERT(DATETIME, '+@CurrentColumnName+',110)
FROM ' + @CurrentTableName + '
WHERE ' + @CurrentColumnName + ' IS NOT NULL')
INSERT INTO #Results (TableName, ColumnName, ConvertsToDate)
VALUES (@CurrentTableName, @CurrentColumnName, 1)
END TRY
BEGIN CATCH
PRINT @CurrentTableName + '.' + @CurrentColumnName + ' is not a valid date'
PRINT ERROR_MESSAGE()
END CATCH
BEGIN TRY
EXEC('
INSERT INTO #DateCheck (DateValue)
SELECT TOP 1 CONVERT(DATETIME, '+@CurrentColumnName+',111)
FROM ' + @CurrentTableName + '
WHERE ' + @CurrentColumnName + ' IS NOT NULL')
INSERT INTO #Results (TableName, ColumnName, ConvertsToDate)
VALUES (@CurrentTableName, @CurrentColumnName, 1)
END TRY
BEGIN CATCH
PRINT @CurrentTableName + '.' + @CurrentColumnName + ' is not a valid date'
PRINT ERROR_MESSAGE()
END CATCH
BEGIN TRY
EXEC('
INSERT INTO #DateCheck (DateValue)
SELECT TOP 1 CONVERT(DATETIME, '+@CurrentColumnName+',112)
FROM ' + @CurrentTableName + '
WHERE ' + @CurrentColumnName + ' IS NOT NULL')
INSERT INTO #Results (TableName, ColumnName, ConvertsToDate)
VALUES (@CurrentTableName, @CurrentColumnName, 1)
END TRY
BEGIN CATCH
PRINT @CurrentTableName + '.' + @CurrentColumnName + ' is not a valid date'
PRINT ERROR_MESSAGE()
END CATCH
BEGIN TRY
EXEC('
INSERT INTO #DateCheck (DateValue)
SELECT TOP 1 CONVERT(DATETIME, '+@CurrentColumnName+',113)
FROM ' + @CurrentTableName + '
WHERE ' + @CurrentColumnName + ' IS NOT NULL')
INSERT INTO #Results (TableName, ColumnName, ConvertsToDate)
VALUES (@CurrentTableName, @CurrentColumnName, 1)
END TRY
BEGIN CATCH
PRINT @CurrentTableName + '.' + @CurrentColumnName + ' is not a valid date'
PRINT ERROR_MESSAGE()
END CATCH
BEGIN TRY
EXEC('
INSERT INTO #DateCheck (DateValue)
SELECT TOP 1 CONVERT(DATETIME, '+@CurrentColumnName+',114)
FROM ' + @CurrentTableName + '
WHERE ' + @CurrentColumnName + ' IS NOT NULL')
INSERT INTO #Results (TableName, ColumnName, ConvertsToDate)
VALUES (@CurrentTableName, @CurrentColumnName, 1)
END TRY
BEGIN CATCH
PRINT @CurrentTableName + '.' + @CurrentColumnName + ' is not a valid date'
PRINT ERROR_MESSAGE()
END CATCH
-- start of code block (when copying/pasting, start here)
BEGIN TRY
EXEC('
INSERT INTO #DateCheck (DateValue)
SELECT TOP 1 REPLACE('+@CurrentColumnName+', ''-'', '' '')
FROM ' + @CurrentTableName + '
WHERE ' + @CurrentColumnName + ' IS NOT NULL')
INSERT INTO #Results (TableName, ColumnName, ConvertsToDate)
VALUES (@CurrentTableName, @CurrentColumnName, 1)
END TRY
BEGIN CATCH
PRINT @CurrentTableName + '.' + @CurrentColumnName + ' is not a valid date'
PRINT ERROR_MESSAGE()
END CATCH
-- end of code block (when copying/pasting, end here then change the SELECT TOP 1 statement to use the format)
SET @LoopCounter = @LoopCounter + 1
END
SELECT DISTINCT * FROM #Results
DROP TABLE #DateCheck
DROP TABLE #ListOfColumnsToCheck
DROP TABLE #Results