在具有nvarchar数据类型的数据库中搜索日期列

时间:2014-06-06 10:13:25

标签: sql sql-server date

我正在尝试搜索可能驻留在数据库中的所有日期列。问题是有许多日期列属于数据类型nvarchar,列名称也没有暗示它是日期列。

这些列中存储的日期也可以是任何日期格式。我尝试使用isdate(),但isdate无法识别dd-mm-yyyydd/mm/yyyymmm-dd-yyyy(2014年6月6日)。

有没有办法识别这些列?

1 个答案:

答案 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