在特定日期之前显示具有多个表的数据库中的所有日期时间字段

时间:2013-06-13 10:05:18

标签: sql-server vba ms-access

我希望创建一些VBA代码,通过我的链接表(到SQL Server)查看,并输出任何字段的列表,这些字段是datetime,日期在1990年。

我想我会为每个循环需要两个这样的

For Each table in currentDB.TableDefs

    For Each field in table.fields

        If field.type = datetime and field.value < '1900-01-01 00:00:00'
            debug.print table.name, field.name and field.value.
        End IF

    Next
Next

关于如何做到这一点的任何想法?

由于

5 个答案:

答案 0 :(得分:1)

你已经有两个循环了!你好像做得对。它不起作用吗?

答案 1 :(得分:1)

VBA解决方案

基本上遍历每个表上的每个字段,寻找DateTime字段类型(整数值为8 - http://allenbrowne.com/ser-49.html)。 if if找到DateTime字段后,运行查询并查看它是否返回任何记录。

Dim db As Database
Dim t As TableDef
Dim f As Field
Dim rs As Recordset

Set db = CurrentDb

For Each t In db.TableDefs
    For Each f In t.Fields
        If f.Type = 8 Then

            Set rs = db.OpenRecordset("SELECT " & f.Name & " FROM " & t.Name & " WHERE " & f.Name & " < #1/1/1990 12:00:00 PM#;")
            If rs.EOF = False Then
                Debug.Print t.Name, f.Name, rs.Fields(f.Name)
            End If
            rs.Close

        End If
    Next
Next

答案 2 :(得分:0)

如果您的字段类型是DateTime,那么您只需使用年份函数()

If year(field.value) > 1900 Then

    'codes here

End If

在VB中你可以这样做

Dim dBirth as Date

For x as Integer = 0 to MyTable.rows.Count-1
   dBirth = MyTable.Rows(x).Item("birthdate")
   If dBirth > 1990 Then

       'codes here  

   End If
Next

答案 3 :(得分:0)

您可以使用此存储过程:它将年份作为输入参数。 它返回具有输入年份值的列(及其表名)。

ALTER PROCEDURE [dbo].[sp_GetAllDateColumns] @startDateYear [INT]
AS
  BEGIN
      SET nocount ON;
      -- --------------- 
      DECLARE @table_name NVARCHAR(100)
      DECLARE @col_name VARCHAR(100)
      DECLARE @sqlCommand NVARCHAR(1000)
      DECLARE @count INT
      -- ---------------
      DECLARE @ResultArray TABLE
        (
           table_name NVARCHAR(100),
           col_name   VARCHAR(100)
        )
      -- ----------------
      DECLARE table_cursor CURSOR FOR
        SELECT ( SCH.name + '.' + TAB.name )AS tablename,
               COL.name                     AS colname
        FROM   sys.schemas SCH,
               sys.tables TAB,
               sys.columns COL,
               sys.types TYP
        WHERE  COL.system_type_id = TYP.system_type_id
               AND TAB.object_id = COL.object_id
               AND SCH.schema_id = TAB.schema_id
               AND TYP.name IN ( 'datetime', 'date' );

      OPEN table_cursor
      FETCH next FROM table_cursor INTO @table_name, @col_name
      WHILE @@FETCH_STATUS = 0
        BEGIN
            SET @sqlCommand = 'SELECT @cnt = COUNT(*) FROM '
                              + @table_name + ' WHERE  datepart(year,' +
                              + @col_name + ' ) < '
                              + CONVERT(NVARCHAR, @startDateYear)
            EXECUTE Sp_executesql @sqlCommand, N'@cnt int OUTPUT', @cnt=@count output
            IF @count >= 1
              BEGIN
                  INSERT INTO @ResultArray(table_name, col_name)VALUES (@table_name,@col_name)
              END
            FETCH next FROM table_cursor INTO @table_name, @col_name
        END
      CLOSE table_cursor
      DEALLOCATE table_cursor
      --Return result
      SELECT * FROM   @ResultArray
  END

要从SQL Server调用此过程,您所要做的就是执行此查询:

EXEC [dbo].[sp_GetAllDateColumns] @startDateYear = 2003

答案 4 :(得分:0)

在SQL术语中,您需要一个游标来遍历所有表/日期 - 列对,并在每列中查找最小的日期值。您可以将结果插入临时表中以根据需要进行分析。

很抱歉这不是VBA,但VBA不会做任何工作,只是中继SQL命令。 因此,如果您只能通过VBA访问数据库(出于任何原因),请发送此命令,并正常读取上一个select语句的输出。

IF exists (select * from tempdb.sys.tables where name like '#Temp_results%') DROP TABLE #Temp_results
create table #Temp_results (
    table_name varchar (50) null,
    column_name varchar (50) null,
    Min_Date datetime null
)
GO

declare @sql varchar (max), @tab varchar (50), @col varchar (50)
declare _cur insensitive cursor for

    select top 2 c.name as table_name, a.name as column_name
    from sys.columns a
    join sys.types b on a.user_type_id = b.user_type_id
    join sys.tables c on a.object_id = c.object_id
    where b.name like 'date%' or b.name = 'timestamp%'
    and c.type = 'U'

open _cur
fetch next from _cur into @tab, @col    
while @@FETCH_STATUS = 0
begin 
    select @sql ='INSERT INTO #Temp_results select ''' + @tab + ''', ''' + @col + ''', (select min([' + @col + ']) from [' + @tab + '])'

    --select @sql  /* This is used to debug d-sql. Comment out next statement. Copy and execute SQL code. */

    exec (@sql)

fetch next from _cur into @tab, @col    
end 

close _cur
deallocate _cur
GO

select table_name,  column_name, Min_Date, 
case 
 when Min_Date < '1900-01-01' then 'Very old date'
 when Min_Date < '1990-01-01' then 'Just an old date'
 else 'OK' 
end How_Old_Date_Is

from #Temp_results
GO
相关问题